public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform
@ 2021-05-26 10:06 Nhi Pham
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
                   ` (34 more replies)
  0 siblings, 35 replies; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Leif Lindholm, Michael D Kinney, Ard Biesheuvel, Nate DeSimone

This patch series adds the support for the Mt. Jade platform based on Ampere's
Altra Family Processor.

Notes:
  + The current patch series was tested with the edk2-stable202102 tag.
  + The IASL compiler version 20201217 is required to build.
  + The edk2-non-osi source is required to build.

You can get code from
https://github.com/AmpereComputing/edk2-platforms/tree/ampere-upstream-wip-v2

Cc: Vu Nguyen <vunguyen@os.amperecomputing.com>
Cc: Nhi Pham <nhi@os.amperecomputing.com>
Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Changes since v1:
  + Addressed all Leif's feedback in the thread
  https://edk2.groups.io/g/devel/message/70356.
  + Removed the LinuxBoot image as Leif's feedback in the thread
  https://edk2.groups.io/g/devel/message/68717. The image will be
  pre-produced by users as the instruction in the README before compiling.
  + Other major code improvements from in-house review:
    * Create new AmperePlatformPkg and AmpereSiliconPkg packages for
    containing common Platform/Silicon modules.
    * Remove SMProLib and PMProLib libraries which are replaced by the
    MailboxInterfaceLib and SystemFirmwareInterfaceLib libraries for the
    communication interface between UEFI and System Firmware.
    * Clean up and fix coding styles to conform to EDK II C Coding
    Standards Specification.

Nhi Pham (10):
  AmperePlatformPkg: Implement FailSafe library
  AmperePlatformPkg: Add FailSafe and WDT support
  AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table
  AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table
  AmpereAltraPkg, JadePkg: Add ACPI support
  JadePkg: Add ASpeed GOP driver
  AmpereAltraPkg: Add configuration screen for ACPI
  AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
  Platform/Ampere: Introduce the LinuxBootPkg
  AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade
    platform

Quan Nguyen (3):
  AmpereAltraPkg: Add BootProgress support
  JadePkg: Add SMBIOS tables support
  AmpereAltraPkg: Add configuration screen for RAS

Vu Nguyen (19):
  Ampere: Initial support for Ampere Altra processor and Mt. Jade
    platform
  AmpereAltraPkg: Add MmCommunication modules
  AmpereAltraPkg: Add DwI2cLib library
  AmpereAltraPkg: Add DwGpioLib library
  JadePkg: Implement RealTimeClockLib for PCF85063
  AmpereAltraPkg: Support non-volatile variables
  AmpereSiliconPkg: Add PlatformManagerUiLib library instance
  AmpereAltraPkg: Add PcieCoreLib library instance
  JadePkg: Add PcieBoardLib library instance
  AmpereAltraPkg: Add PciHostBridge driver
  JadePkg: Enable PCIe-related libraries and device drivers
  AmpereAltraPkg: Add Random Number Generator Support
  AmpereAltraPkg: Add DebugInfoPei module
  AmpereAltraPkg: Add platform info screen
  AmpereAltraPkg: Add configuration screen for memory
  AmpereAltraPkg: Add configuration screen for CPU
  AmpereAltraPkg: Add configuration screen for Watchdog timer
  AmpereAltraPkg: Add configuration screen for Pcie Devices
  JadePkg: Recover boot options when NVRAM cleared

 .../AmperePlatformPkg/AmperePlatformPkg.dec   |   31 +
 .../Ampere/AmpereAltraPkg/AmpereAltraPkg.dec  |   72 +
 .../AmpereSiliconPkg/AmpereSiliconPkg.dec     |   85 +
 .../AmpereAltraLinuxBootPkg.dsc.inc           |  550 ++
 .../AmpereAltraPkg/AmpereAltraPkg.dsc.inc     |  736 +++
 Platform/Ampere/JadePkg/Jade.dsc              |  192 +
 Platform/Ampere/JadePkg/JadeLinuxBoot.dsc     |   90 +
 Platform/Ampere/JadePkg/Jade.fdf              |  369 ++
 Platform/Ampere/JadePkg/JadeLinuxBoot.fdf     |  201 +
 .../Drivers/FailSafeDxe/FailSafeDxe.inf       |   54 +
 .../Library/AcpiHelperLib/AcpiHelperLib.inf   |   33 +
 .../Library/AcpiPccLib/AcpiPccLib.inf         |   41 +
 .../Library/FailSafeLib/FailSafeLib.inf       |   41 +
 .../Ampere/JadePkg/AcpiTables/AcpiTables.inf  |   20 +
 .../AcpiPlatformDxe/AcpiPlatformDxe.inf       |   76 +
 .../BootOptionsRecoveryDxe.inf                |   39 +
 .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf     |   45 +
 .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf     |   45 +
 .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf   |   52 +
 .../PCF85063RealTimeClockLib.inf              |   44 +
 .../Library/PcieBoardLib/PcieBoardLib.inf     |   60 +
 Platform/Ampere/LinuxBootPkg/LinuxBoot.inf    |   17 +
 .../AcpiCommonTables/AcpiCommonTables.inf     |   44 +
 .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   56 +
 .../Drivers/ATFHobPei/ATFHobPeim.inf          |   41 +
 .../Drivers/AcpiConfigDxe/AcpiConfigDxe.inf   |   56 +
 .../BootProgressDxe/BootProgressDxe.inf       |   51 +
 .../BootProgressPeim/BootProgressPeim.inf     |   49 +
 .../Drivers/CpuConfigDxe/CpuConfigDxe.inf     |   58 +
 .../Drivers/DebugInfoPei/DebugInfoPei.inf     |   41 +
 .../Drivers/FlashFvbDxe/FlashFvbDxe.inf       |   54 +
 .../Drivers/FlashPei/FlashPei.inf             |   51 +
 .../Drivers/MemInfoDxe/MemInfoDxe.inf         |   59 +
 .../Drivers/MemoryInitPeim/MemoryInitPeim.inf |   64 +
 .../MmCommunicationDxe/MmCommunication.inf    |   57 +
 .../MmCommunicationPei/MmCommunicationPei.inf |   34 +
 .../PcieDeviceConfigDxe.inf                   |   59 +
 .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
 .../Drivers/RasConfigDxe/RasConfigDxe.inf     |   56 +
 .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf  |   43 +
 .../WatchdogConfigDxe/WatchdogConfigDxe.inf   |   50 +
 .../Library/AmpereCpuLib/AmpereCpuLib.inf     |   44 +
 .../Library/ArmPlatformLib/ArmPlatformLib.inf |   57 +
 .../Library/DwGpioLib/DwGpioLib.inf           |   33 +
 .../Library/DwI2cLib/DwI2cLib.inf             |   38 +
 .../Library/FlashLib/FlashLib.inf             |   36 +
 .../MailboxInterfaceLib.inf                   |   37 +
 .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   63 +
 .../MmCommunicationLib/MmCommunicationLib.inf |   35 +
 .../Library/NVParamLib/NVParamLib.inf         |   32 +
 .../Library/PcieCoreLib/PcieCoreLib.inf       |   68 +
 .../Library/PlatformPeiLib/PlatformPeiLib.inf |   42 +
 .../AmpereAltraPkg/Library/RngLib/RngLib.inf  |   29 +
 .../SystemFirmwareInterfaceLib.inf            |   30 +
 .../Library/TrngLib/TrngLib.inf               |   29 +
 .../LinuxBootBootManagerLib.inf               |   54 +
 .../PlatformUiLib/PlatformManagerUiLib.inf    |   47 +
 .../Drivers/FailSafeDxe/FailSafe.h            |   20 +
 .../Drivers/FailSafeDxe/Watchdog.h            |   29 +
 .../Include/Library/FailSafeLib.h             |   62 +
 .../Drivers/AcpiPlatformDxe/AcpiApei.h        |  123 +
 .../Drivers/AcpiPlatformDxe/AcpiNfit.h        |   49 +
 .../Drivers/AcpiPlatformDxe/AcpiPlatform.h    |   76 +
 .../PCF85063RealTimeClockLib/PCF85063.h       |   91 +
 .../Library/PcieBoardLib/NVDataStruc.h        |   89 +
 .../Library/PcieBoardLib/PcieBoardScreen.h    |  138 +
 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h  |  451 ++
 .../Pci/PciHostBridgeDxe/PciRootBridgeIo.h    |  554 ++
 .../Drivers/AcpiConfigDxe/AcpiConfigDxe.h     |   85 +
 .../Drivers/CpuConfigDxe/CpuConfigDxe.h       |   74 +
 .../Drivers/CpuConfigDxe/NVDataStruc.h        |   19 +
 .../Drivers/MemInfoDxe/MemInfoScreen.h        |  168 +
 .../Drivers/MemInfoDxe/NVDataStruc.h          |   47 +
 .../MmCommunicationDxe/MmCommunicate.h        |   22 +
 .../Drivers/PcieDeviceConfigDxe/NVDataStruc.h |   56 +
 .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.h |   78 +
 .../Drivers/PcieDeviceConfigDxe/PcieHelper.h  |   58 +
 .../Drivers/PlatformInfoDxe/PlatformInfoHii.h |   22 +
 .../Drivers/RasConfigDxe/NVDataStruc.h        |   46 +
 .../Drivers/RasConfigDxe/RasConfigDxe.h       |   82 +
 .../Drivers/WatchdogConfigDxe/NVDataStruc.h   |   27 +
 .../WatchdogConfigDxe/WatchdogConfigDxe.h     |   82 +
 .../AmpereAltraPkg/Include/AcpiHeader.h       |   37 +
 .../AmpereAltraPkg/Include/AcpiNVDataStruc.h  |   28 +
 .../Include/Guid/AcpiConfigFormSet.h          |   19 +
 .../Include/Guid/CpuConfigHii.h               |   19 +
 .../Include/Guid/PcieDeviceConfigHii.h        |   19 +
 .../Include/Guid/PlatformInfoHobGuid.h        |   17 +
 .../Include/Guid/WatchdogConfigHii.h          |   19 +
 .../Include/Library/AmpereCpuLib.h            |  282 +
 .../AmpereAltraPkg/Include/Library/FlashLib.h |   42 +
 .../AmpereAltraPkg/Include/Library/GpioLib.h  |   76 +
 .../AmpereAltraPkg/Include/Library/I2cLib.h   |  100 +
 .../Include/Library/MailboxInterfaceLib.h     |  172 +
 .../Include/Library/MmCommunicationLib.h      |   19 +
 .../Include/Library/NVParamLib.h              |  133 +
 .../Include/Library/PcieBoardLib.h            |  102 +
 .../Include/Library/PcieCoreLib.h             |  164 +
 .../Library/SystemFirmwareInterfaceLib.h      |  282 +
 .../AmpereAltraPkg/Include/Library/TrngLib.h  |   31 +
 Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h |   79 +
 .../AmpereAltraPkg/Include/NVParamDef.h       |  515 ++
 Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h  |  203 +
 .../AmpereAltraPkg/Include/Platform/Ac01.h    |  146 +
 .../AmpereAltraPkg/Include/PlatformInfoHob.h  |  182 +
 .../Library/PcieCoreLib/PcieCore.h            |  582 ++
 .../Library/PcieCoreLib/PcieCoreCapCfg.h      |   64 +
 .../Library/PcieCoreLib/PciePatchAcpi.h       |   30 +
 .../Include/Guid/PlatformManagerHii.h         |   31 +
 .../Include/Library/AcpiHelperLib.h           |  109 +
 .../Include/Library/AcpiPccLib.h              |  166 +
 .../Library/PlatformUiLib/PlatformManager.h   |   51 +
 .../PlatformUiLib/PlatformManagerVfr.h        |   28 +
 .../JadePkg/Library/PcieBoardLib/Vfr.vfr      |  212 +
 .../Drivers/AcpiConfigDxe/Vfr.vfr             |   69 +
 .../Drivers/CpuConfigDxe/Vfr.vfr              |   43 +
 .../AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr |   62 +
 .../Drivers/PcieDeviceConfigDxe/Vfr.vfr       |   50 +
 .../Drivers/PlatformInfoDxe/Vfr.vfr           |  112 +
 .../Drivers/RasConfigDxe/Vfr.vfr              |  105 +
 .../Drivers/WatchdogConfigDxe/Vfr.vfr         |   58 +
 .../Drivers/FailSafeDxe/FailSafeDxe.c         |  184 +
 .../Drivers/FailSafeDxe/Watchdog.c            |  357 ++
 .../Library/AcpiHelperLib/AcpiHelperLib.c     |  246 +
 .../Library/AcpiPccLib/AcpiPccLib.c           |  241 +
 .../Library/FailSafeLib/FailSafeLib.c         |  320 +
 .../Drivers/AcpiPlatformDxe/AcpiApei.c        |  476 ++
 .../Drivers/AcpiPlatformDxe/AcpiDsdt.c        |  445 ++
 .../Drivers/AcpiPlatformDxe/AcpiMadt.c        |  351 +
 .../Drivers/AcpiPlatformDxe/AcpiNfit.c        |  599 ++
 .../Drivers/AcpiPlatformDxe/AcpiPcct.c        |  196 +
 .../Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c |  178 +
 .../Drivers/AcpiPlatformDxe/AcpiPptt.c        |  378 ++
 .../Drivers/AcpiPlatformDxe/AcpiSlit.c        |  190 +
 .../Drivers/AcpiPlatformDxe/AcpiSrat.c        |  274 +
 .../BootOptionsRecoveryDxe.c                  |   58 +
 .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c       |  709 +++
 .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.c       |  705 +++
 .../SmbiosPlatformDxe/SmbiosPlatformDxe.c     | 1049 +++
 .../PCF85063RealTimeClockLib/PCF85063.c       |  317 +
 .../PCF85063RealTimeClockLib.c                |  257 +
 .../JadePkg/Library/PcieBoardLib/PcieBoard.c  |  438 ++
 .../Library/PcieBoardLib/PcieBoardCommon.c    |  327 +
 .../Library/PcieBoardLib/PcieBoardScreen.c    | 1120 ++++
 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 1419 +++++
 .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 1582 +++++
 .../Drivers/ATFHobPei/ATFHobPeim.c            |   52 +
 .../Drivers/AcpiConfigDxe/AcpiConfigDxe.c     |  733 +++
 .../BootProgressDxe/BootProgressDxe.c         |  211 +
 .../BootProgressPeim/BootProgressPeim.c       |  210 +
 .../Drivers/CpuConfigDxe/CpuConfigDxe.c       |  508 ++
 .../Drivers/DebugInfoPei/DebugInfoPei.c       |  230 +
 .../Drivers/FlashFvbDxe/FlashFvbDxe.c         |  525 ++
 .../Drivers/FlashPei/FlashPei.c               |  283 +
 .../Drivers/MemInfoDxe/MemInfoNvramLib.c      |  394 ++
 .../Drivers/MemInfoDxe/MemInfoScreen.c        | 1325 ++++
 .../Drivers/MemoryInitPeim/MemoryInitPeim.c   |  151 +
 .../MmCommunicationDxe/MmCommunication.c      |  454 ++
 .../MmCommunicationPei/MmCommunicationPei.c   |   37 +
 .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.c | 1046 +++
 .../Drivers/PcieDeviceConfigDxe/PcieHelper.c  |  191 +
 .../Drivers/PlatformInfoDxe/PlatformInfoDxe.c |  391 ++
 .../Drivers/RasConfigDxe/RasConfigDxe.c       |  762 +++
 .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.c    |  164 +
 .../WatchdogConfigDxe/WatchdogConfigDxe.c     |  460 ++
 .../Library/AmpereCpuLib/AmpereCpuLib.c       |  706 +++
 .../Library/ArmPlatformLib/ArmPlatformLib.c   |  169 +
 .../ArmPlatformLib/ArmPlatformLibMemory.c     |  399 ++
 .../Library/DwGpioLib/DwGpioLib.c             |  314 +
 .../Library/DwI2cLib/DwI2cLib.c               |  883 +++
 .../Library/FlashLib/FlashLib.c               |  358 ++
 .../MailboxInterfaceLib/MailboxInterfaceLib.c |  282 +
 .../MemoryInitPeiLib/MemoryInitPeiLib.c       |   93 +
 .../MmCommunicationLib/MmCommunicationLib.c   |  184 +
 .../Library/NVParamLib/NVParamLib.c           |  202 +
 .../Library/PcieCoreLib/PcieCore.c            | 1266 ++++
 .../Library/PcieCoreLib/PcieCoreLib.c         |  536 ++
 .../Library/PcieCoreLib/PciePatchAcpi.c       |  610 ++
 .../Library/PlatformPeiLib/PlatformPeiLib.c   |   40 +
 .../AmpereAltraPkg/Library/RngLib/RngLib.c    |  141 +
 .../SystemFirmwareInterfaceLib.c              |  328 +
 .../AmpereAltraPkg/Library/TrngLib/TrngLib.c  |   63 +
 .../LinuxBootBootManagerLib/LinuxBootBm.c     |  173 +
 .../Library/PlatformUiLib/PlatformManager.c   |  354 ++
 .../Ampere/AmperePlatformPkg/FvRules.fdf.inc  |  176 +
 Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi | 5639 +++++++++++++++++
 Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi | 5639 +++++++++++++++++
 Platform/Ampere/JadePkg/AcpiTables/CPU.asi    |  127 +
 Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl   |  575 ++
 .../Ampere/JadePkg/AcpiTables/PCI-PDRC.asi    |  217 +
 .../JadePkg/AcpiTables/PCI-S0.Rca01.asi       |  681 ++
 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi | 2078 ++++++
 Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi | 2087 ++++++
 Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi | 1303 ++++
 Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi | 1303 ++++
 Platform/Ampere/JadePkg/AcpiTables/PMU.asi    |   10 +
 Platform/Ampere/JadePkg/JadeBoardSetting.cfg  |  209 +
 .../Library/PcieBoardLib/PcieBoardScreen.uni  |   99 +
 .../Ampere/LinuxBootPkg/AArch64/Readme.md     |   29 +
 .../AmpereAltraPkg/AcpiCommonTables/Bert.aslc |   33 +
 .../AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc |   87 +
 .../AmpereAltraPkg/AcpiCommonTables/Einj.asl  |  165 +
 .../AmpereAltraPkg/AcpiCommonTables/Fadt.aslc |   87 +
 .../AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc |  180 +
 .../AmpereAltraPkg/AcpiCommonTables/Hest.asl  |  330 +
 .../AmpereAltraPkg/AcpiCommonTables/Sdei.asl  |   17 +
 .../AmpereAltraPkg/AcpiCommonTables/Spcr.aslc |   81 +
 .../AmpereAltraPkg/AcpiCommonTables/Ssdt.asl  |   15 +
 .../Drivers/AcpiConfigDxe/VfrStrings.uni      |   27 +
 .../BootProgressDxe/BootProgressDxe.uni       |   16 +
 .../BootProgressPeim/BootProgressPeim.uni     |   18 +
 .../Drivers/CpuConfigDxe/VfrStrings.uni       |   17 +
 .../Drivers/MemInfoDxe/MemInfoDxe.uni         |    9 +
 .../Drivers/MemInfoDxe/MemInfoDxeExtra.uni    |    9 +
 .../MemInfoDxe/MemInfoScreenStrings.uni       |   64 +
 .../PcieDeviceConfigDxe.uni                   |   24 +
 .../Drivers/PlatformInfoDxe/VfrStrings.uni    |   56 +
 .../Drivers/RasConfigDxe/VfrStrings.uni       |   38 +
 .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni  |   10 +
 .../Drivers/RngDxe/RngDxeExtra.uni            |    9 +
 .../Drivers/WatchdogConfigDxe/VfrStrings.uni  |   26 +
 .../ArmPlatformLib/ArmPlatformHelper.S        |   45 +
 .../AmpereAltraPkg/Library/RngLib/RngLib.uni  |   13 +
 .../PlatformUiLib/PlatformManagerStrings.uni  |   21 +
 .../PlatformUiLib/PlatformManagerUiLib.uni    |   13 +
 .../PlatformUiLib/PlatformManagerVfr.Vfr      |   29 +
 226 files changed, 60803 insertions(+)
 create mode 100755 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
 create mode 100755 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
 create mode 100755 Platform/Ampere/JadePkg/Jade.dsc
 create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
 create mode 100755 Platform/Ampere/JadePkg/Jade.fdf
 create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
 create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
 create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
 create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
 create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
 create mode 100644 Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
 create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
 create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
 create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
 create mode 100755 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
 create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
 create mode 100644 Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
 create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
 create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
 create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
 create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
 create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
 create mode 100755 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
 create mode 100644 Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
 create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
 create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
 create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PMU.asi
 create mode 100644 Platform/Ampere/JadePkg/JadeBoardSetting.cfg
 create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
 create mode 100644 Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
 create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
 create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
 create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr

-- 
2.17.1


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

* [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and Mt. Jade platform
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:04   ` Leif Lindholm
  2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
                   ` (33 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This commit adds the support for Ampere’s Altra processor-based Mt. Jade
platform that provides up to 160 processor cores in a dual socket
configuration. The essential modules are wired up enough to boot system
to EDK2 UiApp.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec                                         |  28 +
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                                |  42 ++
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                                            |  46 ++
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                            | 674 +++++++++++++++++++
 Platform/Ampere/JadePkg/Jade.dsc                                                                | 100 +++
 Platform/Ampere/JadePkg/Jade.fdf                                                                | 225 +++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf                                  |  41 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf                         |  64 ++
 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf                             |  44 ++
 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf                         |  57 ++
 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf               |  37 +
 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf                     |  63 ++
 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf                 |  35 +
 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf                                 |  32 +
 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf                         |  42 ++
 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf                                         |  29 +
 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf |  30 +
 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf                                       |  29 +
 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h                                |  17 +
 Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h                                    | 282 ++++++++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h                             | 172 +++++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h                              |  19 +
 Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h                                      | 133 ++++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h                      | 282 ++++++++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h                                         |  31 +
 Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h                                                   |  79 +++
 Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h                                              | 515 ++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h                                           | 146 ++++
 Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h                                         | 182 +++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c                                    |  52 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c                           | 151 +++++
 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c                               | 706 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c                           | 169 +++++
 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c                     | 399 +++++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c                 | 282 ++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c                       |  93 +++
 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c                   | 184 +++++
 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c                                   | 202 ++++++
 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c                           |  40 ++
 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c                                           | 141 ++++
 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c   | 328 +++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c                                         |  63 ++
 Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc                                               | 176 +++++
 Platform/Ampere/JadePkg/JadeBoardSetting.cfg                                                    | 209 ++++++
 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S                        |  45 ++
 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni                                         |  13 +
 46 files changed, 6729 insertions(+)

diff --git a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
new file mode 100755
index 000000000000..7c1d1f84f780
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
@@ -0,0 +1,28 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001B
+  PACKAGE_NAME                   = AmperePlatformPkg
+  PACKAGE_GUID                   = 7A78F1B2-E9BE-4F94-891C-385ED524036C
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes]
+
+[LibraryClasses]
+
+[Guids]
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
new file mode 100644
index 000000000000..f0a5bd04ec22
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2020-2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001B
+  PACKAGE_NAME                   = AmpereAltraPkg
+  PACKAGE_GUID                   = 481F7D0D-7525-4B76-AF12-58E7B82C46C2
+  PACKAGE_VERSION                = 0.1
+
+[Includes]
+  Include
+
+[LibraryClasses]
+  ##  @libraryclass  Defines a set of methods to retrieve CPU info.
+  AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
+
+  ##  @libraryclass  Defines a set of methods to get/set NVParam.
+  NVParamLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
+
+  ##  @libraryclass  Defines a set of methods to access Mailbox interface.
+  MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
+
+  ##  @libraryclass  Defines a set of methods to communicate with SCP.
+  SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
+
+  ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
+  MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
+
+  ##  @libraryclass  Defines a set of methods to generate random numbers by using Hardware RNG.
+  TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
+
+[Guids]
+  ## NVParam MM GUID
+  gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
+
+  ## Include/Guid/PlatformInfoHobGuid.h
+  gPlatformHobGuid             = { 0x7f73e372, 0x7183, 0x4022, { 0xb3, 0x76, 0x78, 0x30, 0x32, 0x6d, 0x79, 0xb4 } }
diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
new file mode 100755
index 000000000000..6ebdf7db0a57
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -0,0 +1,46 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x0001001B
+  PACKAGE_NAME                   = AmpereSiliconPkg
+  PACKAGE_GUID                   = F9EB69A8-7569-4C0E-87D1-3CC9EB7CBF09
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+
+[LibraryClasses]
+
+[Guids]
+  gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
+
+[Ppis]
+
+[PcdsFixedAtBuild]
+  #
+  # SMpro PMpro Pcds
+  #
+  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg|0x100000540000|UINT64|0x00000001
+  gAmpereTokenSpaceGuid.PcdSmproEfuseShadow0|0x10000054a000|UINT64|0x00000002
+  gAmpereTokenSpaceGuid.PcdSmproNsMailboxIndex|0x1|UINT32|0x00000003
+  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg|0x100001540000|UINT64|0x00000004
+
+[PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
+  #
+  # Firmware Volume Pcds
+  #
+  gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
new file mode 100755
index 000000000000..af66c27822a3
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -0,0 +1,674 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+  #
+  # Allow dynamic PCDs
+  #
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+  #
+  # Random Generator Library
+  #
+  TrngLib|Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
+  RngLib|Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
+
+  #
+  # ARM Architectural Libraries
+  #
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+  ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
+
+  #
+  # Ampere Altra specific Libraries
+  #
+  ArmPlatformLib|Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
+  PlatformPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+  NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
+  MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
+  SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
+  AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
+
+  #
+  # ARM PL011 UART Driver
+  #
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
+
+  #
+  # Timer Library
+  #
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+  #
+  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
+  # in the debugger will show load and unload commands for symbols. You can cut and paste this
+  # into the command window to load symbols. We should be able to use a script to do this, but
+  # the version of RVD I have does not support scripts accessing system memory.
+  #
+  #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+  #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
+
+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+
+  #
+  # BDS Libraries
+  #
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+
+  #
+  # UEFI Shell libraries
+  #
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf
+
+  #
+  # Secure Boot dependencies
+  #
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+
+  #
+  # re-use the UserPhysicalPresent() dummy implementation from the ovmf tree
+  #
+  PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf
+!else
+  TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+  AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+!endif
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+
+  #
+  # Networking Requirements
+  #
+!if $(NETWORK_TLS_ENABLE) == TRUE
+  TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
+!endif
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
+
+!ifdef $(EDK2_SKIP_PEICORE)
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+!endif
+
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.PEIM]
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.SEC, LibraryClasses.common.PEIM]
+  MemoryInitPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+!endif
+!if $(TARGET) != RELEASE
+  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+
+  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+
+[LibraryClasses.ARM,LibraryClasses.AARCH64]
+  #
+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+  # This library provides the instrinsic functions generate by a given compiler.
+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+  #
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+  #
+  # Add support for GCC stack protector
+  #
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+  #
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+  #
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+  #
+  # If TRUE, Graphics Output Protocol will be installed on virtual handle
+  # created by ConsplitterDxe. It could be set FALSE to save size.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+[PcdsFixedAtBuild.common]
+!ifdef $(FIRMWARE_VER)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
+!endif
+
+  #
+  # SBSA Watchdog Count
+  #
+!ifndef DISABLE_SBSA_WATCHDOG
+  gArmPlatformTokenSpaceGuid.PcdWatchdogCount|1
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  #  DEBUG_INFO      0x00000040  // Informational debug messages
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNP Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // LoadFile
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                              // significantly impact boot performance
+  #  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragements for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCore|0x0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+
+  #
+  # Stacks for MPCores in Normal World
+  #
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x91100000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x20000
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000
+
+  #
+  # System Memory Base
+  #
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x90000000
+
+  #
+  # UEFI region size
+  #
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000
+
+  #
+  # Ampere Altra Core-Cluster profile
+  #
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|80
+  gArmPlatformTokenSpaceGuid.PcdClusterCount|40
+
+  #
+  # PL011 - Serial Terminal
+  # Ampere Altra UART0
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x100002600000
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|32
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz|1843200
+  gArmPlatformTokenSpaceGuid.PL011UartInterrupt|0x62
+
+  #
+  # PL011 - Serial Debug UART
+  # Ampere Altra UART2
+  #
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|0x100002620000
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|115200
+
+  #
+  # We want to use the Shell Libraries but don't want it to initialise
+  # automatically. We initialise the libraries when the command is called by the
+  # Shell.
+  #
+  gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+  #
+  # ARM SBSA Watchdog
+  #
+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x1000027c0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x1000027d0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|92
+
+  #
+  # ARM Generic Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x100100000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x100100140000
+
+  #
+  # ARM Architectural Timer Frequency
+  #
+  # Set it to 0 so that the code will read frequence from register
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
+  gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+
+  #
+  # use the TTY terminal type
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+  #
+  # GUID of the UI app
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  #
+  # Enable strict image permissions for all images. (This applies
+  # only to images that were built with >= 4 KB section alignment.)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
+
+  #
+  # Enable NX memory protection for all non-code regions, including OEM and OS
+  # reserved ones, with the exception of LoaderData regions, of which OS loaders
+  # (i.e., GRUB) may assume that its contents are executable.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1
+
+  #
+  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
+
+  #
+  # MmCommunication
+  #
+  gArmTokenSpaceGuid.PcdMmBufferBase|0x88300000
+  gArmTokenSpaceGuid.PcdMmBufferSize|0x100000
+
+[PcdsDynamicHii.common.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|10
+
+[PcdsDynamicDefault.common]
+  #
+  # Fist DRAM Memory region under 4GB address range
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x70000000
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
+
+################################################################################
+#
+# Component Section - list of all EDK II Component Entries defined by this Platform
+#
+################################################################################
+
+[Components.common]
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+
+  #
+  # DXE Phase modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+  #
+  # PCD
+  #
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+!if $(SECURE_BOOT_ENABLE) == TRUE
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+!endif
+  }
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  #
+  # Environment Variables Protocol
+  #
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+    <LibraryClasses>
+      BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+      TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+      VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+      NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
+  }
+
+  #
+  # Timer
+  #
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # ARM GIC Dxe
+  #
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  #
+  # Uefi Cpu
+  #
+  UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  #
+  # Console
+  #
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  #
+  # Simple TextIn/TextOut for UEFI Terminal
+  #
+  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+
+  #
+  # Hii Database
+  #
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Semi-hosting filesystem
+  #
+  ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
+
+  #
+  # Networking stack
+  #
+!include NetworkPkg/Network.dsc.inc
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork2CommandsLib/UefiShellNetwork2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+!ifdef $(INCLUDE_TFTP_COMMAND)
+  ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+!endif #$(INCLUDE_TFTP_COMMAND)
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
new file mode 100755
index 000000000000..f68af24a0d78
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -0,0 +1,100 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Jade
+  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x0001001B
+  OUTPUT_DIRECTORY               = Build/Jade
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Ampere/JadePkg/Jade.fdf
+
+  #
+  # Defines for default states. These can be changed on the command line.
+  # -D FLAG=VALUE
+  #
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  #  DEBUG_INFO      0x00000040  // Informational debug messages
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNP Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // LoadFile
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                              // significantly impact boot performance
+  #  DEBUG_ERROR     0x80000000  // Error
+  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
+  DEFINE FIRMWARE_VER            = 0.01.001
+  DEFINE EDK2_SKIP_PEICORE       = TRUE
+  DEFINE SECURE_BOOT_ENABLE      = FALSE
+  DEFINE INCLUDE_TFTP_COMMAND    = TRUE
+
+  #
+  # Network definition
+  #
+  DEFINE NETWORK_IP6_ENABLE                  = FALSE
+  DEFINE NETWORK_HTTP_BOOT_ENABLE            = TRUE
+  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS      = TRUE
+  DEFINE NETWORK_TLS_ENABLE                  = FALSE
+
+# Include default Ampere Platform DSC file
+!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+
+################################################################################
+#
+# Specific Platform Library
+#
+################################################################################
+[LibraryClasses]
+  #
+  # RTC Library: Common RTC
+  #
+  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+
+################################################################################
+#
+# Specific Platform Pcds
+#
+################################################################################
+[PcdsFeatureFlag.common]
+[PcdsFixedAtBuild.common]
+
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  # Override the default values from SecurityPkg to ensure images
+  # from all sources are verified in secure boot
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+!endif
+
+
+################################################################################
+#
+# Specific Platform Component
+#
+################################################################################
+[Components.common]
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
new file mode 100755
index 000000000000..8ed6df381aed
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -0,0 +1,225 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL33_JADE_UEFI]
+BaseAddress   = 0x92000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+Size          = 0x007C0000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x10000
+NumBlocks     = 0x7C
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+#
+# FV MAIN
+# Offset: 0x00000000
+# Size:   0x00740000
+#
+0x00000000|0x00740000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+#
+# NV Variables
+# T.B.D
+#
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 61C0F511-A691-4F54-974F-B9A42172CE53
+
+APRIORI PEI {
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+}
+
+  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
+  INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+
+  #
+  # Print platform information before passing control into the Driver Execution Environment (DXE) phase
+  #
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+[FV.FvMain]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 5C60F367-A505-419A-859E-2A4FF6CA6FE5
+
+APRIORI DXE {
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+}
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+  INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
+  INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+!if $(SECURE_BOOT_ENABLE) == TRUE
+  INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf
+!endif
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Environment Variables Protocol
+  #
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+
+  #
+  # Timer
+  #
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # ARM GIC Dxe
+  #
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf
+
+  #
+  # FAT filesystem + GPT/MBR partitioning
+  #
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF FatPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+!if $(INCLUDE_TFTP_COMMAND) == TRUE
+  INF ShellPkg/DynamicCommand/TftpDynamicCommand/TftpDynamicCommand.inf
+!endif
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF MdeModulePkg/Universal/DriverHealthManagerDxe/DriverHealthManagerDxe.inf
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  INF MdeModulePkg/Application/UiApp/UiApp.inf
+
+  #
+  # Networking stack
+  #
+!include NetworkPkg/Network.fdf.inc
+
+!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
new file mode 100644
index 000000000000..c1bcdbad9392
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
@@ -0,0 +1,41 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = ATFHobPeim
+  FILE_GUID                     = B1975734-77C2-4827-9617-914883F3B578
+  MODULE_TYPE                   = PEIM
+  VERSION_STRING                = 1.0
+  ENTRY_POINT                   = InitializeATFHobPeim
+
+[Sources]
+  ATFHobPeim.c
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  HobLib
+  PcdLib
+  PeiServicesLib
+  PeimEntryPoint
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
new file mode 100755
index 000000000000..8d857b9612b4
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
@@ -0,0 +1,64 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = MemoryInit
+  FILE_GUID                      = AC939A4D-D185-463F-A0CE-4120BF0ACF79
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializeMemory
+
+[Sources]
+  MemoryInitPeim.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmPlatformLib
+  DebugLib
+  HobLib
+  MemoryInitPeiLib
+  PeimEntryPoint
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+  gPlatformHobGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
new file mode 100644
index 000000000000..cb2eeddbb669
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
@@ -0,0 +1,44 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = AmpereCpuLib
+  FILE_GUID                      = 4ACE898C-4DDC-4EF7-BB6C-91549BDF5B9C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = CpuLib
+
+[Sources]
+  AmpereCpuLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  HobLib
+  IoLib
+  NVParamLib
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmPlatformTokenSpaceGuid.PcdClusterCount
+
+  gAmpereTokenSpaceGuid.PcdSmproEfuseShadow0
+
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+
+[Guids]
+  gPlatformHobGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
new file mode 100755
index 000000000000..a4d29379198d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
@@ -0,0 +1,57 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ArmPlatformLib
+  FILE_GUID                      = 7F829BB1-5092-4D8E-8FB7-2B2C2A80D783
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = ArmPlatformLib
+
+[Sources]
+  ArmPlatformHelper.S
+  ArmPlatformLib.c
+  ArmPlatformLibMemory.c
+
+[LibraryClasses]
+  AmpereCpuLib
+  ArmLib
+  ArmSmcLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  PL011UartLib
+  PcdLib
+  SerialPortLib
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdMmBufferBase
+  gArmTokenSpaceGuid.PcdMmBufferSize
+
+[FixedPcd]
+  gArmPlatformTokenSpaceGuid.PcdClusterCount
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCore
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
new file mode 100644
index 000000000000..de07a573b62b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
@@ -0,0 +1,37 @@
+## @file
+#  The library implements the hardware Mailbox (Doorbell) interface for communication
+#  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
+#
+#  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = MailboxInterface
+  FILE_GUID                      = EE482BD0-A91A-45BE-83B1-2157A0FB94C3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MailboxInterfaceLib
+
+[Sources]
+  MailboxInterfaceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  TimerLib
+
+[FixedPcd]
+  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
+  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
new file mode 100755
index 000000000000..b6dc7d2ec04a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
@@ -0,0 +1,63 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ArmMemoryInitPeiLib
+  FILE_GUID                      = 55DDB6E0-70B5-11E0-B33E-0002A5D5C51B
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MemoryInitPeiLib
+
+[Sources]
+  MemoryInitPeiLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmMmuLib
+  ArmPlatformLib
+  DebugLib
+  HobLib
+
+[Guids]
+  gEfiMemoryTypeInformationGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFdBaseAddress
+  gArmTokenSpaceGuid.PcdFdSize
+
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize
+
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+  gArmTokenSpaceGuid.PcdSystemMemorySize
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
new file mode 100755
index 000000000000..1693fa7e8050
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
@@ -0,0 +1,35 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = MmCommunicationLib
+  FILE_GUID                      = 106099B8-0051-4B35-9578-EFB1045D2FA8
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = MmCommunicationLib
+  CONSTRUCTOR                    = MmCommunicationLibConstructor
+
+[Sources]
+  MmCommunicationLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmSmcLib
+  BaseMemoryLib
+  DebugLib
+  PcdLib
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdMmBufferBase
+  gArmTokenSpaceGuid.PcdMmBufferSize
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
new file mode 100755
index 000000000000..2d506913f733
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
@@ -0,0 +1,32 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = NVParamLib
+  FILE_GUID                     = 8512FF56-11DF-4A16-A0CF-81B27DBD23FB
+  MODULE_TYPE                   = BASE
+  VERSION_STRING                = 0.1
+  LIBRARY_CLASS                 = NVParamLib
+
+[Sources.common]
+  NVParamLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MmCommunicationLib
+
+[Guids]
+  gNVParamMmGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
new file mode 100644
index 000000000000..524b3fe777b8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
@@ -0,0 +1,42 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ArmPlatformPeiLib
+  FILE_GUID                      = 49D37060-70B5-11E0-AA2D-0002A5D5C51B
+  MODULE_TYPE                    = SEC
+  VERSION_STRING                 = 0.1
+  LIBRARY_CLASS                  = PlatformPeiLib
+
+[Sources]
+  PlatformPeiLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmPlatformLib
+  ArmSmcLib
+  DebugLib
+  HobLib
+  PcdLib
+  PeiServicesLib
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdFvBaseAddress
+  gArmTokenSpaceGuid.PcdFvSize
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
new file mode 100644
index 000000000000..5b25a64d5451
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  Instance of RNG (Random Number Generator) Library.
+#
+#  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = RngLib
+  MODULE_UNI_FILE                = RngLib.uni
+  FILE_GUID                      = 9CC35499-5CC8-49A2-8C27-AE7B3B83D149
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RngLib
+
+[Sources]
+  RngLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  TrngLib
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
new file mode 100644
index 000000000000..f11291003dde
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
@@ -0,0 +1,30 @@
+## @file
+#  Provides functions for communication with System Firmware (SMpro/PMpro)
+#  via interfaces like Mailbox.
+#
+#  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SystemFirmwareInterface
+  FILE_GUID                      = 8574F1CC-BF8C-46FD-9276-5B202E2A425C
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SystemFirmwareInterfaceLib
+
+[Sources]
+  SystemFirmwareInterfaceLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MailboxInterfaceLib
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
new file mode 100644
index 000000000000..aac835ed46ed
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
@@ -0,0 +1,29 @@
+## @file
+#  Instance of RNG (Random Number Generator) Library.
+#
+#  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = Trng
+  FILE_GUID                      = 30200949-29CF-4BDB-8300-EFFC44D03603
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TrngLib
+
+[Sources]
+  TrngLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  SystemFirmwareInterfaceLib
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
new file mode 100755
index 000000000000..5b199bf2b4e8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
@@ -0,0 +1,17 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_INFO_HOB_GUID_H_
+#define PLATFORM_INFO_HOB_GUID_H_
+
+#define PLATFORM_INFO_HOB_GUID \
+  { 0x7f73e372, 0x7183, 0x4022, { 0xb3, 0x76, 0x78, 0x30, 0x32, 0x6d, 0x79, 0xb4 } }
+
+extern EFI_GUID gPlatformHobGuid;
+
+#endif /* PLATFORM_INFO_HOB_GUID_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
new file mode 100644
index 000000000000..de576474fb48
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
@@ -0,0 +1,282 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef AMPERE_CPU_LIB_H_
+#define AMPERE_CPU_LIB_H_
+
+/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
+#define CLIDR_CTYPE_SHIFT(Level)    (3 * (Level - 1))
+#define CLIDR_CTYPE_MASK(Level)     (7 << CLIDR_CTYPE_SHIFT(Level))
+#define CLIDR_CTYPE(Clidr, Level) \
+  (((Clidr) & CLIDR_CTYPE_MASK(Level)) >> CLIDR_CTYPE_SHIFT(Level))
+
+#define CCSIDR_NUMSETS_SHIFT        13
+#define CCSIDR_NUMSETS_MASK         0xFFFE000
+#define CCSIDR_NUMSETS(Ccsidr) \
+  (((Ccsidr) & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT)
+#define CCSIDR_ASSOCIATIVITY_SHIFT  3
+#define CCSIDR_ASSOCIATIVITY_MASK   0x1FF8
+#define CCSIDR_ASSOCIATIVITY(Ccsidr) \
+  (((Ccsidr) & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_SHIFT)
+#define CCSIDR_LINE_SIZE_SHIFT      0
+#define CCSIDR_LINE_SIZE_MASK       0x7
+#define CCSIDR_LINE_SIZE(Ccsidr) \
+  (((Ccsidr) & CCSIDR_LINE_SIZE_MASK) >> CCSIDR_LINE_SIZE_SHIFT)
+
+#define SUBNUMA_MODE_MONOLITHIC        0
+#define SUBNUMA_MODE_HEMISPHERE        1
+#define SUBNUMA_MODE_QUADRANT          2
+
+#define MONOLITIC_NUM_OF_REGION        1
+#define HEMISPHERE_NUM_OF_REGION       2
+#define QUADRANT_NUM_OF_REGION         4
+#define SUBNUMA_CPM_REGION_SIZE        4
+#define NUM_OF_CPM_PER_MESH_ROW        8
+
+#define CPM_PER_ROW_OFFSET(CpmId)      ((CpmId) % NUM_OF_CPM_PER_MESH_ROW)
+#define CPM_ROW_NUMBER(CpmId)          ((CpmId) / NUM_OF_CPM_PER_MESH_ROW)
+
+#define SOCKET_ID(CpuId)               ((CpuId) / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM))
+#define CLUSTER_ID(CpuId)              (((CpuId) / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM)
+
+
+/**
+  Get the SubNUMA mode.
+
+  @return   UINT8      The SubNUMA mode.
+
+**/
+UINT8
+EFIAPI
+CpuGetSubNumaMode (
+  VOID
+  );
+
+/**
+  Get the number of SubNUMA region.
+
+  @return   UINT8      The number of SubNUMA region.
+
+**/
+UINT8
+EFIAPI
+CpuGetNumberOfSubNumaRegion (
+  VOID
+  );
+
+/**
+  Get the SubNUMA node of a CPM.
+
+  @param    SocketId    Socket index.
+  @param    Cpm         CPM index.
+  @return   UINT8       The SubNUMA node of a CPM.
+
+**/
+UINT8
+EFIAPI
+CpuGetSubNumNode (
+  UINT8  Socket,
+  UINT16 Cpm
+  );
+
+/**
+  Get the associativity of cache.
+
+  @param    Level       Cache level.
+  @return   UINT32      Associativity of cache.
+
+**/
+UINT32
+EFIAPI
+CpuGetAssociativity (
+  UINT32 Level
+  );
+
+/**
+  Get the cache size.
+
+  @param    Level       Cache level.
+  @return   UINT32      Cache size.
+
+**/
+UINT32
+EFIAPI
+CpuGetCacheSize (
+  UINT32 Level
+  );
+
+/**
+  Get the number of supported socket.
+
+  @return   UINT8      Number of supported socket.
+
+**/
+UINT8
+EFIAPI
+GetNumberOfSupportedSockets (
+  VOID
+  );
+
+/**
+  Get the number of active socket.
+
+  @return   UINT8      Number of active socket.
+
+**/
+UINT8
+EFIAPI
+GetNumberOfActiveSockets (
+  VOID
+  );
+
+/**
+  Get the number of active CPM per socket.
+
+  @param    SocketId    Socket index.
+  @return   UINT16      Number of CPM.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCPMsPerSocket (
+  UINT8 SocketId
+  );
+
+/**
+  Get the number of configured CPM per socket.
+
+  @param    SocketId    Socket index.
+  @return   UINT16      Number of configured CPM.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfConfiguredCPMs (
+  UINT8 SocketId
+  );
+
+/**
+  Set the number of configured CPM per socket.
+
+  @param    SocketId        Socket index.
+  @param    NumberOfCPMs    Number of CPM to be configured.
+  @return   EFI_SUCCESS     Operation succeeded.
+  @return   Others          An error has occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+SetNumberOfConfiguredCPMs (
+  UINT8  SocketId,
+  UINT16 NumberOfCPMs
+  );
+
+/**
+  Get the maximum number of core per socket. This number
+  should be the same for all sockets.
+
+  @return   UINT16      Maximum number of core.
+
+**/
+UINT16
+EFIAPI
+GetMaximumNumberOfCores (
+  VOID
+  );
+
+/**
+  Get the maximum number of CPM per socket. This number
+  should be the same for all sockets.
+
+  @return   UINT32      Maximum number of CPM.
+
+**/
+UINT16
+EFIAPI
+GetMaximumNumberOfCPMs (
+  VOID
+  );
+
+/**
+  Get the number of active cores of a sockets.
+
+  @return   UINT16      Number of active core.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCoresPerSocket (
+  UINT8 SocketId
+  );
+
+/**
+  Get the number of active cores of all socket.
+
+  @return   UINT16      Number of active core.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCores (
+  VOID
+  );
+
+/**
+  Check if the logical CPU is enabled or not.
+
+  @param    CpuId       The logical Cpu ID. Started from 0.
+  @return   BOOLEAN     TRUE if the Cpu enabled
+                        FALSE if the Cpu disabled.
+
+**/
+BOOLEAN
+EFIAPI
+IsCpuEnabled (
+  UINT16 CpuId
+  );
+
+
+/**
+  Check if the slave socket is present
+
+  @return   BOOLEAN     TRUE if the Slave Cpu is present
+                        FALSE if the Slave Cpu is not present
+
+**/
+BOOLEAN
+EFIAPI
+IsSlaveSocketPresent (
+  VOID
+  );
+
+/**
+  Check if the slave socket is active
+
+  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
+                        FALSE if the Slave CPU Socket is not active.
+
+**/
+BOOLEAN
+EFIAPI
+IsSlaveSocketActive (
+  VOID
+  );
+
+/**
+  Check if the CPU product ID is Ac01
+  @return   BOOLEAN     TRUE if the Product ID is Ac01
+                        FALSE otherwise.
+
+**/
+BOOLEAN
+EFIAPI
+IsAc01Processor (
+  VOID
+  );
+
+#endif /* AMPERE_CPU_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
new file mode 100644
index 000000000000..2750487f3e96
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
@@ -0,0 +1,172 @@
+/** @file
+  The library implements the hardware Mailbox (Doorbell) interface for communication
+  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
+
+  A transfer to SMpro/PMpro is performed on a doorbell channel which is implemented through
+  hardware doorbell registers. Each transfer can be up to 12 bytes long, including 4 bytes
+  for the message and two 4 bytes for additional data.
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MAILBOX_INTERFACE_LIB_H_
+#define MAILBOX_INTERFACE_LIB_H_
+
+#define SMPRO_DB_MAX                     8
+#define PMPRO_DB_MAX                     8
+#define NUMBER_OF_DOORBELLS_PER_SOCKET   (SMPRO_DB_MAX + PMPRO_DB_MAX)
+
+//
+// General address offset of Doorbell registers
+//
+#define DB_IN_REG_OFST            0x00000000 // Doorbell In
+#define DB_DIN0_REG_OFST          0x00000004 // Doorbell In Data
+#define DB_DIN1_REG_OFST          0x00000008 // Doorbell In Data
+#define DB_OUT_REG_OFST           0x00000010 // Doorbell Out
+#define DB_DOUT0_REG_OFST         0x00000014 // Doorbell Out Data
+#define DB_DOUT1_REG_OFST         0x00000018 // Doorbell Out Data
+#define DB_STATUS_REG_OFST        0x00000020 // Doorbell Interrupt Status
+#define DB_STATUS_MASK_REG_OFST   0x00000024 // Doorbell Interrupt Status Mask
+
+//
+// List of supported doorbells
+//
+typedef enum {
+  //
+  // PMpro Doorbells
+  //
+  PMproDoorbellChannel0 = 0,
+  PMproDoorbellChannel1,
+  PMproDoorbellChannel2,
+  PMproDoorbellChannel3,
+  PMproDoorbellChannel4,
+  PMproDoorbellChannel5,
+  PMproDoorbellChannel6,
+  PMproDoorbellChannel7,
+  //
+  // SMpro Doorbells
+  //
+  SMproDoorbellChannel0 = PMPRO_DB_MAX,
+  SMproDoorbellChannel1,
+  SMproDoorbellChannel2,
+  SMproDoorbellChannel3,
+  SMproDoorbellChannel4,
+  SMproDoorbellChannel5,
+  SMproDoorbellChannel6,
+  SMproDoorbellChannel7
+} DOORBELL_CHANNELS;
+
+#pragma pack(1)
+//
+// Mailbox Message Data
+//
+// A mailbox transaction supports up to 12 bytes long,
+// including 4 bytes for message and two 4 bytes for extended data.
+//
+typedef struct {
+  UINT32 Data;
+  UINT32 ExtendedData[2];
+} MAILBOX_MESSAGE_DATA;
+
+#pragma pack()
+
+//
+// Timeout configuration when waiting for an doorbell interrupt status
+//
+#define MAILBOX_POLL_TIMEOUT_US  10000000
+#define MAILBOX_POLL_INTERVAL_US 1000
+#define MAILBOX_POLL_COUNT       (MAILBOX_POLL_TIMEOUT_US / MAILBOX_POLL_INTERVAL_US)
+
+/**
+  Get the base address of a doorbell.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+
+  @retval UINT32                The base address of the doorbell.
+                                The returned value is 0 indicate that the input parameters are invalid.
+
+**/
+UINTN
+EFIAPI
+MailboxGetDoorbellAddress (
+  IN UINT8             Socket,
+  IN DOORBELL_CHANNELS Doorbell
+  );
+
+/**
+  Get the interrupt number of a doorbell.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+
+  @retval UINT32                The interrupt number.
+                                The returned value is 0 indicate that the input parameters are invalid.
+
+**/
+UINT32
+EFIAPI
+MailboxGetDoorbellInterruptNumber (
+  IN UINT8             Socket,
+  IN DOORBELL_CHANNELS Doorbell
+  );
+
+/**
+  Read a message via the hardware Doorbell interface.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+  @param[out] Message           Pointer to the Mailbox message.
+
+  @retval EFI_SUCCESS           Read the message successfully.
+  @retval EFI_TIMEOUT           Timeout occurred when waiting for available message in the mailbox.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN  UINT8                Socket,
+  IN  DOORBELL_CHANNELS    Doorbell,
+  OUT MAILBOX_MESSAGE_DATA *Message
+  );
+
+/**
+  Write a message via the hardware Doorbell interface.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbel channel for communication with the SMpro/PMpro.
+  @param[in]  Message           Pointer to the Mailbox message.
+
+  @retval EFI_SUCCESS           Write the message successfully.
+  @retval EFI_TIMEOUT           Timeout occurred when waiting for acknowledge signal from the mailbox.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT8                Socket,
+  IN DOORBELL_CHANNELS    Doorbell,
+  IN MAILBOX_MESSAGE_DATA *Message
+  );
+
+/**
+  Unmask the Doorbell interrupt status.
+
+  @param  Socket    Active socket index.
+  @param  Doorbell  Doorbel channel for communication with the SMpro/PMpro.
+
+  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MailboxUnmaskInterrupt (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell
+  );
+
+#endif /* MAILBOX_INTERFACE_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
new file mode 100644
index 000000000000..9bae501b3382
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMMUNICATION_LIB_H_
+#define MM_COMMUNICATION_LIB_H_
+
+EFI_STATUS
+EFIAPI
+MmCommunicationCommunicate (
+  IN OUT VOID  *CommBuffer,
+  IN OUT UINTN *CommSize OPTIONAL
+  );
+
+#endif /* MM_COMMUNICATION_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
new file mode 100644
index 000000000000..d0c2a6e3bffa
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
@@ -0,0 +1,133 @@
+/** @file
+
+  The non-volatile parameter layout in SPI-NOR is shown below. There is
+  two copies. The master copy is changeable by the user. The Last Known
+  copy is handled by the fail safe future. It is a last know bootable copy.
+
+   ---------------------------
+   | Master Copy             | 16KB
+   | Pre-boot parameters     |
+   ---------------------------
+   | Master Copy             | 16KB
+   | Pre-boot parameters     |
+   | w/o failsafe support    |
+   ---------------------------
+   | Master Copy             |
+   | Manufactory &           | 32KB
+   | Users parameters        |
+   ---------------------------
+   | Last Known Copy         | 16KB
+   | Pre-boot parameters     |
+   ---------------------------
+   |                         | 16KB
+   ---------------------------
+   | Last Known Copy         |
+   | Manufactory &           | 32KB
+   | Users parameters        |
+   ---------------------------
+
+  As each non-volatile parameter requires 8 bytes, there is a total of 8K
+  parameters.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NV_PARAM_LIB_H_
+#define NV_PARAM_LIB_H_
+
+#define NV_PARAM_MAX_SIZE   (64 * 1024)
+#define NV_PARAM_ENTRYSIZE  8
+
+#define NV_PERM_ALL     0xFFFF /* Allowed for all */
+#define NV_PERM_ATF     0x0001 /* Allowed for EL3 code */
+#define NV_PERM_OPTEE   0x0004 /* Allowed for secure El1 */
+#define NV_PERM_BIOS    0x0008 /* Allowed for EL2 non-secure */
+#define NV_PERM_MANU    0x0010 /* Allowed for manufactory interface */
+#define NV_PERM_BMC     0x0020 /* Allowed for BMC interface */
+
+#define NVPARAM_SIZE    0x8
+
+/*
+ * Retrieve a non-volatile parameter
+ *
+ * @param:      Parameter ID to retrieve
+ * @acl_rd:     Permission for read operation. See NV_PERM_XXX.
+ * @val:        Pointer to an UINT32 to store the value
+ * @return:     EFI_INVALID_PARAMETER if parameter is invalid
+ *              EFI_NOT_FOUND if value is not set
+ *              EFI_UNSUPPORTED if service unavailable
+ *              EFI_ACCESS_DENIED if permission not allowed
+ *              Otherwise, 0 for success
+ *
+ * NOTE: If you need a signed value, cast it. It is expected that the
+ * caller will carry the correct permission over various call sequences.
+ *
+ */
+EFI_STATUS
+NVParamGet (
+  IN  UINT32 Param,
+  IN  UINT16 ACLRd,
+  OUT UINT32 *Val
+  );
+
+/*
+ * Set a non-volatile parameter
+ *
+ * @param:      Parameter ID to set
+ * @acl_rd:     Permission for read operation
+ * @acl_wr:     Permission for write operation
+ * @val:        Unsigned int value to set.
+ * @return:     EFI_INVALID_PARAMETER if parameter is invalid
+ *              EFI_UNSUPPORTED if service unavailable
+ *              EFI_ACCESS_DENIED if permission not allowed
+ *              Otherwise, 0 for success
+ *
+ * NOTE: If you have a signed value, cast to unsigned. If the parameter has
+ * not being created before, the provied permission is used to create the
+ * parameter. Otherwise, it is checked for access. It is expected that the
+ * caller will carry the correct permission over various call sequences.
+ *
+ */
+EFI_STATUS
+NVParamSet (
+  IN UINT32 Param,
+  IN UINT16 ACLRd,
+  IN UINT16 ACLWr,
+  IN UINT32 Val
+  );
+
+/*
+ * Clear a non-volatile parameter
+ *
+ * @param:      Parameter ID to set
+ * @acl_wr:     Permission for write operation
+ * @return:     EFI_INVALID_PARAMETER if parameter is invalid
+ *              EFI_UNSUPPORTED if service unavailable
+ *              EFI_ACCESS_DENIED if permission not allowed
+ *              Otherwise, 0 for success
+ *
+ * NOTE: It is expected that the caller will carry the correct permission
+ * over various call sequences.
+ *
+ */
+EFI_STATUS
+NVParamClr (
+  IN UINT32 Param,
+  IN UINT16 ACLWr
+  );
+
+/*
+ * Clear all non-volatile parameters
+ *
+ * @return:     EFI_UNSUPPORTED if service unavailable
+ *              Otherwise, 0 for success
+ */
+EFI_STATUS
+NVParamClrAll (
+  VOID
+  );
+
+#endif /* NV_PARAM_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
new file mode 100644
index 000000000000..ce96c2a6b4b6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
@@ -0,0 +1,282 @@
+/** @file
+  Provides functions for communication with System Firmware (SMpro/PMpro)
+  via interfaces like Mailbox.
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef SYSTEM_FIRMWARE_INTERFACE_LIB_H_
+#define SYSTEM_FIRMWARE_INTERFACE_LIB_H_
+
+//
+// Common mailbox message format
+//   Bit 31:28 - Message type
+//   Bit 27:24 - Message subtype
+//   Bit 23:16 - Message control byte
+//   Bit 15:0  - Message data specific
+//
+#define MAILBOX_MESSAGE_TYPE_SHIFT         28
+#define MAILBOX_MESSAGE_SUBTYPE_SHIFT      24
+#define MAILBOX_MESSAGE_CONTROL_BYTE_SHIFT 16
+
+#define COMMON_MESSAGE_ENCODE(Type,Subtype,Control)             \
+          (                                                     \
+            ((Type) << MAILBOX_MESSAGE_TYPE_SHIFT) |            \
+            ((Subtype) << MAILBOX_MESSAGE_SUBTYPE_SHIFT) |      \
+            ((Control) << MAILBOX_MESSAGE_CONTROL_BYTE_SHIFT)   \
+          )
+
+#define MAILBOX_MESSAGE_CONTROL_URGENT    BIT7
+#define MAILBOX_MESSAGE_CONTROL_TYPICAL   0
+
+//
+// Mailbox Message Types
+//
+#define MAILBOX_MESSAGE_TYPE_DEBUG        0x00
+#define MAILBOX_MESSAGE_TYPE_ADDRESS      0x05
+#define MAILBOX_MESSAGE_TYPE_USER         0x06
+
+//
+// Mailbox Message Type 0x00 - Debug message
+//
+#define MAILBOX_DEBUG_MESSAGE_SUBTYPE_REGISTER_READ  0x01
+#define MAILBOX_DEBUG_MESSAGE_SUBTYPE_REGISTER_WRITE 0x02
+
+//
+// Debug message data format
+//   Bit 31:16 - Refer to definition of COMMON_MESSAGE_ENCODE
+//   Bit 15:0  - Store lower 16-bit of the upper 64-bit address
+//
+#define MAILBOX_DEBUG_MESSAGE_ENCODE(Subtype,Address)       \
+          (                                                 \
+            (COMMON_MESSAGE_ENCODE (                        \
+               MAILBOX_MESSAGE_TYPE_DEBUG,                  \
+               (Subtype),                                   \
+               MAILBOX_MESSAGE_CONTROL_TYPICAL)) |          \
+            ((Address) & 0xFFFF)                            \
+          )
+
+//
+// Mailbox Message Type 0x05 - Address message
+//
+#define MAILBOX_ADDRESS_MESSAGE_SUBTYPE_PCC          0x03
+
+//
+// Address message data format
+//   Bit 31:16 - Refer to definition of COMMON_MESSAGE_ENCODE
+//   Bit 15:8  - Message Parameter
+//   Bit 7:4   - Address message control bit
+//               0x4: 256 alignment
+//               0x0: No alignment
+//   Bit 3:0   - Unused
+//
+#define MAILBOX_ADDRESS_MESSAGE_ENCODE(Subtype,Param,Align) \
+          (                                                 \
+            (COMMON_MESSAGE_ENCODE (                        \
+               MAILBOX_MESSAGE_TYPE_ADDRESS,                \
+               (Subtype),                                   \
+               MAILBOX_MESSAGE_CONTROL_TYPICAL)) |          \
+            ((Param) << 8) |                                \
+            ((Align) << 4)                                  \
+          )
+
+#define MAILBOX_ADDRESS_URGENT_MESSAGE_ENCODE(Subtype,Param,Align) \
+          (                                                        \
+            (COMMON_MESSAGE_ENCODE (                               \
+               MAILBOX_MESSAGE_TYPE_ADDRESS,                       \
+               (Subtype),                                          \
+               MAILBOX_MESSAGE_CONTROL_URGENT)) |                  \
+            ((Param) << 8) |                                       \
+            ((Align) << 4)                                         \
+          )
+
+#define MAILBOX_ADDRESS_256_ALIGNMENT      0x4
+#define MAILBOX_ADDRESS_NO_ALIGNMENT       0x0
+
+#define MAILBOX_ADDRESS_MESSAGE_PARAM_CPPC 0x01
+
+#define MAILBOX_URGENT_CPPC_MESSAGE                 \
+          (                                         \
+            MAILBOX_ADDRESS_URGENT_MESSAGE_ENCODE ( \
+              MAILBOX_ADDRESS_MESSAGE_SUBTYPE_PCC,  \
+              MAILBOX_ADDRESS_MESSAGE_PARAM_CPPC,   \
+              MAILBOX_ADDRESS_256_ALIGNMENT)        \
+          )
+
+#define MAILBOX_TYPICAL_PCC_MESSAGE                 \
+          (                                         \
+            MAILBOX_ADDRESS_MESSAGE_ENCODE (        \
+              MAILBOX_ADDRESS_MESSAGE_SUBTYPE_PCC,  \
+              0,                                    \
+              MAILBOX_ADDRESS_256_ALIGNMENT)        \
+          )
+
+//
+// Mailbox Message Type 0x06 - User message
+//
+#define MAILBOX_USER_MESSAGE_SUBTYPE_SET_CONFIGURATION   0x02
+#define MAILBOX_USER_MESSAGE_SUBTYPE_BOOT_PROGRESS       0x06
+#define MAILBOX_USER_MESSAGE_SUBTYPE_TRNG_PROXY          0x07
+
+//
+// User message data format
+//   Bit 31:16 - Refer to definition of COMMON_MESSAGE_ENCODE
+//   Bit 15:8  - Message Parameter 0
+//   Bit 7:0   - Message Parameter 1
+//
+#define MAILBOX_USER_MESSAGE_ENCODE(Subtype,Param0,Param1) \
+          (                                                \
+            (COMMON_MESSAGE_ENCODE (                       \
+               MAILBOX_MESSAGE_TYPE_USER,                  \
+               (Subtype),                                  \
+               MAILBOX_MESSAGE_CONTROL_TYPICAL)) |         \
+            ((Param0) << 8) |                              \
+            (Param1)                                       \
+          )
+
+//
+// Parameters for True RNG Proxy Message
+//   Param0: 1 - Get a random number
+//   Param1: Unused
+//
+#define MAILBOX_TRNG_PROXY_GET_RANDOM_NUMBER 1
+
+//
+// Parameters for Boot Progress
+//   Param0: 1 - Set boot state
+//   Param1: Boot stage value
+//     0x08: BL33/UEFI Stage
+//
+#define MAILBOX_BOOT_PROGRESS_COMMAND_SET 1
+#define MAILBOX_BOOT_PROGRESS_STAGE_UEFI  8
+
+//
+// Parameters for Set Configuration
+//   Param0: Configuration type
+//     20: Turbo configuration
+//   Param1: Unused
+//
+#define MAILBOX_SET_CONFIGURATION_TURBO 20
+
+/**
+  Read a register which is not accessible from the non-secure world
+  by sending a mailbox message to the SMpro processor.
+
+  Note that not all addresses are allowed.
+
+  @param[in]  Socket       Active socket index.
+  @param[in]  Address      A 64-bit register address to be read.
+  @param[out] Value        A pointer to the read value.
+
+  @retval EFI_SUCCESS           Read the register successfully.
+  @retval EFI_UNSUPPORTED       The register is not allowed.
+  @retval Otherwise             Errors returned from MailboxWrite/MailboxRead() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgRegisterRead (
+  IN  UINT8  Socket,
+  IN  UINTN  Address,
+  OUT UINT32 *Value
+  );
+
+/**
+  Write a value to a register which is not accessible from the non-secure world
+  by sending a mailbox message to the SMpro processor.
+
+  Note that not all addresses are allowed.
+
+  @param[in]  Socket       Active socket index.
+  @param[in]  Address      A 64-bit register address to be written.
+  @param[in]  Value        The value to be written to the register.
+
+  @retval EFI_SUCCESS      Write the register successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise        Errors returned from the MailboxWrite() function.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgRegisterWrite (
+  IN UINT8  Socket,
+  IN UINTN  Address,
+  IN UINT32 Value
+  );
+
+/**
+  Set the PCC shared Memory Address to service handlers in the System Control Processors,
+  using for communication between the System Firmware and OSPM.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  Doorbell         Doorbell index which is numbered like DOORBELL_CHANNELS.
+  @param[in]  AddressAlign256  Enable/Disable 256 alignment.
+  @param[in]  Address          The shared memory address.
+
+  @retval EFI_SUCCESS           Set the shared memory address successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgSetPccSharedMem (
+  IN UINT8     Socket,
+  IN UINT8     Doorbell,
+  IN BOOLEAN   AddressAlign256,
+  IN UINTN     Address
+  );
+
+/**
+  The True RNG is provided by the SMpro processor. This function is to send a mailbox
+  message to the SMpro to request a 64-bit random number.
+
+  @param[out]  Buffer           A pointer to the read 64-bit random number.
+
+  @retval EFI_SUCCESS           The operation succeeds.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite/MailboxRead() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgGetRandomNumber64 (
+  OUT UINT8 *Buffer
+  );
+
+/**
+  Report the UEFI boot progress to the SMpro.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  BootStatus       The status of the UEFI boot.
+  @param[in]  Checkpoint       The UEFI Checkpoint value.
+
+  @retval EFI_SUCCESS           Set the boot progress successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgSetBootProgress (
+  IN UINT8   Socket,
+  IN UINT8   BootStatus,
+  IN UINT32  Checkpoint
+  );
+
+/**
+  Configure the Turbo (Max Performance) mode.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  Enable           Enable/Disable the Turbo (Max performance) mode.
+
+  @retval EFI_SUCCESS           Configure the Turbo successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgTurboConfig (
+  IN UINT8   Socket,
+  IN BOOLEAN Enable
+  );
+
+#endif /* SYSTEM_FIRMWARE_INTERFACE_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
new file mode 100644
index 000000000000..b478986cb032
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
@@ -0,0 +1,31 @@
+/** @file
+  RNG (Random Number Generator) Library that uses Hardware RNG in SMpro.
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef TRNG_LIB_H_
+#define TRNG_LIB_H_
+
+/**
+  Generates a random number by using Hardware RNG in SMpro.
+
+  @param[out] Buffer      Buffer to receive the random number.
+  @param[in]  BufferSize  Number of bytes in Buffer.
+
+  @retval EFI_SUCCESS           The random value was returned successfully.
+  @retval EFI_DEVICE_ERROR      A random value could not be retrieved
+                                due to a hardware or firmware error.
+  @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is zero.
+**/
+EFI_STATUS
+EFIAPI
+GenerateRandomNumbers (
+  OUT UINT8 *Buffer,
+  IN  UINTN BufferSize
+  );
+
+#endif /* TRNG_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h
new file mode 100644
index 000000000000..e348b71b5e58
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h
@@ -0,0 +1,79 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_LIB_H_
+#define MM_LIB_H_
+
+enum {
+  MM_SPINOR_FUNC_GET_INFO,
+  MM_SPINOR_FUNC_READ,
+  MM_SPINOR_FUNC_WRITE,
+  MM_SPINOR_FUNC_ERASE,
+  MM_SPINOR_FUNC_GET_NVRAM_INFO,
+  MM_SPINOR_FUNC_GET_NVRAM2_INFO,
+  MM_SPINOR_FUNC_GET_FAILSAFE_INFO
+};
+
+enum {
+  MM_NVPARAM_FUNC_READ = 1,
+  MM_NVPARAM_FUNC_WRITE,
+  MM_NVPARAM_FUNC_CLEAR,
+  MM_NVPARAM_FUNC_CLEAR_ALL
+};
+
+#define MM_SPINOR_RES_SUCCESS           0xAABBCC00
+#define MM_SPINOR_RES_FAIL              0xAABBCCFF
+
+#define MM_NVPARAM_RES_SUCCESS          0xAABBCC00
+#define MM_NVPARAM_RES_NOT_SET          0xAABBCC01
+#define MM_NVPARAM_RES_NO_PERM          0xAABBCC02
+#define MM_NVPARAM_RES_FAIL             0xAABBCCFF
+
+#define EFI_MM_MAX_PAYLOAD_U64_E  10
+#define EFI_MM_MAX_PAYLOAD_SIZE   (EFI_MM_MAX_PAYLOAD_U64_E * sizeof(UINT64))
+#define EFI_MM_MAX_TMP_BUF_SIZE   0x1000000
+
+typedef struct {
+  /* Allows for disambiguation of the message format */
+  EFI_GUID HeaderGuid;
+  /*
+   * Describes the size of Data (in bytes) and does not include the size
+   * of the header
+   */
+  UINTN MsgLength;
+} EFI_MM_COMM_HEADER_NOPAYLOAD;
+
+typedef struct {
+  UINT64 Data[EFI_MM_MAX_PAYLOAD_U64_E];
+} EFI_MM_COMM_PAYLOAD;
+
+typedef struct {
+  EFI_MM_COMM_HEADER_NOPAYLOAD EfiMmHdr;
+  EFI_MM_COMM_PAYLOAD          PayLoad;
+} EFI_MM_COMM_REQUEST;
+
+typedef struct {
+  UINT64 Status;
+  UINT64 DeviceBase;
+  UINT64 PageSize;
+  UINT64 SectorSize;
+  UINT64 DeviceSize;
+} EFI_MM_COMMUNICATE_SPINOR_RES;
+
+typedef struct {
+  UINT64 Status;
+  UINT64 NVBase;
+  UINT64 NVSize;
+} EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES;
+
+typedef struct {
+  UINT64 Status;
+  UINT64 Value;
+} EFI_MM_COMMUNICATE_NVPARAM_RES;
+
+#endif /* MM_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h b/Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h
new file mode 100644
index 000000000000..1891d055fd9e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h
@@ -0,0 +1,515 @@
+/** @file
+
+  The non-volatile parameter layout in SPI-NOR is shown below. There is
+  two copies. The master copy is changeable by the user. The Last Known
+  copy is handled by the fail safe future. It is a last know bootable copy.
+
+   ---------------------------
+   | Master Copy             | 16KB
+   | Pre-boot parameters     |
+   ---------------------------
+   | Master Copy             | 16KB
+   | Pre-boot parameters     |
+   | w/o failsafe support    |
+   ---------------------------
+   | Master Copy             |
+   | Manufactory &           | 32KB
+   | Users parameters        |
+   ---------------------------
+   | Last Known Copy         | 16KB
+   | Pre-boot parameters     |
+   ---------------------------
+   |                         | 16KB
+   ---------------------------
+   | Last Known Copy         |
+   | Manufactory &           | 32KB
+   | Users parameters        |
+   ---------------------------
+
+  As each non-volatile parameter requires 8 bytes, there is a total of 8K
+  parameters.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVPARAMDEF_H_
+#define NVPARAMDEF_H_
+
+typedef enum {
+  /*
+   * SoC validation pre-boot non-volatile setting
+   *
+   * These parameters will reset to default value on failsafe.
+   * They are not used in production life cycle.
+   */
+  NV_PREBOOT_PARAM_START                    = 0x000000,
+  NV_SI_PCP_VDMC                            = (1 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_FAILSAFE_RETRY                      = (2 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PPR_EN                          = (3 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RESERVED0                       = (4 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RESERVED1                       = (5 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_LOG_LEVEL                       = (6 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RESERVED2                       = (7 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RD_DBI_EN                       = (8 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WR_DBI_EN                       = (9 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RETRY_EN                        = (10 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_BANK_HASH_EN                    = (11 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RESERVED3                       = (12 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RCD_PARITY_EN                   = (13 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WRPATH_CLK_GATE_EN              = (14 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_IOCAL_MARGIN                    = (15 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTR_S_MARGIN                    = (16 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTR_L_MARGIN                    = (17 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTR_CS_MARGIN                   = (18 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTW_S_MARGIN                    = (19 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTW_L_MARGIN                    = (20 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTW_CS_MARGIN                   = (21 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTW_S_MARGIN                    = (22 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTW_L_MARGIN                    = (23 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RTW_CS_MARGIN                   = (24 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTR_S_MARGIN                    = (25 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTR_L_MARGIN                    = (26 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WTR_CS_MARGIN                   = (27 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PARITY_EN                       = (28 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_SLC_DISABLE                         = (29 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_SLC_SIZE                            = (30 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_SLC_SCRUB                           = (31 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_CCIX_DISABLE                        = (32 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_ESM_SPEED                           = (33 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_CAL_MODE                    = (34 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_RAS_TEST_EN                         = (35 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_EYE_SCREEN_TEST_EN              = (36 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_EYE_MASK_RD_MARGIN              = (37 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_EYE_MASK_WR_MARGIN              = (38 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RDODT_ON_MARGIN                 = (39 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RDODT_OFF_MARGIN                = (40 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WRODT_ON_MARGIN                 = (41 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WRODT_OFF_MARGIN                = (42 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_SLC_OCM_EN                          = (43 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_ESM_WIDTH                           = (44 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_TM2_DISABLE                         = (45 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_CPUPLL_FREQ_MHZ                     = (46 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_ERR_INJECT_MASK_SK0             = (47 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_ERR_INJECT_MASK_SK1             = (48 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_CXG_DISABLE_EARLY_COMPACK           = (49 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_CXG_ENABLE_SAME_ADDR_COMP_ORDER     = (50 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_TURNAROUND_CONTROL              = (51 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_HIT_TURNAROUND_CONTROL          = (52 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_QOS_CLASS_CONTROL               = (53 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_ESCALATION_CONTROL              = (54 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_QV_CONTROL_31_00                = (55 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_QV_CONTROL_63_32                = (56 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_CREDIT_CONTROL                  = (57 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WRITE_PRIORITY_CONTROL_31_00    = (58 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_WRITE_PRIORITY_CONTROL_63_32    = (59 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_QUEUE_THRESHOLD_CONTROL_31_00   = (60 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_QUEUE_THRESHOLD_CONTROL_63_32   = (61 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_ATF_FAILURE_FAILSAFE                = (62 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_UEFI_FAILURE_FAILSAFE               = (63 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_STRIPE_DECODE                   = (64 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_DEBUG_CTRL                      = (65 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_CXG_RA_DEVNR_ORD_WFC_DIS            = (66 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_DLL_TRACK_UPD_THRESHOLD     = (67 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_DLL_TRACK_UPD_THRESHOLD_AC  = (68 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_INIT_UPDATE_CONFIG          = (69 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_UPDATE_CONTROL              = (70 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_PROFILE_EN                          = (71 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_PCIE_PHY_SETTING                    = (72 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_CAL_THRESHOLD               = (73 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_PHY_CAL_INTERVAL_CNT            = (74 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_RESERVED                            = (75 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_S0_RHS_RCA_EN                       = (76 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_S1_RHS_RCA_EN                       = (77 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_2P_DPLL                             = (78 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_2P_ALI_CFG                          = (79 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_2P_ALI_CFG_LINK_RETRAIN             = (80 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_2P_ALI_CFG_CRC                      = (81 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RT_CONTROL_31_00                = (82 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_RT_CONTROL_63_32                = (83 * 8) + NV_PREBOOT_PARAM_START,
+  NV_SI_DDR_TIMEOUT_CONTROL                 = (84 * 8) + NV_PREBOOT_PARAM_START,
+  NV_PMPRO_REGION1_LOAD_START               = NV_SI_SLC_DISABLE,
+  NV_PMPRO_REGION1_LOAD_END                 = NV_SI_2P_ALI_CFG_CRC,
+  /* NOTE: Add before NV_PREBOOT_PARAM_MAX and increase its value */
+  NV_PREBOOT_PARAM_MAX                      = (84 * 8) + NV_PREBOOT_PARAM_START,
+
+  /*
+   * Manufactory non-volatile memory
+   *
+   * These parameters will reset to default value on failsafe.
+   */
+  NV_MANU_PARAM_START                       = 0x004000,
+  NV_SI_DDR_VMARGIN                         = (0 * 8) + NV_MANU_PARAM_START,
+  NV_PMPRO_REGION2_LOAD_START               = NV_SI_DDR_VMARGIN,
+  NV_SI_SOC_VMARGIN                         = (1 * 8) + NV_MANU_PARAM_START,
+  NV_SI_AVS_VMARGIN                         = (2 * 8) + NV_MANU_PARAM_START,
+  NV_SI_TPC_TM1_MARGIN                      = (3 * 8) + NV_MANU_PARAM_START,
+  NV_SI_TPC_TM2_MARGIN                      = (4 * 8) + NV_MANU_PARAM_START,
+  NV_SI_TPC_FREQ_THROTTLE                   = (5 * 8) + NV_MANU_PARAM_START,
+  NV_SI_T_LTLM_EN                           = (6 * 8) + NV_MANU_PARAM_START,
+  NV_SI_T_LTLM_THRSHLD                      = (7 * 8) + NV_MANU_PARAM_START,
+  NV_SI_T_GTLM_THRSHLD                      = (8 * 8) + NV_MANU_PARAM_START,
+  NV_SI_P_LM_EN                             = (9 * 8) + NV_MANU_PARAM_START,
+  NV_SI_P_LM_THRSHLD                        = (10 * 8) + NV_MANU_PARAM_START,
+  NV_SI_TPC_OVERTEMP_ISR_DISABLE            = (11 * 8) + NV_MANU_PARAM_START,
+  NV_SI_VPP_VMARGIN                         = (12 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PMPRO_FAILURE_FAILSAFE              = (13 * 8) + NV_MANU_PARAM_START,
+  NV_SI_FAILSAFE_DISABLE                    = (14 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLIMIT_APM_DS_PERCENTAGE            = (15 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLIMIT_APM_EP_MS                    = (16 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLIMIT_APM_PM1_PERCENTAGE_TDP       = (17 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CPU_LPI_FREQ_DISABLE                = (18 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CPU_LPI_FREQ_ENERGY_THRSHLD         = (19 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CCIX_OPT_CONFIG                     = (20 * 8) + NV_MANU_PARAM_START,
+  NV_SI_MESH_FREQ_MARGIN                    = (21 * 8) + NV_MANU_PARAM_START,
+  NV_SI_MESH_TURBO_EN                       = (22 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PWR_HEADROOM_WATT                   = (23 * 8) + NV_MANU_PARAM_START,
+  NV_SI_EXTRA_PCP_VOLT_MV                   = (24 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CPU_LPI_HYST_CNT                    = (25 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DVFS_VOLT_INC_STEP_MV               = (26 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DVFS_VOLT_DEC_STEP_MV               = (27 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLIMIT_APM_TEMP_THLD                = (28 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLIMIT_APM_EN                       = (29 * 8) + NV_MANU_PARAM_START,
+  NV_SI_VDM_EN                              = (30 * 8) + NV_MANU_PARAM_START,
+  NV_SI_VDM_VMARGIN_MV                      = (31 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_EN                              = (32 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_SOCKET                          = (33 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_MCU_MASK                        = (34 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_RANK_MASK                       = (35 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_SLICE_MASK                      = (36 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_BIT_MASK                        = (37 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_X_PARAM                         = (38 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_Y_PARAM                         = (39 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_X_LEFT                          = (40 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_X_RIGHT                         = (41 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_X_STEP                          = (42 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_Y_BOTTOM                        = (43 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_Y_TOP                           = (44 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_Y_STEP                          = (45 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_START_ADDR_LO                   = (46 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_START_ADDR_UP                   = (47 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_SIZE                            = (48 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_THREAD_CNT                      = (49 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_SCREEN                          = (50 * 8) + NV_MANU_PARAM_START,
+  NV_SI_PLT_RSVD                            = (51 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DVFS_VOLT_CHANGE_BY_STEP_EN         = (52 * 8) + NV_MANU_PARAM_START,
+  NS_SI_DVFS_TCAL_F_LIMIT                   = (53 * 8) + NV_MANU_PARAM_START,
+  NS_SI_DVFS_TCAL_T_LIMIT                   = (54 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CCIX_DIAG_CTRL1                     = (55 * 8) + NV_MANU_PARAM_START,
+  NV_SI_CCIX_DIAG_CTRL2                     = (56 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_EN                         = (57 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_DIMM_LOW_TEMP_THRESHOLD    = (58 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_DIMM_HIGH_TEMP_THRESHOLD   = (59 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_MCU_LOW_TEMP_THRESHOLD     = (60 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_MCU_HIGH_TEMP_THRESHOLD    = (61 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_LOW_TEMP_VOLT_OFF_MV       = (62 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_PERIOD_SEC                 = (63 * 8) + NV_MANU_PARAM_START,
+  NV_SI_DDR_TCAL_SOC_VOLT_CAP_MV            = (64 * 8) + NV_MANU_PARAM_START,
+  NV_SI_ALTRAMAX_ICCMAX_EN                  = (65 * 8) + NV_MANU_PARAM_START,
+  NV_SI_MESH_TURBO_ACTIVITY_THRESHOLD       = (66 * 8) + NV_MANU_PARAM_START,
+  NV_PMPRO_REGION2_LOAD_END                 = NV_SI_MESH_TURBO_ACTIVITY_THRESHOLD,
+  /* NOTE: Add before NV_MANU_PARAM_MAX and increase its value */
+  NV_MANU_PARAM_MAX                         = (66 * 8) + NV_MANU_PARAM_START,
+
+  /*
+   * User non-volatile memory
+   *
+   * These parameters will reset to default value on failsafe.
+   */
+  NV_USER_PARAM_START                       = 0x008000,
+  NV_SI_S0_PCP_ACTIVECPM_0_31               = (0 * 8) + NV_USER_PARAM_START,
+  NV_SI_S0_PCP_ACTIVECPM_32_63              = (1 * 8) + NV_USER_PARAM_START,
+  NV_SI_S1_PCP_ACTIVECPM_0_31               = (2 * 8) + NV_USER_PARAM_START,
+  NV_SI_S1_PCP_ACTIVECPM_32_63              = (3 * 8) + NV_USER_PARAM_START,
+  NV_SI_WDT_BIOS_EXP_MINS                   = (4 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_CE_RAS_THRESHOLD                = (5 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_CE_RAS_INTERVAL                 = (6 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_SPEED                           = (7 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_SCRUB_EN                        = (8 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_ECC_MODE                        = (9 * 8) + NV_USER_PARAM_START,
+  NV_SI_S0_RCA_PCI_DEVMAP                   = (10 * 8) + NV_USER_PARAM_START,
+  NV_SI_S0_RCB_PCI_DEVMAP                   = (11 * 8) + NV_USER_PARAM_START,
+  NV_SI_S1_RCA_PCI_DEVMAP                   = (12 * 8) + NV_USER_PARAM_START,
+  NV_SI_S1_RCB_PCI_DEVMAP                   = (13 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_ERRCTRL                         = (14 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_REFRESH_GRANULARITY             = (15 * 8) + NV_USER_PARAM_START,
+  NV_SI_SUBNUMA_MODE                        = (16 * 8) + NV_USER_PARAM_START,
+  NV_SI_ERRATUM_1542419_WA                  = (17 * 8) + NV_USER_PARAM_START,
+  NV_SI_NEAR_ATOMIC_DISABLE                 = (18 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_SLAVE_32BIT_MEM_EN              = (19 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPUECTLR_EL1_0_31                   = (20 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPUECTLR_EL1_32_63                  = (21 * 8) + NV_USER_PARAM_START,
+  NV_SI_HARDWARE_EINJ                       = (22 * 8) + NV_USER_PARAM_START,
+  NV_SI_2P_CE_RAS_THRESHOLD                 = (23 * 8) + NV_USER_PARAM_START,
+  NV_SI_2P_CE_RAS_INTERVAL                  = (24 * 8) + NV_USER_PARAM_START,
+  NV_SI_RAS_BERT_ENABLED                    = (25 * 8) + NV_USER_PARAM_START,
+  NV_SI_HNF_AUX_CTL_0_31                    = (26 * 8) + NV_USER_PARAM_START,
+  NV_SI_HNF_AUX_CTL_32_63                   = (27 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPM_CE_RAS_THRESHOLD                = (28 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPM_CE_RAS_INTERVAL                 = (29 * 8) + NV_USER_PARAM_START,
+  NV_SI_HNF_AUX_CTL_0_31_WR_EN_MASK         = (30 * 8) + NV_USER_PARAM_START,
+  NV_SI_HNF_AUX_CTL_32_63_WR_EN_MASK        = (31 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_WR_BACK_EN                      = (32 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPUECTLR_EL1_0_31_WR_EN_MASK        = (33 * 8) + NV_USER_PARAM_START,
+  NV_SI_CPUECTLR_EL1_32_63_WR_EN_MASK       = (34 * 8) + NV_USER_PARAM_START,
+  NV_SI_LINK_ERR_THRESHOLD                  = (35 * 8) + NV_USER_PARAM_START,
+  NV_SI_SEC_WDT_BIOS_EXP_MINS               = (36 * 8) + NV_USER_PARAM_START,
+  NV_SI_NVDIMM_MODE                         = (37 * 8) + NV_USER_PARAM_START,
+  NV_SI_RAS_SDEI_ENABLED                    = (38 * 8) + NV_USER_PARAM_START,
+  NV_SI_NVDIMM_PROV_MASK_S0                 = (39 * 8) + NV_USER_PARAM_START,
+  NV_SI_NVDIMM_PROV_MASK_S1                 = (40 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_ZQCS_EN                         = (41 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_CRC_MODE                        = (42 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXG_RA_AUX_CTL_0_31                 = (43 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXG_RA_AUX_CTL_32_63                = (44 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXG_RA_AUX_CTL_0_31_WR_EN_MASK      = (45 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXG_RA_AUX_CTL_32_63_WR_EN_MASK     = (46 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXLA_AUX_CTL_0_31                   = (47 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXLA_AUX_CTL_32_63                  = (48 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXLA_AUX_CTL_0_31_WR_EN_MASK        = (49 * 8) + NV_USER_PARAM_START,
+  NV_SI_CXLA_AUX_CTL_32_63_WR_EN_MASK       = (50 * 8) + NV_USER_PARAM_START,
+  NV_SI_DDR_LOW_POWER_CFG                   = (51 * 8) + NV_USER_PARAM_START,
+  NV_SI_ALERT_DIMM_SHUTDOWN_EN              = (52 * 8) + NV_USER_PARAM_START,
+  NV_SI_DFS_EN                              = (53 * 8) + NV_USER_PARAM_START,
+  NV_SI_RAS_PCIE_AER_FW_FIRST               = (54 * 8) + NV_USER_PARAM_START,
+  NV_SI_RAS_DRAM_EINJ_NOTRIGGER             = (55 * 8) + NV_USER_PARAM_START,
+  NV_SI_RAS_AEST_PROC_EN                    = (56 * 8) + NV_USER_PARAM_START,
+  NV_SI_MESH_S0_CXG_RC_STRONG_ORDERING_EN   = (57 * 8) + NV_USER_PARAM_START,
+  NV_SI_MESH_S1_CXG_RC_STRONG_ORDERING_EN   = (58 * 8) + NV_USER_PARAM_START,
+  NV_SI_2P_RESERVED0                        = (59 * 8) + NV_USER_PARAM_START,
+  NV_SI_2P_RESERVED1                        = (60 * 8) + NV_USER_PARAM_START,
+  NV_SI_2P_RESERVED2                        = (61 * 8) + NV_USER_PARAM_START,
+  NV_SI_HCR_EL2_CTL_LOW                     = (62 * 8) + NV_USER_PARAM_START,
+  NV_SI_HCR_EL2_CTL_HIGH                    = (63 * 8) + NV_USER_PARAM_START,
+  /* NOTE: Add before NV_USER_PARAM_MAX and increase its value */
+  NV_USER_PARAM_MAX                         = (63 * 8) + NV_USER_PARAM_START,
+  NV_PMPRO_REGION3_LOAD_START               = NV_USER_PARAM_START,
+  NV_PMPRO_REGION3_LOAD_END                 = NV_USER_PARAM_MAX,
+
+  /*
+   * Non-volatile board read-only setting
+   *
+   * These parameters do not support failsafe and will always read
+   * from its location. Please note that the physical base address
+   * location for board setting is not the same as above region. This
+   * allows packaging these board setting along with the firmware
+   * image itself. See SPI-NOR flash layout design for more info.
+   *
+   * Please note that script will parse these and generate
+   * board setting. The keyword "Default: " is used to provide
+   * the default value.
+   */
+  NV_BOARD_PARAM_START                      = 0x00C000,
+  NV_SI_RO_BOARD_VENDOR                     = (0 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0000CD3A - Follow BMC FRU format */
+  NV_PMPRO_REGION4_LOAD_START               = NV_SI_RO_BOARD_VENDOR,
+  NV_SI_RO_BOARD_TYPE                       = (1 * 8) + NV_BOARD_PARAM_START,  /* Default: 0x00000000 - Follow BMC FRU format */
+  NV_SI_RO_BOARD_REV                        = (2 * 8) + NV_BOARD_PARAM_START,  /* Default: 0x00000000 Follow BMC FRU format */
+  NV_SI_RO_BOARD_CFG                        = (3 * 8) + NV_BOARD_PARAM_START,  /* Default: 0x00000000 Follow BMC FRU format */
+  NV_SI_RO_BOARD_S0_DIMM_AVAIL              = (4 * 8) + NV_BOARD_PARAM_START,  /* Default: 0x0000FFFF */
+  NV_SI_RO_BOARD_S1_DIMM_AVAIL              = (5 * 8) + NV_BOARD_PARAM_START,  /* Default: 0x0000FFFF */
+  NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ           = (6 * 8) + NV_BOARD_PARAM_START,  /* Default: 33000 */
+  NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ           = (7 * 8) + NV_BOARD_PARAM_START,  /* Default: 33000 */
+  NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ           = (8 * 8) + NV_BOARD_PARAM_START,  /* Default: 10000 */
+  NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ           = (9 * 8) + NV_BOARD_PARAM_START,  /* Default: 10000 */
+  NV_SI_RO_BOARD_TPM_LOC                    = (10 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_I2C0_FREQ_KHZ              = (11 * 8) + NV_BOARD_PARAM_START, /* Default: 400 */
+  NV_SI_RO_BOARD_I2C1_FREQ_KHZ              = (12 * 8) + NV_BOARD_PARAM_START, /* Default: 400 */
+  NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ           = (13 * 8) + NV_BOARD_PARAM_START, /* Default: 400 */
+  NV_SI_RO_BOARD_I2C3_FREQ_KHZ              = (14 * 8) + NV_BOARD_PARAM_START, /* Default: 400 */
+  NV_SI_RO_BOARD_I2C9_FREQ_KHZ              = (15 * 8) + NV_BOARD_PARAM_START, /* Default: 400 */
+  NV_SI_RO_BOARD_2P_CFG                     = (16 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFFFFFF01 */
+  NV_SI_RO_BOARD_S0_RCA0_CFG                = (17 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA1_CFG                = (18 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA2_CFG                = (19 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000004 */
+  NV_SI_RO_BOARD_S0_RCA3_CFG                = (20 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000004 */
+  NV_SI_RO_BOARD_S0_RCB0_LO_CFG             = (21 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S0_RCB0_HI_CFG             = (22 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S0_RCB1_LO_CFG             = (23 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S0_RCB1_HI_CFG             = (24 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S0_RCB2_LO_CFG             = (25 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S0_RCB2_HI_CFG             = (26 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_S0_RCB3_LO_CFG             = (27 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_S0_RCB3_HI_CFG             = (28 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCA0_CFG                = (29 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA1_CFG                = (30 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA2_CFG                = (31 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S1_RCA3_CFG                = (32 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00030003 */
+  NV_SI_RO_BOARD_S1_RCB0_LO_CFG             = (33 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_S1_RCB0_HI_CFG             = (34 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCB1_LO_CFG             = (35 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCB1_HI_CFG             = (36 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_S1_RCB2_LO_CFG             = (37 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCB2_HI_CFG             = (38 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCB3_LO_CFG             = (39 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_S1_RCB3_HI_CFG             = (40 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020002 */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_P0            = (41 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000001 */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_P1            = (42 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000002 */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_P2            = (43 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_P3            = (44 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000004 */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_M1            = (45 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFFFFFFFF */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_M2            = (46 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFFFFFFFE */
+  NV_SI_RO_BOARD_T_LTLM_DELTA_M3            = (47 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFFFFFFFD */
+  NV_SI_RO_BOARD_P_LM_PID_P                 = (48 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_P_LM_PID_I                 = (49 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD         = (50 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD         = (51 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_P_LM_PID_D                 = (52 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST      = (53 * 8) + NV_BOARD_PARAM_START,
+  /*
+   * NV_SI_RO_BOARD_TPM_ALG_ID: 0=Default to SHA256, 1=SHA1, 2=SHA256
+   * Any other value will lead to default digest.
+   */
+  NV_SI_RO_BOARD_TPM_ALG_ID                         = (54 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000002 */
+  NV_SI_RO_BOARD_DDR_SPEED_GRADE                    = (55 * 8) + NV_BOARD_PARAM_START, /* Default: 3200 */
+  NV_SI_RO_BOARD_DDR_S0_RTT_WR                      = (56 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020000 */
+  NV_SI_RO_BOARD_DDR_S1_RTT_WR                      = (57 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00020000 */
+  NV_SI_RO_BOARD_DDR_S0_RTT_NOM                     = (58 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFF060177 */
+  NV_SI_RO_BOARD_DDR_S1_RTT_NOM                     = (59 * 8) + NV_BOARD_PARAM_START, /* Default: 0xFF060177 */
+  NV_SI_RO_BOARD_DDR_S0_RTT_PARK                    = (60 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00060070 */
+  NV_SI_RO_BOARD_DDR_S1_RTT_PARK                    = (61 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00060070 */
+  NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC            = (62 * 8) + NV_BOARD_PARAM_START, /* Default: 0x000000 */
+  NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC            = (63 * 8) + NV_BOARD_PARAM_START, /* Default: 0x000000 */
+  NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC            = (64 * 8) + NV_BOARD_PARAM_START, /* Default: 0x000000 */
+  NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC            = (65 * 8) + NV_BOARD_PARAM_START, /* Default: 0x000000 */
+  NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC            = (66 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0C0CCC */
+  NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC            = (67 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0C0CCC */
+  NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC            = (68 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC            = (69 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC            = (70 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC            = (71 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC            = (72 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC            = (73 * 8) + NV_BOARD_PARAM_START, /* Default: 0x030333 */
+  NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC            = (74 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0EDEED */
+  NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC            = (75 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0DEDDE */
+  NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC            = (76 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0B7BB7 */
+  NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC            = (77 * 8) + NV_BOARD_PARAM_START, /* Default: 0x07B77B */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC          = (78 * 8) + NV_BOARD_PARAM_START, /* Default: 0x5 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC           = (79 * 8) + NV_BOARD_PARAM_START, /* Default: 0x90DD90 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC         = (80 * 8) + NV_BOARD_PARAM_START, /* Default: 0x5 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC          = (81 * 8) + NV_BOARD_PARAM_START, /* Default: 0x90DD90 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC          = (82 * 8) + NV_BOARD_PARAM_START, /* Default: 0x5 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC           = (83 * 8) + NV_BOARD_PARAM_START, /* Default: 0x90DD90 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC         = (84 * 8) + NV_BOARD_PARAM_START, /* Default: 0x5 */
+  NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC          = (85 * 8) + NV_BOARD_PARAM_START, /* Default: 0x90DD90 */
+  NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC      = (86 * 8) + NV_BOARD_PARAM_START, /* Default: 0x24 */
+  NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC     = (87 * 8) + NV_BOARD_PARAM_START, /* Default: 0x1A */
+  NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC      = (88 * 8) + NV_BOARD_PARAM_START, /* Default: 0x50 */
+  NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC     = (89 * 8) + NV_BOARD_PARAM_START, /* Default: 0x20 */
+  NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT           = (90 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02800280 */
+  NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT           = (91 * 8) + NV_BOARD_PARAM_START, /* Default: 0x90909090 */
+  NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT            = (92 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT              = (93 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00C000C0 */
+  NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ               = (94 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ               = (95 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ                   = (96 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ                  = (97 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE              = (98 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02010201 */
+  NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE                  = (99 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO                = (100 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL               = (101 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS           = (102 * 8) + NV_BOARD_PARAM_START, /* Default: 0x01050106 */
+  NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD                = (103 * 8) + NV_BOARD_PARAM_START, /* Default: 0x554 */
+  NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE           = (104 * 8) + NV_BOARD_PARAM_START, /* Default: 0x0 */
+  NV_SI_RO_BOARD_S0_PCIE_CLK_CFG                    = (105 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA4_CFG                        = (106 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S0_RCA5_CFG                        = (107 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S0_RCA6_CFG                        = (108 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S0_RCA7_CFG                        = (109 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020003 */
+  NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET              = (110 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET              = (111 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET              = (112 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET              = (113 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET             = (114 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET             = (115 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET             = (116 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET             = (117 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET             = (118 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET             = (119 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET             = (120 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET             = (121 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET              = (122 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET              = (123 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET              = (124 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET              = (125 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET              = (126 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET              = (127 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET              = (128 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET              = (129 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET             = (130 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET             = (131 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET             = (132 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET             = (133 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET             = (134 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET             = (135 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET             = (136 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET             = (137 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET              = (138 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET              = (139 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET              = (140 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET              = (141 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_PCIE_CLK_CFG                    = (142 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA4_CFG                        = (143 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S1_RCA5_CFG                        = (144 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S1_RCA6_CFG                        = (145 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020202 */
+  NV_SI_RO_BOARD_S1_RCA7_CFG                        = (146 * 8) + NV_BOARD_PARAM_START, /* Default: 0x02020003 */
+  NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET              = (147 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET              = (148 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET             = (149 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET             = (150 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET             = (151 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET             = (152 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET             = (153 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET             = (154 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET             = (155 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET             = (156 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET              = (157 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET              = (158 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET              = (159 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET              = (160 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET              = (161 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET              = (162 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET             = (163 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET             = (164 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET             = (165 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET             = (166 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET             = (167 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET             = (168 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET             = (169 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET             = (170 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET              = (171 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET              = (172 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET              = (173 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET              = (174 * 8) + NV_BOARD_PARAM_START, /* Default: 0x57575757 */
+  NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD               = (175 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000003 */
+  NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL                = (176 * 8) + NV_BOARD_PARAM_START, /* Default: 0x000001A4 */
+  NV_SI_RO_BOARD_SX_PHY_CFG_SETTING                 = (177 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_DDR_PHY_DC_CLK                     = (178 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00018000 */
+  NV_SI_RO_BOARD_DDR_PHY_DC_DATA                    = (179 * 8) + NV_BOARD_PARAM_START, /* Default: 0x80018000 */
+  NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET             = (180 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET             = (181 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET             = (182 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET             = (183 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET             = (184 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET             = (185 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET             = (186 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET             = (187 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD      = (188 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00550055 */
+  NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US               = (189 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000064 */
+  NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV         = (190 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000005 */
+  NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN             = (191 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000001 */
+  NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME           = (192 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000002 */
+  NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US        = (193 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000005 */
+  NV_SI_RO_BOARD_PCIE_AER_FW_FIRST                  = (194 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS                = (195 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_TPM_DISABLE                        = (196 * 8) + NV_BOARD_PARAM_START,
+  NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN  = (197 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN  = (198 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN                = (199 * 8) + NV_BOARD_PARAM_START, /* Default: 0x00000000 */
+  NV_PMPRO_REGION4_LOAD_END                         = NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN,
+  /* NOTE: Add before NV_BOARD_PARAM_MAX and increase its value */
+  NV_BOARD_PARAM_MAX                                = (199 * 8) + NV_BOARD_PARAM_START,
+} NVPARAM;
+
+#endif /* NVPARAMDEF_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h b/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
new file mode 100644
index 000000000000..9b0b2e2f50d5
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
@@ -0,0 +1,146 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_AC01_H_
+#define PLATFORM_AC01_H_
+
+/* Number of supported sockets in the platform */
+#define PLATFORM_CPU_MAX_SOCKET             2
+
+/* Maximum number of CPMs in the chip. */
+#define PLATFORM_CPU_MAX_CPM                (FixedPcdGet32 (PcdClusterCount))
+
+/* Number of cores per CPM. */
+#define PLATFORM_CPU_NUM_CORES_PER_CPM      (FixedPcdGet32 (PcdCoreCount) / PLATFORM_CPU_MAX_CPM)
+
+/* Socket bit offset of core UID. */
+#define PLATFORM_SOCKET_UID_BIT_OFFSET      16
+
+/* CPM bit offset of core UID. */
+#define PLATFORM_CPM_UID_BIT_OFFSET         8
+
+/* Maximum number of cores supported. */
+#define PLATFORM_CPU_MAX_NUM_CORES  (PLATFORM_CPU_MAX_SOCKET * PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM)
+
+/* Maximum number of memory region */
+#define PLATFORM_DRAM_INFO_MAX_REGION  16
+
+/* Maximum number of DDR slots supported */
+#define PLATFORM_DIMM_INFO_MAX_SLOT    32
+
+/* Maximum number of memory supported. */
+#define PLATFORM_MAX_MEMORY_REGION     4
+
+/* The Array of Soc Gpio Base Address */
+#define GPIO_DWAPB_BASE_ADDR      0x1000026f0000,0x1000026e0000,0x1000027b0000,0x1000026d0000,0x5000026f0000,0x5000026e0000,0x5000027b0000,0x5000026d0000
+
+/* The Array of Soc Gpi Base Address */
+#define GPI_DWAPB_BASE_ADDR      0x1000026d0000,0x5000026d0000
+
+/* Number of Pins Per Each Contoller */
+#define GPIO_DWAPB_PINS_PER_CONTROLLER    8
+
+/* Number of Pins Each Socket */
+#define GPIO_DWAPB_PINS_PER_SOCKET        32
+
+/* The maximum number of I2C bus */
+#define MAX_PLATFORM_I2C_BUS_NUM          2
+
+/* The base address of DW I2C */
+#define PLATFORM_I2C_REGISTER_BASE        0x1000026B0000ULL, 0x100002750000ULL
+
+/* Offset of failsafe testing feature */
+#define NV_UEFI_FAILURE_FAILSAFE_OFFSET   0x1F8
+
+/* Maximum number of memory controller supports NVDIMM-N per socket */
+#define PLATFORM_NVDIMM_MCU_MAX_PER_SK    2
+
+/* Maximum number of NVDIMM-N per memory controller */
+#define PLATFORM_NVDIMM_NUM_MAX_PER_MCU   1
+
+/* Maximum number of NVDIMM region per socket */
+#define PLATFORM_NVDIMM_REGION_MAX_PER_SK 2
+
+/* Socket 0 base address of NVDIMM non-hashed region 0 */
+#define PLATFORM_NVDIMM_SK0_NHASHED_REGION0     0x0B0000000000ULL
+
+/* Socket 0 base address of NVDIMM non-hashed region 1 */
+#define PLATFORM_NVDIMM_SK0_NHASHED_REGION1     0x0F0000000000ULL
+
+/* Socket 1 base address of NVDIMM non-hashed region 0 */
+#define PLATFORM_NVDIMM_SK1_NHASHED_REGION0     0x430000000000ULL
+
+/* Socket 1 base address of NVDIMM non-hashed region 1 */
+#define PLATFORM_NVDIMM_SK1_NHASHED_REGION1     0x470000000000ULL
+
+/* DIMM ID of NVDIMM-N device 1 */
+#define PLATFORM_NVDIMM_NVD1_DIMM_ID            6
+
+/* DIMM ID of NVDIMM-N device 2 */
+#define PLATFORM_NVDIMM_NVD2_DIMM_ID            14
+
+/* DIMM ID of NVDIMM-N device 3 */
+#define PLATFORM_NVDIMM_NVD3_DIMM_ID            22
+
+/* DIMM ID of NVDIMM-N device 4 */
+#define PLATFORM_NVDIMM_NVD4_DIMM_ID            30
+
+/* NFIT device handle of NVDIMM-N device 1 */
+#define PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE      0x0330
+
+/* NFIT device handle of NVDIMM-N device 2 */
+#define PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE      0x0770
+
+/* NFIT device handle of NVDIMM-N device 3 */
+#define PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE      0x1330
+
+/* NFIT device handle of NVDIMM-N device 4 */
+#define PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE      0x1770
+
+/* Interleave ways of non-hashed NVDIMM-N */
+#define PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS 1
+
+/* Interleave ways of hashed NVDIMM-N */
+#define PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS  2
+
+/* Region offset of hashed NVDIMM-N */
+#define PLATFORM_NVDIMM_HASHED_REGION_OFFSET    512
+
+/* The base address of master socket GIC redistributor registers */
+#define GICR_MASTER_BASE_REG    0x100100140000
+
+/* The base address of GIC distributor registers */
+#define GICD_BASE_REG           0x100100000000
+
+/* The base address of slave socket GIC redistributor registers */
+#define GICR_SLAVE_BASE_REG     0x500100140000
+
+/* The base address of slave socket GIC distributor registers */
+#define GICD_SLAVE_BASE_REG     0x500100000000
+
+/* Socket 0 first RC */
+#define SOCKET0_FIRST_RC        2
+
+/* Socket 0 last RC */
+#define SOCKET0_LAST_RC         7
+
+/* Socket 1 first RC */
+#define SOCKET1_FIRST_RC        10
+
+/* Socket 1 last RC */
+#define SOCKET1_LAST_RC         15
+
+//
+// SMpro EFUSE Shadow register
+//
+#define SMPRO_EFUSE_SHADOW0         (FixedPcdGet64 (PcdSmproEfuseShadow0))
+
+#define CFG2P_OFFSET                0x200
+#define SLAVE_PRESENT_N             BIT1 // Slave socket present
+
+#endif /* PLATFORM_AC01_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h b/Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h
new file mode 100644
index 000000000000..f8abcb92a17c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h
@@ -0,0 +1,182 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_INFO_HOB_H_
+#define PLATFORM_INFO_HOB_H_
+
+#include <IndustryStandard/Tpm20.h>
+#include <Platform/Ac01.h>
+
+/* DIMM type */
+enum {
+  UDIMM,
+  RDIMM,
+  SODIMM,
+  RSODIMM,
+  LRDIMM,
+  NVRDIMM
+};
+
+/* DIMM status */
+enum {
+  DIMM_NOT_INSTALLED = 0,
+  DIMM_INSTALLED_OPERATIONAL,    /* installed and operational     */
+  DIMM_INSTALLED_NONOPERATIONAL, /* installed and non-operational */
+  DIMM_INSTALLED_FAILED          /* installed and failed          */
+};
+
+typedef struct {
+  UINT32 NumRegion;
+  UINT64 TotalSize;
+  UINT64 Base[PLATFORM_DRAM_INFO_MAX_REGION];
+  UINT64 Size[PLATFORM_DRAM_INFO_MAX_REGION];
+  UINT64 Node[PLATFORM_DRAM_INFO_MAX_REGION];
+  UINT64 Socket[PLATFORM_DRAM_INFO_MAX_REGION];
+  UINT32 MaxSpeed;
+  UINT32 McuMask[PLATFORM_CPU_MAX_SOCKET];
+  UINT32 NvdRegion[PLATFORM_DRAM_INFO_MAX_REGION];
+  UINT32 NvdimmMode[PLATFORM_CPU_MAX_SOCKET];
+} PLATFORM_DRAM_INFO;
+
+typedef struct {
+  CHAR8  PartNumber[32];
+  UINT64 DimmSize;
+  UINT16 DimmMfcId;
+  UINT16 Reserved;
+  UINT8  DimmNrRank;
+  UINT8  DimmType;
+  UINT8  DimmStatus;
+  UINT8  DimmDevType;
+} PLATFORM_DIMM_INFO;
+
+typedef struct {
+  UINT8 Data[512];
+} PLATFORM_DIMM_SPD_DATA;
+
+typedef struct {
+  PLATFORM_DIMM_INFO     Info;
+  PLATFORM_DIMM_SPD_DATA SpdData;
+  UINT32                 NodeId;
+} PLATFORM_DIMM;
+
+typedef struct {
+  UINT32         BoardDimmSlots;
+  PLATFORM_DIMM  Dimm[PLATFORM_DIMM_INFO_MAX_SLOT];
+} PLATFORM_DIMM_LIST;
+
+typedef struct {
+  UINT32 EnableMask[4];
+} PLATFORM_CLUSTER_EN;
+
+//
+// Algorithm ID defined in pre-UEFI firmware
+//
+typedef enum {
+  PLATFORM_ALGORITHM_SHA1 = 1,
+  PLATFORM_ALGORITHM_SHA256
+} PLATFORM_ALGORITHM_ID;
+
+//
+// Platform digest data definition
+//
+typedef union {
+  unsigned char Sha1[SHA1_DIGEST_SIZE];
+  unsigned char Sha256[SHA256_DIGEST_SIZE];
+} PLATFORM_TPM_DIGEST;
+
+#define MAX_VIRTUAL_PCR_INDEX   0x0002
+
+#pragma pack(1)
+typedef struct {
+  PLATFORM_ALGORITHM_ID AlgorithmId;
+  struct {
+    PLATFORM_TPM_DIGEST Hash;
+  } VPcr[MAX_VIRTUAL_PCR_INDEX]; // vPCR 0 or 1
+} PLATFORM_VPCR_HASH_INFO;
+
+typedef struct {
+  UINT8  InterfaceType;              // If I/F is CRB then CRB parameters are expected
+  UINT64 InterfaceParametersAddress; // Physical address of interface, by Value */
+  UINT64 InterfaceParametersLength;
+  UINT32 SupportedAlgorithmsBitMask;
+  UINT64 EventLogAddress;
+  UINT64 EventLogLength;
+  UINT8  Reserved[3];
+} PLATFORM_TPM2_CONFIG_DATA;
+
+typedef struct {
+  UINT32 CurrentRequest;
+  UINT32 LastRequest;
+  UINT32 LastRequestStatus;
+} PLATFORM_TPM2_PPI_REQUEST;
+
+typedef struct {
+  UINT64                      AddressOfControlArea;
+  UINT64                      ControlAreaLength;
+  UINT8                       InterruptMode;
+  UINT8                       Reserved[3];
+  UINT32                      InterruptNumber;         // Should have a value of zero polling
+  UINT32                      SmcFunctionId;           // SMC Function ID
+  UINT64                      PpiRequestNotifyAddress; // Doorbell/Interrupt Address
+  PLATFORM_TPM2_PPI_REQUEST   *PpiRequest;             // PPI Request
+} PLATFORM_TPM2_CRB_INTERFACE_PARAMETERS;
+
+typedef struct {
+  PLATFORM_TPM2_CONFIG_DATA              Tpm2ConfigData;
+  PLATFORM_TPM2_CRB_INTERFACE_PARAMETERS Tpm2CrbInterfaceParams;
+  PLATFORM_VPCR_HASH_INFO                Tpm2VPcrHashInfo;
+} PLATFORM_TPM2_INFO;
+#pragma pack()
+
+typedef struct {
+  UINT8               MajorNumber;
+  UINT8               MinorNumber;
+  UINT64              PcpClk;
+  UINT64              CpuClk;
+  UINT64              SocClk;
+  UINT64              AhbClk;
+  UINT64              SysClk;
+  UINT8               CpuInfo[128];
+  UINT8               CpuVer[32];
+  UINT8               SmPmProVer[32];
+  UINT8               SmPmProBuild[32];
+  PLATFORM_DRAM_INFO  DramInfo;
+  PLATFORM_DIMM_LIST  DimmList;
+  PLATFORM_CLUSTER_EN ClusterEn[2];
+  UINT32              FailSafeStatus;
+  UINT32              RcDisableMask[2];
+  UINT8               ResetStatus;
+  UINT16              CoreVoltage[2];
+  UINT16              SocVoltage[2];
+  UINT16              Dimm1Voltage[2];
+  UINT16              Dimm2Voltage[2];
+
+  /* Chip information */
+  UINT32 ScuProductId[2];
+  UINT8  MaxNumOfCore[2];
+  UINT8  Warranty[2];
+  UINT8  SubNumaMode[2];
+  UINT8  AvsEnable[2];
+  UINT32 AvsVoltageMV[2];
+  UINT8  TurboCapability[2];
+  UINT32 TurboFrequency[2];
+
+  UINT8  SkuMaxTurbo[2];
+  UINT8  SkuMaxCore[2];
+  UINT32 AHBCId[2];
+
+  /* TPM2 Info */
+  PLATFORM_TPM2_INFO Tpm2Info;
+
+  /* 2P link info for RCA0/RCA1 */
+  UINT8 Link2PSpeed[2];
+  UINT8 Link2PWidth[2];
+
+} PLATFORM_INFO_HOB;
+
+#endif /* PLATFORM_INFO_HOB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c
new file mode 100644
index 000000000000..04def9fa2e42
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c
@@ -0,0 +1,52 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <PlatformInfoHob.h>
+#include <Uefi/UefiBaseType.h>
+
+VOID
+BuildPlatformInformationHob (
+  VOID
+  )
+{
+  VOID *Hob;
+
+  /* The ATF HOB handoff base is at PcdSystemMemoryBase */
+  Hob = GetNextGuidHob (
+          &gPlatformHobGuid,
+          (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase)
+          );
+  if (Hob != NULL) {
+    BuildGuidDataHob (
+      &gPlatformHobGuid,
+      GET_GUID_HOB_DATA (Hob),
+      GET_GUID_HOB_DATA_SIZE (Hob)
+      );
+  }
+}
+
+EFI_STATUS
+EFIAPI
+InitializeATFHobPeim (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  BuildPlatformInformationHob ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c
new file mode 100644
index 000000000000..4098b4664bf8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c
@@ -0,0 +1,151 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+/*
+ * The protocols, PPI and GUID defintions for this module
+ */
+#include <Guid/MemoryTypeInformation.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <PlatformInfoHob.h>
+#include <Ppi/BootInRecoveryMode.h>
+#include <Ppi/MasterBootMode.h>
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+  IN UINT64               UefiMemorySize
+  );
+
+VOID
+BuildMemoryTypeInformationHob (
+  VOID
+  )
+{
+  EFI_MEMORY_TYPE_INFORMATION Info[10];
+
+  Info[0].Type          = EfiACPIReclaimMemory;
+  Info[0].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIReclaimMemory);
+  Info[1].Type          = EfiACPIMemoryNVS;
+  Info[1].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiACPIMemoryNVS);
+  Info[2].Type          = EfiReservedMemoryType;
+  Info[2].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiReservedMemoryType);
+  Info[3].Type          = EfiRuntimeServicesData;
+  Info[3].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesData);
+  Info[4].Type          = EfiRuntimeServicesCode;
+  Info[4].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiRuntimeServicesCode);
+  Info[5].Type          = EfiBootServicesCode;
+  Info[5].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesCode);
+  Info[6].Type          = EfiBootServicesData;
+  Info[6].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiBootServicesData);
+  Info[7].Type          = EfiLoaderCode;
+  Info[7].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderCode);
+  Info[8].Type          = EfiLoaderData;
+  Info[8].NumberOfPages = PcdGet32 (PcdMemoryTypeEfiLoaderData);
+
+  /* Terminator for the list */
+  Info[9].Type          = EfiMaxMemoryType;
+  Info[9].NumberOfPages = 0;
+
+  BuildGuidDataHob (&gEfiMemoryTypeInformationGuid, &Info, sizeof (Info));
+}
+
+EFI_STATUS
+EFIAPI
+InitializeMemory (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_STATUS         Status;
+  UINTN              SystemMemoryBase;
+  UINTN              SystemMemoryTop;
+  UINTN              FdBase;
+  UINTN              FdTop;
+  UINTN              UefiMemoryBase;
+  UINTN              Index;
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  DEBUG ((DEBUG_INFO, "Memory Init PEIM Loaded\n"));
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  /* Find system memory top of the first node */
+  SystemMemoryTop = 0;
+  for (Index = 0; Index < PlatformHob->DramInfo.NumRegion; Index++) {
+    if (SystemMemoryTop <= PlatformHob->DramInfo.Base[Index] &&
+        PlatformHob->DramInfo.Node[Index] == 0 &&
+        (PlatformHob->DramInfo.Base[Index] +
+         PlatformHob->DramInfo.Size[Index] - 1) <= 0xFFFFFFFF)
+    {
+      SystemMemoryTop = PlatformHob->DramInfo.Base[Index] + PlatformHob->DramInfo.Size[Index];
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "PEIM memory configuration.\n"));
+
+  SystemMemoryBase = (UINTN)FixedPcdGet64 (PcdSystemMemoryBase);
+  FdBase = (UINTN)PcdGet64 (PcdFdBaseAddress);
+  FdTop = FdBase + (UINTN)PcdGet32 (PcdFdSize);
+
+  // In case the firmware has been shadowed in the System Memory
+  if ((FdBase >= SystemMemoryBase) && (FdTop <= SystemMemoryTop)) {
+    //
+    // Check if there is enough space between the top of the system memory and the top of the
+    // firmware to place the UEFI memory (for PEI & DXE phases)
+    //
+    if (SystemMemoryTop - FdTop >= FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)) {
+      UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+    } else {
+      // Check there is enough space for the UEFI memory
+      ASSERT (SystemMemoryBase + FixedPcdGet32 (PcdSystemMemoryUefiRegionSize) <= FdBase);
+
+      UefiMemoryBase = FdBase - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+    }
+  } else {
+    // Check the Firmware does not overlapped with the system memory
+    ASSERT ((FdBase < SystemMemoryBase) || (FdBase >= SystemMemoryTop));
+    ASSERT ((FdTop <= SystemMemoryBase) || (FdTop > SystemMemoryTop));
+
+    UefiMemoryBase = SystemMemoryTop - FixedPcdGet32 (PcdSystemMemoryUefiRegionSize);
+  }
+
+  Status = PeiServicesInstallPeiMemory (
+             UefiMemoryBase,
+             FixedPcdGet32 (PcdSystemMemoryUefiRegionSize)
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error: Failed to install Pei Memory\n"));
+  } else {
+    DEBUG ((DEBUG_INFO, "Info: Installed Pei Memory\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  // Initialize MMU and Memory HOBs (Resource Descriptor HOBs)
+  Status = MemoryPeim (UefiMemoryBase, FixedPcdGet32 (PcdSystemMemoryUefiRegionSize));
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error: Failed to initialize MMU and Memory HOBS\n"));
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
new file mode 100644
index 000000000000..8da698e0b855
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
@@ -0,0 +1,706 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/NVParamLib.h>
+#include <NVParamDef.h>
+#include <Platform/Ac01.h>
+#include <PlatformInfoHob.h>
+
+STATIC PLATFORM_INFO_HOB *mPlatformInfoHob = NULL;
+
+PLATFORM_INFO_HOB *
+GetPlatformHob (
+  VOID
+  )
+{
+  VOID *Hob;
+
+  if (mPlatformInfoHob == NULL) {
+    Hob = GetNextGuidHob (
+            &gPlatformHobGuid,
+            (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase)
+            );
+    ASSERT (Hob != NULL);
+    if (Hob == NULL) {
+      DEBUG ((DEBUG_ERROR, "%a: Failed to get gPlatformHobGuid!\n", __FUNCTION__));
+      return NULL;
+    }
+
+    mPlatformInfoHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+  }
+
+  return mPlatformInfoHob;
+}
+
+/**
+  Get the SubNUMA mode.
+
+  @return   UINT8      The SubNUMA mode.
+
+**/
+UINT8
+EFIAPI
+CpuGetSubNumaMode (
+  VOID
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    return SUBNUMA_MODE_MONOLITHIC;
+  }
+
+  return PlatformHob->SubNumaMode[0];
+}
+
+/**
+  Get the number of SubNUMA region.
+
+  @return   UINT8      The number of SubNUMA region.
+
+**/
+UINT8
+EFIAPI
+CpuGetNumberOfSubNumaRegion (
+  VOID
+  )
+{
+  UINT8 SubNumaMode;
+  UINT8 NumberOfSubNumaRegion;
+
+  SubNumaMode = CpuGetSubNumaMode ();
+  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
+
+  switch (SubNumaMode) {
+  case SUBNUMA_MODE_MONOLITHIC:
+    NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION;
+    break;
+
+  case SUBNUMA_MODE_HEMISPHERE:
+    NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION;
+    break;
+
+  case SUBNUMA_MODE_QUADRANT:
+    NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION;
+    break;
+
+  default:
+    // Should never reach there.
+    ASSERT (FALSE);
+    break;
+  }
+
+  return NumberOfSubNumaRegion;
+}
+
+/**
+  Get the SubNUMA node of a CPM.
+
+  @param    SocketId    Socket index.
+  @param    Cpm         CPM index.
+  @return   UINT8       The SubNUMA node of a CPM.
+
+**/
+UINT8
+EFIAPI
+CpuGetSubNumNode (
+  UINT8  SocketId,
+  UINT16 Cpm
+  )
+{
+  BOOLEAN IsAsymMesh;
+  UINT8   SubNumaNode;
+  UINT16  MaxNumberOfCPM;
+  UINT8   MiddleRow;
+  UINT8   QuadrantHigherRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {1, 1, 1, 1, 3, 3, 3, 3};
+  UINT8   QuadrantLowerRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW]  = {0, 0, 0, 0, 2, 2, 2, 2};
+  UINT8   QuadrantMiddleRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 1, 1, 3, 3, 2, 2};
+  UINT8   SubNumaMode;
+
+  MaxNumberOfCPM = GetMaximumNumberOfCPMs ();
+  SubNumaMode = CpuGetSubNumaMode ();
+  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
+
+  switch (SubNumaMode) {
+  case SUBNUMA_MODE_MONOLITHIC:
+    SubNumaNode = (SocketId == 0) ? 0 : 1;
+    break;
+
+  case SUBNUMA_MODE_HEMISPHERE:
+    if (CPM_PER_ROW_OFFSET (Cpm) >= SUBNUMA_CPM_REGION_SIZE) {
+      SubNumaNode = 1;
+    } else {
+      SubNumaNode = 0;
+    }
+
+    if (SocketId == 1) {
+      SubNumaNode += HEMISPHERE_NUM_OF_REGION;
+    }
+    break;
+
+  case SUBNUMA_MODE_QUADRANT:
+    //
+    // CPM Mesh Rows
+    //
+    // |---------------------------------------|
+    // | 00 ----------- 03 | 04 ----------- 07 | Row 0
+    // |-------------------|-------------------|
+    // | 08 ----------- 11 | 12 ----------- 15 | Row 1
+    // |-------------------|-------------------|
+    // | 16 - 17 | 18 - 19 | 20 - 21 | 22 - 23 | Middle Row
+    // |-------------------|-------------------|
+    // | 24 ----------- 27 | 28 ----------- 31 | Row 3
+    // |-------------------|-------------------|
+    // | 32 ----------- 35 | 36 ----------- 39 | Row 4
+    // |---------------------------------------|
+    //
+
+    IsAsymMesh = (BOOLEAN)(CPM_ROW_NUMBER (MaxNumberOfCPM) % 2 != 0);
+    MiddleRow = CPM_ROW_NUMBER (MaxNumberOfCPM) / 2;
+    if (IsAsymMesh
+        && CPM_ROW_NUMBER (Cpm) == MiddleRow)
+    {
+      SubNumaNode = QuadrantMiddleRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
+
+    } else if (CPM_ROW_NUMBER (Cpm) >= MiddleRow) {
+      SubNumaNode = QuadrantHigherRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
+
+    } else {
+      SubNumaNode = QuadrantLowerRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
+    }
+
+    if (SocketId == 1) {
+      SubNumaNode += QUADRANT_NUM_OF_REGION;
+    }
+    break;
+
+  default:
+    // Should never reach there.
+    ASSERT (FALSE);
+    break;
+  }
+
+  return SubNumaNode;
+}
+
+/**
+  Get the associativity of cache.
+
+  @param    Level       Cache level.
+  @return   UINT32      Associativity of cache.
+
+**/
+UINT32
+EFIAPI
+CpuGetAssociativity (
+  UINT32 Level
+  )
+{
+  UINT64 CacheCCSIDR;
+  UINT64 CacheCLIDR;
+  UINT32 Value = 0x2; /* Unknown Set-Associativity */
+
+  CacheCLIDR = ReadCLIDR ();
+  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
+    return Value;
+  }
+
+  CacheCCSIDR = ReadCCSIDR (Level);
+  switch (CCSIDR_ASSOCIATIVITY (CacheCCSIDR)) {
+  case 0:
+    /* Direct mapped */
+    Value = 0x3;
+    break;
+
+  case 1:
+    /* 2-way Set-Associativity */
+    Value = 0x4;
+    break;
+
+  case 3:
+    /* 4-way Set-Associativity */
+    Value = 0x5;
+    break;
+
+  case 7:
+    /* 8-way Set-Associativity */
+    Value = 0x7;
+    break;
+
+  case 15:
+    /* 16-way Set-Associativity */
+    Value = 0x8;
+    break;
+
+  case 11:
+    /* 12-way Set-Associativity */
+    Value = 0x9;
+    break;
+
+  case 23:
+    /* 24-way Set-Associativity */
+    Value = 0xA;
+    break;
+
+  case 31:
+    /* 32-way Set-Associativity */
+    Value = 0xB;
+    break;
+
+  case 47:
+    /* 48-way Set-Associativity */
+    Value = 0xC;
+    break;
+
+  case 63:
+    /* 64-way Set-Associativity */
+    Value = 0xD;
+    break;
+
+  case 19:
+    /* 20-way Set-Associativity */
+    Value = 0xE;
+    break;
+  }
+
+  return Value;
+}
+
+/**
+  Get the cache size.
+
+  @param    Level       Cache level.
+  @return   UINT32      Cache size.
+
+**/
+UINT32
+EFIAPI
+CpuGetCacheSize (
+  UINT32 Level
+  )
+{
+  UINT32 CacheLineSize;
+  UINT32 Count;
+  UINT64 CacheCCSIDR;
+  UINT64 CacheCLIDR;
+
+  CacheCLIDR = ReadCLIDR ();
+  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
+    return 0;
+  }
+
+  CacheCCSIDR = ReadCCSIDR (Level);
+  CacheLineSize = 1;
+  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
+  while (Count-- > 0) {
+    CacheLineSize *= 2;
+  }
+
+  return ((CCSIDR_NUMSETS (CacheCCSIDR) + 1) *
+          (CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1) *
+          CacheLineSize);
+}
+
+/**
+  Get the number of supported socket.
+
+  @return   UINT8      Number of supported socket.
+
+**/
+UINT8
+EFIAPI
+GetNumberOfSupportedSockets (
+  VOID
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    //
+    // By default, the number of supported sockets is 1.
+    //
+    return 1;
+  }
+
+  return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN));
+}
+
+/**
+  Get the number of active socket.
+
+  @return   UINT8      Number of active socket.
+
+**/
+UINT8
+EFIAPI
+GetNumberOfActiveSockets (
+  VOID
+  )
+{
+  UINT8               NumberOfActiveSockets, Count, Index, Index1;
+  PLATFORM_CLUSTER_EN *Socket;
+  PLATFORM_INFO_HOB   *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    //
+    // By default, the number of active sockets is 1.
+    //
+    return 1;
+  }
+
+  NumberOfActiveSockets = 0;
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    Socket = &PlatformHob->ClusterEn[Index];
+    Count = ARRAY_SIZE (Socket->EnableMask);
+    for (Index1 = 0; Index1 < Count; Index1++) {
+      if (Socket->EnableMask[Index1] != 0) {
+        NumberOfActiveSockets++;
+        break;
+      }
+    }
+  }
+
+  return NumberOfActiveSockets;
+}
+
+/**
+  Get the number of active CPM per socket.
+
+  @param    SocketId    Socket index.
+  @return   UINT16      Number of CPM.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCPMsPerSocket (
+  UINT8 SocketId
+  )
+{
+  UINT16              NumberOfCPMs, Count, Index;
+  UINT32              Val32;
+  PLATFORM_CLUSTER_EN *Socket;
+  PLATFORM_INFO_HOB   *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    return 0;
+  }
+
+  if (SocketId >= GetNumberOfActiveSockets ()) {
+    return 0;
+  }
+
+  NumberOfCPMs = 0;
+  Socket = &PlatformHob->ClusterEn[SocketId];
+  Count = ARRAY_SIZE (Socket->EnableMask);
+  for (Index = 0; Index < Count; Index++) {
+    Val32 = Socket->EnableMask[Index];
+    while (Val32 > 0) {
+      if ((Val32 & 0x1) != 0) {
+        NumberOfCPMs++;
+      }
+      Val32 >>= 1;
+    }
+  }
+
+  return NumberOfCPMs;
+}
+
+/**
+  Get the number of configured CPM per socket. This number
+  should be the same for all sockets.
+
+  @param    SocketId    Socket index.
+  @return   UINT8       Number of configured CPM.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfConfiguredCPMs (
+  UINT8 SocketId
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+  UINT32     Param, ParamStart, ParamEnd;
+  UINT16     Count;
+
+  Count = 0;
+  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
+  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
+  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
+    Status = NVParamGet (
+               Param,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               &Value
+               );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+    while (Value != 0) {
+      if ((Value & 0x01) != 0) {
+        Count++;
+      }
+      Value >>= 1;
+    }
+  }
+
+  return Count;
+}
+
+/**
+  Set the number of configured CPM per socket.
+
+  @param    SocketId        Socket index.
+  @param    NumberOfCPMs    Number of CPM to be configured.
+  @return   EFI_SUCCESS     Operation succeeded.
+  @return   Others          An error has occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+SetNumberOfConfiguredCPMs (
+  UINT8  SocketId,
+  UINT16 NumberOfCPMs
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+  UINT32     Param, ParamStart, ParamEnd;
+  BOOLEAN    IsClear;
+
+  IsClear = FALSE;
+  if (NumberOfCPMs == 0) {
+    IsClear = TRUE;
+  }
+
+  Status = EFI_SUCCESS;
+
+  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
+  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
+  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
+    if (NumberOfCPMs >= 32) {
+      Value = 0xffffffff;
+      NumberOfCPMs -= 32;
+    } else {
+      Value = 0;
+      while (NumberOfCPMs > 0) {
+        Value |= (1 << (--NumberOfCPMs));
+      }
+    }
+    if (IsClear) {
+      /* Clear this param */
+      Status = NVParamClr (
+                 Param,
+                 NV_PERM_BIOS | NV_PERM_MANU
+                 );
+    } else {
+      Status = NVParamSet (
+                 Param,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 Value
+                 );
+    }
+  }
+
+  return Status;
+}
+
+/**
+  Get the maximum number of core per socket.
+
+  @return   UINT16      Maximum number of core.
+
+**/
+UINT16
+EFIAPI
+GetMaximumNumberOfCores (
+  VOID
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    return 0;
+  }
+
+  return PlatformHob->MaxNumOfCore[0];
+}
+
+/**
+  Get the maximum number of CPM per socket. This number
+  should be the same for all sockets.
+
+  @return   UINT16      Maximum number of CPM.
+
+**/
+UINT16
+EFIAPI
+GetMaximumNumberOfCPMs (
+  VOID
+  )
+{
+  return GetMaximumNumberOfCores () / PLATFORM_CPU_NUM_CORES_PER_CPM;
+}
+
+/**
+  Get the number of active cores of a sockets.
+
+  @param    SocketId    Socket Index.
+  @return   UINT16      Number of active core.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCoresPerSocket (
+  UINT8 SocketId
+  )
+{
+  return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM;
+}
+
+/**
+  Get the number of active cores of all sockets.
+
+  @return   UINT16      Number of active core.
+
+**/
+UINT16
+EFIAPI
+GetNumberOfActiveCores (
+  VOID
+  )
+{
+  UINT16 NumberOfActiveCores;
+  UINT8  Index;
+
+  NumberOfActiveCores = 0;
+
+  for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) {
+    NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index);
+  }
+
+  return NumberOfActiveCores;
+}
+
+/**
+  Check if the logical CPU is enabled or not.
+
+  @param    CpuId       The logical Cpu ID. Started from 0.
+  @return   BOOLEAN     TRUE if the Cpu enabled
+                        FALSE if the Cpu disabled.
+
+**/
+BOOLEAN
+EFIAPI
+IsCpuEnabled (
+  UINT16 CpuId
+  )
+{
+  PLATFORM_CLUSTER_EN *Socket;
+  PLATFORM_INFO_HOB   *PlatformHob;
+  UINT8               SocketId;
+  UINT16              ClusterId;
+
+  SocketId = SOCKET_ID (CpuId);
+  ClusterId = CLUSTER_ID (CpuId);
+
+  PlatformHob = GetPlatformHob ();
+  if (PlatformHob == NULL) {
+    return FALSE;
+  }
+
+  if (SocketId >= GetNumberOfActiveSockets ()) {
+    return FALSE;
+  }
+
+  Socket = &PlatformHob->ClusterEn[SocketId];
+  if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Check if the slave socket is present
+
+  @return   BOOLEAN     TRUE if the Slave Cpu is present
+                        FALSE if the Slave Cpu is not present
+
+**/
+BOOLEAN
+EFIAPI
+IsSlaveSocketPresent (
+  VOID
+  )
+{
+  UINT32 Value;
+
+  Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET);
+
+  return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE;
+}
+
+/**
+  Check if the slave socket is active
+
+  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
+                        FALSE if the Slave CPU Socket is not active.
+
+**/
+BOOLEAN
+EFIAPI
+IsSlaveSocketActive (
+  VOID
+  )
+{
+  return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE;
+}
+
+/**
+  Check if the CPU product ID is Ac01
+  @return   BOOLEAN     TRUE if the Product ID is Ac01
+                        FALSE otherwise.
+
+**/
+BOOLEAN
+EFIAPI
+IsAc01Processor (
+  VOID
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  PlatformHob = GetPlatformHob ();
+  ASSERT (PlatformHob != NULL);
+
+  if (PlatformHob != NULL) {
+    if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) {
+      return TRUE;
+    }
+  }
+
+  return FALSE;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
new file mode 100644
index 000000000000..8c1eb93f00fd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
@@ -0,0 +1,169 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PL011UartLib.h>
+#include <Library/SerialPortLib.h>
+#include <Platform/Ac01.h>
+#include <PlatformInfoHob.h>
+#include <Ppi/ArmMpCoreInfo.h>
+#include <Ppi/TemporaryRamSupport.h>
+
+ARM_CORE_INFO mArmPlatformMpCoreInfoTable[PLATFORM_CPU_MAX_NUM_CORES];
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+  @return   Return the current Boot Mode of the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
+
+/**
+  Initialize controllers that must setup in the normal world
+
+  This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
+  in the PEI phase.
+
+**/
+EFI_STATUS
+ArmPlatformInitialize (
+  IN UINTN MpId
+  )
+{
+  RETURN_STATUS      Status;
+  UINT64             BaudRate;
+  UINT32             ReceiveFifoDepth;
+  EFI_PARITY_TYPE    Parity;
+  UINT8              DataBits;
+  EFI_STOP_BITS_TYPE StopBits;
+
+  Status = EFI_SUCCESS;
+
+  if (FixedPcdGet64 (PcdSerialRegisterBase) != 0) {
+    /* Debug port should use the same parameters with console */
+    BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
+    ReceiveFifoDepth = FixedPcdGet32 (PcdUartDefaultReceiveFifoDepth);
+    Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
+    DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
+    StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
+
+    /* Initialize uart debug port */
+    Status = PL011UartInitializePort (
+               (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
+               FixedPcdGet32 (PL011UartClkInHz),
+               &BaudRate,
+               &ReceiveFifoDepth,
+               &Parity,
+               &DataBits,
+               &StopBits
+               );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN         *CoreCount,
+  OUT ARM_CORE_INFO **ArmCoreTable
+  )
+{
+  UINTN              mArmPlatformCoreCount;
+  UINTN              ClusterId;
+  UINTN              SocketId;
+  UINTN              Index;
+
+  ASSERT (CoreCount != NULL);
+  ASSERT (ArmCoreTable != NULL);
+  ASSERT (*ArmCoreTable != NULL);
+
+  mArmPlatformCoreCount = 0;
+  for  (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index++) {
+    if (!IsCpuEnabled (Index)) {
+      continue;
+    }
+    SocketId = SOCKET_ID (Index);
+    ClusterId = CLUSTER_ID (Index);
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].ClusterId = SocketId;
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].CoreId =
+      (ClusterId << 8) | (Index % PLATFORM_CPU_NUM_CORES_PER_CPM);
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearAddress = 0;
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearValue = 0;
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxGetAddress = 0;
+    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxSetAddress = 0;
+    mArmPlatformCoreCount++;
+  }
+
+  *CoreCount = mArmPlatformCoreCount;
+
+  *ArmCoreTable = mArmPlatformMpCoreInfoTable;
+  ASSERT (*ArmCoreTable != NULL);
+
+  return EFI_SUCCESS;
+}
+
+// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
+EFI_GUID             mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+
+EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &mArmMpCoreInfoPpiGuid,
+    &mMpCoreInfoPpi
+  },
+};
+
+/**
+  Return the Platform specific PPIs
+
+  This function exposes the Platform Specific PPIs. They can be used by any PrePi modules or passed
+  to the PeiCore by PrePeiCore.
+
+  @param[out]   PpiListSize         Size in Bytes of the Platform PPI List
+  @param[out]   PpiList             Platform PPI List
+
+**/
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                  *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
+  )
+{
+  ASSERT (PpiListSize != NULL);
+  ASSERT (PpiList != NULL);
+  ASSERT (*PpiList != NULL);
+
+  if (ArmIsMpCore ()) {
+    *PpiListSize = sizeof (gPlatformPpiTable);
+    *PpiList = gPlatformPpiTable;
+  } else {
+    *PpiListSize = 0;
+    *PpiList = NULL;
+  }
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
new file mode 100644
index 000000000000..117c9cc56ac2
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
@@ -0,0 +1,399 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <PlatformInfoHob.h>
+
+/* Number of Virtual Memory Map Descriptors */
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          50
+
+/* DDR attributes */
+#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
+  )
+{
+  UINTN                        Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
+  UINT32                       NumRegion;
+  UINTN                        Count;
+  VOID                         *Hob;
+  PLATFORM_INFO_HOB            *PlatformHob;
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  ASSERT (VirtualMemoryMap != NULL);
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  /* For Address space 0x1000_0000_0000 to 0x1001_00FF_FFFF
+   *  - Device memory
+   */
+  VirtualMemoryTable[Index].PhysicalBase = 0x100000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x100000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x102000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /* For Address space 0x5000_0000_0000 to 0x5001_00FF_FFFF
+   *  - Device memory
+   */
+  if (IsSlaveSocketActive ())
+  {
+    VirtualMemoryTable[++Index].PhysicalBase = 0x500000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x500000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x101000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  }
+
+  /*
+   *  - PCIe RCA0 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x300000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x300000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCA0 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x20000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x20000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCA1 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x340000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x340000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCA1 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x28000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x28000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCA2 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x380000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x380000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCA2 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x30000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x30000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCA3 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x3C0000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x3C0000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCA3 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x38000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x38000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCB0 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x200000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x200000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCB0 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x00000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x00000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCB1 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x240000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x240000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCB1 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x08000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x08000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCB2 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x280000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x280000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCB2 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x10000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x10000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - PCIe RCB3 Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x2C0000000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x2C0000000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket0 RCB3 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x18000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x18000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  if (IsSlaveSocketActive ()) {
+    // Slave socket exist
+    /*
+     *  - PCIe RCA0 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x700000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x700000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCA1 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x740000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x740000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCA2 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x780000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x780000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCA3 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x7C0000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x7C0000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCB0 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x600000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x600000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCB1 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x640000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x640000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCB2 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x680000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x680000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+    /*
+     *  - PCIe RCB3 Device memory
+     */
+    VirtualMemoryTable[++Index].PhysicalBase = 0x6C0000000000ULL;
+    VirtualMemoryTable[Index].VirtualBase  = 0x6C0000000000ULL;
+    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
+    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+  }
+
+  /*
+   *  - 2P/PCIe Socket1 RCA0 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x60000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x60000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCA1 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x68000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x68000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCA2 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x70000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x70000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCA3 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x78000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x78000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCB0 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x40000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x40000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCB1 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x48000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x48000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCB2 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x50000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x50000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - 2P/PCIe Socket1 RCB3 32-bit Device memory
+   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x58000000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x58000000ULL;
+  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - BERT memory region
+   */
+  VirtualMemoryTable[++Index].PhysicalBase = 0x88230000ULL;
+  VirtualMemoryTable[Index].VirtualBase  = 0x88230000ULL;
+  VirtualMemoryTable[Index].Length       = 0x50000ULL;
+  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
+
+  /*
+   *  - DDR memory region
+   */
+  NumRegion = PlatformHob->DramInfo.NumRegion;
+  Count = 0;
+  while (NumRegion-- > 0) {
+    if (PlatformHob->DramInfo.NvdRegion[Count]) { /* Skip NVDIMM Region */
+      Count++;
+      continue;
+    }
+
+    VirtualMemoryTable[++Index].PhysicalBase = PlatformHob->DramInfo.Base[Count];
+    VirtualMemoryTable[Index].VirtualBase  = PlatformHob->DramInfo.Base[Count];
+    VirtualMemoryTable[Index].Length       = PlatformHob->DramInfo.Size[Count];
+    VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
+    Count++;
+  }
+
+  /* SPM MM NS Buffer for MmCommunicateDxe */
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase);
+  VirtualMemoryTable[Index].VirtualBase  = PcdGet64 (PcdMmBufferBase);
+  VirtualMemoryTable[Index].Length       = PcdGet64 (PcdMmBufferSize);
+  VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
+
+  /* End of Table */
+  VirtualMemoryTable[++Index].PhysicalBase = 0;
+  VirtualMemoryTable[Index].VirtualBase  = 0;
+  VirtualMemoryTable[Index].Length       = 0;
+  VirtualMemoryTable[Index].Attributes   = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
new file mode 100644
index 000000000000..0da1f90699f6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
@@ -0,0 +1,282 @@
+/** @file
+  The library implements the hardware Mailbox (Doorbell) interface for communication
+  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MailboxInterfaceLib.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+
+//
+// Hardware Doorbells
+//
+#define SMPRO_DB0_IRQ_OFST               40
+#define SMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdSmproDbBaseReg))
+
+#define PMPRO_DB0_IRQ_OFST               56
+#define PMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdPmproDbBaseReg))
+
+#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000
+
+//
+// The base SPI interrupt number of the Slave socket
+//
+#define SLAVE_SOCKET_SPI_INTERRUPT 352
+
+#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32)
+
+//
+// Doorbell base register stride size
+//
+#define DB_BASE_REG_STRIDE 0x00001000
+
+#define SMPRO_DBx_ADDRESS(socket, db) \
+        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
+
+#define PMPRO_DBx_ADDRESS(socket, db) \
+        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
+
+//
+// Doorbell Status Bits
+//
+#define DB_STATUS_AVAIL_BIT       BIT16
+#define DB_STATUS_ACK_BIT         BIT0
+
+/**
+  Get the base address of a doorbell.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+
+  @retval UINT32                The base address of the doorbell.
+                                The returned value is 0 indicate that the input parameters are invalid.
+
+**/
+UINTN
+EFIAPI
+MailboxGetDoorbellAddress (
+  IN UINT8             Socket,
+  IN DOORBELL_CHANNELS Doorbell
+  )
+{
+  UINTN DoorbellAddress;
+
+  if (Socket >= GetNumberOfActiveSockets ()
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
+  {
+    return 0;
+  }
+
+  if (Doorbell >= SMproDoorbellChannel0) {
+    DoorbellAddress = SMPRO_DBx_ADDRESS (Socket, (UINT8)(Doorbell - SMproDoorbellChannel0));
+  } else {
+    DoorbellAddress = PMPRO_DBx_ADDRESS (Socket, (UINT8)Doorbell);
+  }
+
+  return DoorbellAddress;
+}
+
+/**
+  Get the interrupt number of a doorbell.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+
+  @retval UINT32                The interrupt number.
+                                The returned value is 0 indicate that the input parameters are invalid.
+
+**/
+UINT32
+EFIAPI
+MailboxGetDoorbellInterruptNumber (
+  IN UINT8             Socket,
+  IN DOORBELL_CHANNELS Doorbell
+  )
+{
+  UINT32 DoorbellInterruptNumber;
+
+  if (Socket >= GetNumberOfActiveSockets ()
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
+  {
+    return 0;
+  }
+
+  DoorbellInterruptNumber = 0;
+
+  if (Socket > 0) {
+    DoorbellInterruptNumber = SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE (Socket);
+  }
+
+  if (Doorbell >= SMproDoorbellChannel0) {
+    DoorbellInterruptNumber += SMPRO_DB0_IRQ_OFST + (UINT8)(Doorbell - SMproDoorbellChannel0);
+  } else {
+    DoorbellInterruptNumber += PMPRO_DB0_IRQ_OFST + (UINT8)Doorbell;
+  }
+
+  return DoorbellInterruptNumber;
+}
+
+/**
+  Read a message via the hardware Doorbell interface.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
+  @param[out] Message           Pointer to the Mailbox message.
+
+  @retval EFI_SUCCESS           Read the message successfully.
+  @retval EFI_TIMEOUT           Timeout occurred when waiting for available message in the mailbox.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+MailboxRead (
+  IN  UINT8                Socket,
+  IN  DOORBELL_CHANNELS    Doorbell,
+  OUT MAILBOX_MESSAGE_DATA *Message
+  )
+{
+  UINTN TimeoutCount;
+  UINTN DoorbellAddress;
+
+  if (Socket >= GetNumberOfActiveSockets ()
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
+      || Message == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TimeoutCount = MAILBOX_POLL_COUNT;
+
+  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
+  ASSERT (DoorbellAddress != 0);
+
+  //
+  // Polling Doorbell status
+  //
+  while ((MmioRead32 ((DoorbellAddress + DB_STATUS_REG_OFST)) & DB_STATUS_AVAIL_BIT) == 0) {
+    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
+    if (--TimeoutCount == 0) {
+      return EFI_TIMEOUT;
+    }
+  }
+
+  Message->ExtendedData[0] = MmioRead32 (DoorbellAddress + DB_DIN0_REG_OFST);
+  Message->ExtendedData[1] = MmioRead32 (DoorbellAddress + DB_DIN1_REG_OFST);
+  Message->Data = MmioRead32 (DoorbellAddress + DB_IN_REG_OFST);
+
+  //
+  // Write 1 to clear the AVAIL status
+  //
+  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_AVAIL_BIT);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write a message via the hardware Doorbell interface.
+
+  @param[in]  Socket            Active socket index.
+  @param[in]  Doorbell          Doorbel channel for communication with the SMpro/PMpro.
+  @param[in]  Message           Pointer to the Mailbox message.
+
+  @retval EFI_SUCCESS           Write the message successfully.
+  @retval EFI_TIMEOUT           Timeout occurred when waiting for acknowledge signal from the mailbox.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+**/
+EFI_STATUS
+EFIAPI
+MailboxWrite (
+  IN UINT8                Socket,
+  IN DOORBELL_CHANNELS    Doorbell,
+  IN MAILBOX_MESSAGE_DATA *Message
+  )
+{
+  UINTN TimeoutCount;
+  UINTN DoorbellAddress;
+
+  if (Socket >= GetNumberOfActiveSockets ()
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
+      || Message == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  TimeoutCount = MAILBOX_POLL_COUNT;
+
+  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
+  ASSERT (DoorbellAddress != 0);
+
+  //
+  // Clear previous pending ack if any
+  //
+  if ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) != 0) {
+    MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
+  }
+
+  //
+  // Send message
+  //
+  MmioWrite32 (DoorbellAddress + DB_DOUT0_REG_OFST, Message->ExtendedData[0]);
+  MmioWrite32 (DoorbellAddress + DB_DOUT1_REG_OFST, Message->ExtendedData[1]);
+  MmioWrite32 (DoorbellAddress + DB_OUT_REG_OFST, Message->Data);
+
+  //
+  // Wait for ACK
+  //
+  while ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) == 0) {
+    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
+    if (--TimeoutCount == 0) {
+      return EFI_TIMEOUT;
+    }
+  }
+
+  //
+  // Write 1 to clear the ACK status
+  //
+  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unmask the Doorbell interrupt status.
+
+  @param  Socket    Active socket index.
+  @param  Doorbell  Doorbel channel for communication with the SMpro/PMpro.
+
+  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
+  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+MailboxUnmaskInterrupt (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell
+  )
+{
+  UINTN DoorbellAddress;
+
+  if (Socket >= GetNumberOfActiveSockets ()
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
+  ASSERT (DoorbellAddress != 0);
+
+  MmioWrite32 (DoorbellAddress + DB_STATUS_MASK_REG_OFST, ~DB_STATUS_AVAIL_BIT);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
new file mode 100644
index 000000000000..edf8925d5a1e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
@@ -0,0 +1,93 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/ArmMmuLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+
+STATIC
+VOID
+InitMmu (
+  IN ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable
+  )
+{
+  VOID          *TranslationTableBase;
+  UINTN         TranslationTableSize;
+  RETURN_STATUS Status;
+
+  // Note: Because we called PeiServicesInstallPeiMemory() before to call InitMmu()
+  // the MMU Page Table resides in DRAM (even at the top of DRAM as it is the first
+  // permanent memory allocation)
+  //
+  Status = ArmConfigureMmu (MemoryTable, &TranslationTableBase, &TranslationTableSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Error: Failed to enable MMU\n"));
+  }
+
+  BuildMemoryAllocationHob (
+    (EFI_PHYSICAL_ADDRESS)(UINTN)TranslationTableBase,
+    EFI_SIZE_TO_PAGES (TranslationTableSize) * EFI_PAGE_SIZE,
+    EfiBootServicesData
+    );
+}
+
+EFI_STATUS
+EFIAPI
+MemoryPeim (
+  IN EFI_PHYSICAL_ADDRESS UefiMemoryBase,
+  IN UINT64               UefiMemorySize
+  )
+{
+  ARM_MEMORY_REGION_DESCRIPTOR *MemoryTable;
+  UINTN                        Index;
+
+  /* Get Virtual Memory Map from the Platform Library */
+  ArmPlatformGetVirtualMemoryMap (&MemoryTable);
+
+  Index = 0;
+  while (MemoryTable[Index].Length != 0) {
+    if (MemoryTable[Index].Attributes == ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK) {
+      BuildResourceDescriptorHob (
+        EFI_RESOURCE_SYSTEM_MEMORY,
+        EFI_RESOURCE_ATTRIBUTE_PRESENT |
+        EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
+        EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
+        EFI_RESOURCE_ATTRIBUTE_TESTED,
+        MemoryTable[Index].PhysicalBase,
+        MemoryTable[Index].Length
+        );
+    } else if (MemoryTable[Index].Attributes == ARM_MEMORY_REGION_ATTRIBUTE_DEVICE) {
+      BuildResourceDescriptorHob (
+        EFI_RESOURCE_MEMORY_MAPPED_IO,
+        EFI_RESOURCE_ATTRIBUTE_PRESENT     |
+        EFI_RESOURCE_ATTRIBUTE_INITIALIZED,
+        MemoryTable[Index].PhysicalBase,
+        MemoryTable[Index].Length
+        );
+    }
+    Index++;
+  }
+
+  BuildMemoryAllocationHob (
+    PcdGet64 (PcdFdBaseAddress),
+    PcdGet32 (PcdFdSize),
+    EfiRuntimeServicesData
+    );
+
+  InitMmu (MemoryTable);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
new file mode 100644
index 000000000000..bf400ec0a835
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
@@ -0,0 +1,184 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/ArmStdSmc.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmCommunicationLib.h>
+#include <Library/PcdLib.h>
+#include <Protocol/MmCommunication.h>
+
+//
+// Address, Length of the pre-allocated buffer for communication with the secure
+// world.
+//
+STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
+
+EFI_STATUS
+EFIAPI
+MmCommunicationLibConstructor (
+  VOID
+  )
+{
+  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
+  // During boot , Virtual and Physical are same
+  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
+  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Communicates with a registered handler.
+
+  This function provides an interface to send and receive messages to the
+  Standalone MM environment in UEFI PEI phase.
+
+  @param[in, out] CommBuffer          A pointer to the buffer to convey
+                                      into MMRAM.
+  @param[in, out] CommSize            The size of the data buffer being
+                                      passed in. This is optional.
+
+  @retval EFI_SUCCESS                 The message was successfully posted.
+  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
+  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
+                                      implementation. If this error is
+                                      returned, the MessageLength field in
+                                      the CommBuffer header or the integer
+                                      pointed by CommSize are updated to reflect
+                                      the maximum payload size the
+                                      implementation can accommodate.
+  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
+                                      or CommSize parameter, if not omitted,
+                                      are in address range that cannot be
+                                      accessed by the MM environment
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationCommunicate (
+  IN OUT VOID  *CommBuffer,
+  IN OUT UINTN *CommSize OPTIONAL
+  )
+{
+  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+  ARM_SMC_ARGS              CommunicateSmcArgs;
+  EFI_STATUS                Status;
+  UINTN                     BufferSize;
+
+  Status = EFI_ACCESS_DENIED;
+  BufferSize = 0;
+
+  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
+
+  //
+  // Check parameters
+  //
+  if (CommBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CommunicateHeader = CommBuffer;
+  // CommBuffer is a mandatory parameter. Hence, Rely on
+  // MessageLength + Header to ascertain the
+  // total size of the communication payload rather than
+  // rely on optional CommSize parameter
+  BufferSize = CommunicateHeader->MessageLength +
+               sizeof (CommunicateHeader->HeaderGuid) +
+               sizeof (CommunicateHeader->MessageLength);
+
+  // If the length of the CommBuffer is 0 then return the expected length.
+  if (CommSize != NULL) {
+    // This case can be used by the consumer of this driver to find out the
+    // max size that can be used for allocating CommBuffer.
+    if ((*CommSize == 0) ||
+        (*CommSize > mNsCommBuffMemRegion.Length))
+    {
+      *CommSize = mNsCommBuffMemRegion.Length;
+      return EFI_BAD_BUFFER_SIZE;
+    }
+    //
+    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
+    //
+    if (*CommSize != BufferSize) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // If the buffer size is 0 or greater than what can be tolerated by the MM
+  // environment then return the expected size.
+  //
+  if ((BufferSize == 0) ||
+      (BufferSize > mNsCommBuffMemRegion.Length))
+  {
+    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
+                                       sizeof (CommunicateHeader->HeaderGuid) -
+                                       sizeof (CommunicateHeader->MessageLength);
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // SMC Function ID
+  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
+
+  // Cookie
+  CommunicateSmcArgs.Arg1 = 0;
+
+  // Copy Communication Payload
+  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
+
+  // comm_buffer_address (64-bit physical address)
+  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
+
+  // comm_size_address (not used, indicated by setting to zero)
+  CommunicateSmcArgs.Arg3 = 0;
+
+  // Call the Standalone MM environment.
+  ArmCallSmc (&CommunicateSmcArgs);
+
+  switch (CommunicateSmcArgs.Arg0) {
+  case ARM_SMC_MM_RET_SUCCESS:
+    ZeroMem (CommBuffer, BufferSize);
+    // On successful return, the size of data being returned is inferred from
+    // MessageLength + Header.
+    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
+    BufferSize = CommunicateHeader->MessageLength +
+                 sizeof (CommunicateHeader->HeaderGuid) +
+                 sizeof (CommunicateHeader->MessageLength);
+
+    CopyMem (
+      CommBuffer,
+      (VOID *)mNsCommBuffMemRegion.VirtualBase,
+      BufferSize
+      );
+    Status = EFI_SUCCESS;
+    break;
+
+  case ARM_SMC_MM_RET_INVALID_PARAMS:
+    Status = EFI_INVALID_PARAMETER;
+    break;
+
+  case ARM_SMC_MM_RET_DENIED:
+    Status = EFI_ACCESS_DENIED;
+    break;
+
+  case ARM_SMC_MM_RET_NO_MEMORY:
+    // Unexpected error since the CommSize was checked for zero length
+    // prior to issuing the SMC
+    Status = EFI_OUT_OF_RESOURCES;
+    ASSERT (0);
+    break;
+
+  default:
+    Status = EFI_ACCESS_DENIED;
+    ASSERT (0);
+  }
+
+  return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c
new file mode 100644
index 000000000000..794a0a77c25f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c
@@ -0,0 +1,202 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmCommunicationLib.h>
+#include <Library/NVParamLib.h>
+#include <MmLib.h>
+
+EFI_MM_COMM_REQUEST mCommBuffer;
+
+STATIC VOID
+UefiMmCreateNVParamReq (
+  IN VOID   *Data,
+  IN UINT64 Size
+  )
+{
+  CopyGuid (&mCommBuffer.EfiMmHdr.HeaderGuid, &gNVParamMmGuid);
+  mCommBuffer.EfiMmHdr.MsgLength = Size;
+
+  if (Size != 0) {
+    ASSERT (Data);
+    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
+
+    CopyMem (mCommBuffer.PayLoad.Data, Data, Size);
+  }
+}
+
+EFI_STATUS
+NVParamGet (
+  IN  UINT32 Param,
+  IN  UINT16 ACLRd,
+  OUT UINT32 *Val
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_MM_COMMUNICATE_NVPARAM_RES *MmNVParamRes;
+  UINT64                         MmData[5];
+  UINTN                          Size;
+
+  MmData[0] = MM_NVPARAM_FUNC_READ;
+  MmData[1] = Param;
+  MmData[2] = (UINT64)ACLRd;
+
+  UefiMmCreateNVParamReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmNVParamRes = (EFI_MM_COMMUNICATE_NVPARAM_RES *)&mCommBuffer.PayLoad;
+  switch (MmNVParamRes->Status) {
+  case MM_NVPARAM_RES_SUCCESS:
+    *Val = (UINT32)MmNVParamRes->Value;
+    return EFI_SUCCESS;
+
+  case MM_NVPARAM_RES_NOT_SET:
+    return EFI_NOT_FOUND;
+
+  case MM_NVPARAM_RES_NO_PERM:
+    return EFI_ACCESS_DENIED;
+
+  case MM_NVPARAM_RES_FAIL:
+    return EFI_DEVICE_ERROR;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+EFI_STATUS
+NVParamSet (
+  IN UINT32 Param,
+  IN UINT16 ACLRd,
+  IN UINT16 ACLWr,
+  IN UINT32 Val
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_MM_COMMUNICATE_NVPARAM_RES *MmNVParamRes;
+  UINT64                         MmData[5];
+  UINTN                          Size;
+
+  MmData[0] = MM_NVPARAM_FUNC_WRITE;
+  MmData[1] = Param;
+  MmData[2] = (UINT64)ACLRd;
+  MmData[3] = (UINT64)ACLWr;
+  MmData[4] = (UINT64)Val;
+
+  UefiMmCreateNVParamReq ((VOID *)&MmData, sizeof (MmData));
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmNVParamRes = (EFI_MM_COMMUNICATE_NVPARAM_RES *)&mCommBuffer.PayLoad;
+  switch (MmNVParamRes->Status) {
+  case MM_NVPARAM_RES_SUCCESS:
+    return EFI_SUCCESS;
+
+  case MM_NVPARAM_RES_NO_PERM:
+    return EFI_ACCESS_DENIED;
+
+  case MM_NVPARAM_RES_FAIL:
+    return EFI_DEVICE_ERROR;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+EFI_STATUS
+NVParamClr (
+  IN UINT32 Param,
+  IN UINT16 ACLWr
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_MM_COMMUNICATE_NVPARAM_RES *MmNVParamRes;
+  UINT64                         MmData[5];
+  UINTN                          Size;
+
+  MmData[0] = MM_NVPARAM_FUNC_CLEAR;
+  MmData[1] = Param;
+  MmData[2] = 0;
+  MmData[3] = (UINT64)ACLWr;
+
+  UefiMmCreateNVParamReq ((VOID *)&MmData, sizeof (MmData));
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmNVParamRes = (EFI_MM_COMMUNICATE_NVPARAM_RES *)&mCommBuffer.PayLoad;
+  switch (MmNVParamRes->Status) {
+  case MM_NVPARAM_RES_SUCCESS:
+    return EFI_SUCCESS;
+
+  case MM_NVPARAM_RES_NO_PERM:
+    return EFI_ACCESS_DENIED;
+
+  case MM_NVPARAM_RES_FAIL:
+    return EFI_DEVICE_ERROR;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+}
+
+EFI_STATUS
+NVParamClrAll (
+  VOID
+  )
+{
+  EFI_STATUS                     Status;
+  EFI_MM_COMMUNICATE_NVPARAM_RES *MmNVParamRes;
+  UINT64                         MmData[5];
+  UINTN                          Size;
+
+  MmData[0] = MM_NVPARAM_FUNC_CLEAR_ALL;
+
+  UefiMmCreateNVParamReq ((VOID *)&MmData, sizeof (MmData));
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmNVParamRes = (EFI_MM_COMMUNICATE_NVPARAM_RES *)&mCommBuffer.PayLoad;
+  switch (MmNVParamRes->Status) {
+  case MM_NVPARAM_RES_SUCCESS:
+    return EFI_SUCCESS;
+
+  case MM_NVPARAM_RES_FAIL:
+    return EFI_DEVICE_ERROR;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c
new file mode 100644
index 000000000000..3ae3ecd60719
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c
@@ -0,0 +1,40 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <PiPei.h>
+
+#include <Library/ArmLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeiServicesLib.h>
+
+EFI_STATUS
+EFIAPI
+PlatformPeim (
+  VOID
+  )
+{
+  UINT64 FvMainBase;
+  UINT32 FvMainSize;
+
+  // Build FV_MAIN Hand-off block (HOB) to let DXE IPL pick up correctly
+  FvMainBase = FixedPcdGet64 (PcdFvBaseAddress);
+  FvMainSize = FixedPcdGet32 (PcdFvSize);
+  ASSERT (FvMainSize != 0);
+
+  BuildFvHob (FvMainBase, FvMainSize);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c
new file mode 100644
index 000000000000..f7e6fb6092a6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c
@@ -0,0 +1,141 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/RngLib.h>
+#include <Library/TrngLib.h>
+
+/**
+  Generates a 16-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 16-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber16 (
+  OUT UINT16 *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (Rand != NULL);
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumbers ((UINT8 *)Rand, sizeof (UINT16));
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Generates a 32-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 32-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber32 (
+  OUT UINT32 *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (Rand != NULL);
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumbers ((UINT8 *)Rand, sizeof (UINT32));
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Generates a 64-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 64-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber64 (
+  OUT UINT64 *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (Rand != NULL);
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumbers ((UINT8 *)Rand, sizeof (UINT64));
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+/**
+  Generates a 128-bit random number.
+
+  if Rand is NULL, then ASSERT().
+
+  @param[out] Rand     Buffer pointer to store the 128-bit random value.
+
+  @retval TRUE         Random number generated successfully.
+  @retval FALSE        Failed to generate the random number.
+
+**/
+BOOLEAN
+EFIAPI
+GetRandomNumber128 (
+  OUT UINT64 *Rand
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (Rand != NULL);
+  if (Rand == NULL) {
+    return FALSE;
+  }
+
+  Status = GenerateRandomNumbers ((UINT8 *)Rand, 2 * sizeof (UINT64));
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return TRUE;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c
new file mode 100644
index 000000000000..9cab653418fb
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c
@@ -0,0 +1,328 @@
+/** @file
+  Provides functions for communication with System Firmware (SMpro/PMpro and ATF).
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MailboxInterfaceLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+
+/**
+  Read a register which is not accessible from the non-secure world
+  by sending a mailbox message to the SMpro processor.
+
+  Note that not all addresses are allowed.
+
+  @param[in]  Socket       Active socket index.
+  @param[in]  Address      A 64-bit register address to be read.
+  @param[out] Value        A pointer to the read value.
+
+  @retval EFI_SUCCESS           Read the register successfully.
+  @retval EFI_UNSUPPORTED       The register is not allowed.
+  @retval Otherwise             Errors returned from MailboxWrite/MailboxRead() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgRegisterRead (
+  IN  UINT8  Socket,
+  IN  UINTN  Address,
+  OUT UINT32 *Value
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+  UINT32               AddressLower32Bit;
+  UINT32               AddressUpper32Bit;
+
+  if (Socket >= GetNumberOfActiveSockets ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AddressLower32Bit = (UINT32)(Address & 0xFFFFFFFF);
+  AddressUpper32Bit = (UINT32)RShiftU64 ((UINT64)Address, 32);
+
+  Message.Data = MAILBOX_DEBUG_MESSAGE_ENCODE (
+                   MAILBOX_DEBUG_MESSAGE_SUBTYPE_REGISTER_READ,
+                   (UINT16)(AddressUpper32Bit & 0xFFFF)
+                   );
+
+  Message.ExtendedData[0] = AddressLower32Bit;
+  Message.ExtendedData[1] = 0;
+
+  Status = MailboxWrite (Socket, SMproDoorbellChannel0, &Message);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = MailboxRead (Socket, SMproDoorbellChannel0, &Message);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((Message.Data & 0xFF00) == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Value != NULL) {
+    *Value = Message.ExtendedData[0];
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Write a value to a register which is not accessible from the non-secure world
+  by sending a mailbox message to the SMpro processor.
+
+  Note that not all addresses are allowed.
+
+  @param[in]  Socket       Active socket index.
+  @param[in]  Address      A 64-bit register address to be written.
+  @param[in]  Value        The value to be written to the register.
+
+  @retval EFI_SUCCESS      Write the register successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise        Errors returned from the MailboxWrite() function.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgRegisterWrite (
+  IN UINT8  Socket,
+  IN UINTN  Address,
+  IN UINT32 Value
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+  UINT32               AddressLower32Bit;
+  UINT32               AddressUpper32Bit;
+
+  if (Socket >= GetNumberOfActiveSockets ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  AddressLower32Bit = (UINT32)(Address & 0xFFFFFFFF);
+  AddressUpper32Bit = (UINT32)RShiftU64 ((UINT64)Address, 32);
+
+  Message.Data = MAILBOX_DEBUG_MESSAGE_ENCODE (
+                   MAILBOX_DEBUG_MESSAGE_SUBTYPE_REGISTER_WRITE,
+                   (UINT16)(AddressUpper32Bit & 0xFFFF)
+                   );
+
+  Message.ExtendedData[0] = AddressLower32Bit;
+  Message.ExtendedData[1] = Value;
+
+  Status = MailboxWrite (Socket, SMproDoorbellChannel0, &Message);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Set the PCC shared Memory Address to service handlers in the System Control Processors,
+  using for communication between the System Firmware and OSPM.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  Doorbell         Doorbell index which is numbered like DOORBELL_CHANNELS.
+  @param[in]  AddressAlign256  Enable/Disable 256 alignment.
+  @param[in]  Address          The shared memory address.
+
+  @retval EFI_SUCCESS           Set the shared memory address successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgSetPccSharedMem (
+  IN UINT8     Socket,
+  IN UINT8     Doorbell,
+  IN BOOLEAN   AddressAlign256,
+  IN UINTN     Address
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+  UINT8                AlignBit;
+  UINT8                AlignControl;
+
+  if (Socket >= GetNumberOfActiveSockets () || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (AddressAlign256) {
+    AlignBit = 8;
+    AlignControl = MAILBOX_ADDRESS_256_ALIGNMENT;
+  } else {
+    AlignBit = 0;
+    AlignControl = MAILBOX_ADDRESS_NO_ALIGNMENT;
+  }
+
+  Message.Data = MAILBOX_ADDRESS_MESSAGE_ENCODE (
+                   MAILBOX_ADDRESS_MESSAGE_SUBTYPE_PCC,
+                   0,
+                   AlignControl
+                   );
+
+  Message.ExtendedData[0] = (UINT32)(RShiftU64 ((UINT64)Address, AlignBit) & 0xFFFFFFFF);
+  Message.ExtendedData[1] = (UINT32)(RShiftU64 ((UINT64)Address, 32 + AlignBit));
+
+  Status = MailboxWrite (Socket, Doorbell, &Message);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  The True RNG is provided by the SMpro processor. This function is to send a mailbox
+  message to the SMpro to request a 64-bit random number.
+
+  @param[out]  Buffer           A pointer to the read 64-bit random number.
+
+  @retval EFI_SUCCESS           The operation succeeds.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite/MailboxRead() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgGetRandomNumber64 (
+  OUT UINT8 *Buffer
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Message.Data = MAILBOX_USER_MESSAGE_ENCODE (
+                   MAILBOX_USER_MESSAGE_SUBTYPE_TRNG_PROXY,
+                   MAILBOX_TRNG_PROXY_GET_RANDOM_NUMBER,
+                   0
+                   );
+  Message.ExtendedData[0] = 0;
+  Message.ExtendedData[1] = 0;
+
+  Status = MailboxWrite (0, SMproDoorbellChannel6, &Message);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = MailboxRead (0, SMproDoorbellChannel6, &Message);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  CopyMem (Buffer, &Message.ExtendedData[0], sizeof (UINT32));
+  CopyMem (Buffer + sizeof (UINT32), &Message.ExtendedData[1], sizeof (UINT32));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Report the UEFI boot progress to the SMpro.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  BootStatus       The status of the UEFI boot.
+  @param[in]  Checkpoint       The UEFI Checkpoint value.
+
+  @retval EFI_SUCCESS           Set the boot progress successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgSetBootProgress (
+  IN UINT8   Socket,
+  IN UINT8   BootStatus,
+  IN UINT32  Checkpoint
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+
+  if (Socket >= GetNumberOfActiveSockets ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Message.Data = MAILBOX_USER_MESSAGE_ENCODE (
+                   MAILBOX_USER_MESSAGE_SUBTYPE_BOOT_PROGRESS,
+                   MAILBOX_BOOT_PROGRESS_COMMAND_SET,
+                   MAILBOX_BOOT_PROGRESS_STAGE_UEFI
+                   );
+
+  //
+  // Extended Data Format for Boot Progress Set
+  //
+  // Data 0:
+  //   Bit 31:16 - Boot Status
+  //   Bit 15:0  - UEFI Checkpoint lower 16-bit
+  //
+  // Data 1:
+  //   Bit 31:16 - Unused
+  //   Bit 15:0  - UEFI Checkpoint upper 16-bit
+  //
+  Message.ExtendedData[0] = ((UINT32)BootStatus & 0xFFFF) | (((UINT32)Checkpoint << 16) & 0xFFFF0000);
+  Message.ExtendedData[1] = (Checkpoint >> 16) & 0xFFFF;
+
+  Status = MailboxWrite (Socket, SMproDoorbellChannel1, &Message);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+  Configure the Turbo (Max Performance) mode.
+
+  @param[in]  Socket           Active socket index.
+  @param[in]  Enable           Enable/Disable the Turbo (Max performance) mode.
+
+  @retval EFI_SUCCESS           Configure the Turbo successfully.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+  @retval Otherwise             Errors returned from the MailboxWrite() functions.
+**/
+EFI_STATUS
+EFIAPI
+MailboxMsgTurboConfig (
+  IN UINT8   Socket,
+  IN BOOLEAN Enable
+  )
+{
+  EFI_STATUS           Status;
+  MAILBOX_MESSAGE_DATA Message;
+
+  if (Socket >= GetNumberOfSupportedSockets ()) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Message.Data = MAILBOX_USER_MESSAGE_ENCODE (
+                   MAILBOX_USER_MESSAGE_SUBTYPE_SET_CONFIGURATION,
+                   MAILBOX_SET_CONFIGURATION_TURBO,
+                   0
+                   );
+
+  //
+  // The Turbo configuration is written into the extended data 0.
+  // The extended data 1 is unused.
+  //
+  Message.ExtendedData[0] = Enable ? 1 : 0;
+  Message.ExtendedData[1] = 0;
+
+  Status = MailboxWrite (Socket, PMproDoorbellChannel1, &Message);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c
new file mode 100644
index 000000000000..55250ddcb86d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c
@@ -0,0 +1,63 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <Library/TrngLib.h>
+
+/**
+  Generates a random number by using Hardware RNG in SMpro.
+
+  @param[out] Buffer      Buffer to receive the random number.
+  @param[in]  BufferSize  Number of bytes in Buffer.
+
+  @retval EFI_SUCCESS           The random value was returned successfully.
+  @retval EFI_DEVICE_ERROR      A random value could not be retrieved
+                                due to a hardware or firmware error.
+  @retval EFI_INVALID_PARAMETER Buffer is NULL or BufferSize is zero.
+**/
+EFI_STATUS
+EFIAPI
+GenerateRandomNumbers (
+  OUT UINT8 *Buffer,
+  IN  UINTN BufferSize
+  )
+{
+  UINTN      Count;
+  UINTN      RandSize;
+  UINT64     Value;
+  EFI_STATUS Status;
+
+  if ((BufferSize == 0) || (Buffer == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // SMpro only supports generating a 64-bits random number once.
+  //
+  RandSize = sizeof (UINT64);
+  for (Count = 0; Count < (BufferSize / sizeof (UINT64)) + 1; Count++) {
+    if (Count == (BufferSize / sizeof (UINT64))) {
+      RandSize = BufferSize % sizeof (UINT64);
+    }
+
+    if (RandSize != 0) {
+      Status = MailboxMsgGetRandomNumber64 ((UINT8 *)&Value);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "%a: Failed to get random number!\n", __FUNCTION__));
+        return EFI_DEVICE_ERROR;
+      }
+      CopyMem (Buffer + Count * sizeof (UINT64), &Value, RandSize);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc b/Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
new file mode 100644
index 000000000000..027b3cf6dee4
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
@@ -0,0 +1,176 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Rules are used with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED FIXED {
+    TE  TE Align = Auto                 $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) FIXED {
+    TE     TE Align = Auto              $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) FIXED {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     TE       TE Align = Auto           $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.Binary]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       |.depex
+     TE       TE Align = Auto           |.efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+        UI       STRING="$(MODULE_NAME)" Optional
+      }
+    }
+  }
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+        UI           STRING="$(MODULE_NAME)" Optional
+      }
+    }
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+        UI           STRING="$(MODULE_NAME)" Optional
+        RAW          ACPI  Optional               |.acpi
+        RAW          ASL   Optional               |.aml
+      }
+    }
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+        UI           STRING="$(MODULE_NAME)" Optional
+      }
+    }
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER.Binary]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional |.depex
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32         PE32                   |.efi
+        UI           STRING="$(MODULE_NAME)" Optional
+      }
+    }
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    COMPRESS PI_STD {
+      GUIDED {
+        UI     STRING ="$(MODULE_NAME)"     Optional
+        PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+      }
+    }
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    COMPRESS PI_STD {
+      GUIDED {
+        PE32      PE32                    |.efi
+        UI        STRING="$(MODULE_NAME)" Optional
+        VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+      }
+    }
+  }
+
+[Rule.Common.UEFI_DRIVER.Binary]
+  FILE DRIVER = $(NAMED_GUID) {
+    PE32         PE32                   |.efi
+    UI           STRING="$(MODULE_NAME)" Optional
+    VERSION      STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW ACPI Optional           |.acpi
+    RAW ASL  Optional           |.aml
+  }
+
+[Rule.Common.PEIM.FMP_IMAGE_DESC]
+  FILE PEIM = $(NAMED_GUID) {
+     RAW BIN                  |.acpi
+     PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32    Align=4K          $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+     VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Platform/Ampere/JadePkg/JadeBoardSetting.cfg b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
new file mode 100644
index 000000000000..5a67e8fc6a75
--- /dev/null
+++ b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
@@ -0,0 +1,209 @@
+# Sample board setting
+#
+# This is a sample board setting as used for the
+# Ampere Altra reference design.
+#
+# Name, offset (hex), value
+# value can be hex or decimal
+#
+
+NV_SI_RO_BOARD_VENDOR, 0x0000, 0x0000CD3A
+NV_SI_RO_BOARD_TYPE, 0x0008, 0x00000000
+NV_SI_RO_BOARD_REV, 0x0010, 0x00000000
+NV_SI_RO_BOARD_CFG, 0x0018, 0x00000000
+NV_SI_RO_BOARD_S0_DIMM_AVAIL, 0x0020, 0x0000FFFF
+NV_SI_RO_BOARD_S1_DIMM_AVAIL, 0x0028, 0x0000FFFF
+NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ, 0x0030, 0x000080E8
+NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ, 0x0038, 0x000080E8
+NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ, 0x0040, 0x00002710
+NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ, 0x0048, 0x00002710
+NV_SI_RO_BOARD_TPM_LOC, 0x0050, 0x00000000
+NV_SI_RO_BOARD_I2C0_FREQ_KHZ, 0x0058, 0x00000190
+NV_SI_RO_BOARD_I2C1_FREQ_KHZ, 0x0060, 0x00000190
+NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ, 0x0068, 0x00000190
+NV_SI_RO_BOARD_I2C3_FREQ_KHZ, 0x0070, 0x00000190
+NV_SI_RO_BOARD_I2C9_FREQ_KHZ, 0x0078, 0x00000190
+NV_SI_RO_BOARD_2P_CFG, 0x0080, 0xFFFFFF01
+NV_SI_RO_BOARD_S0_RCA0_CFG, 0x0088, 0x00000000
+NV_SI_RO_BOARD_S0_RCA1_CFG, 0x0090, 0x00000000
+NV_SI_RO_BOARD_S0_RCA2_CFG, 0x0098, 0x00000004
+NV_SI_RO_BOARD_S0_RCA3_CFG, 0x00A0, 0x00000004
+NV_SI_RO_BOARD_S0_RCB0_LO_CFG, 0x00A8, 0x00020002
+NV_SI_RO_BOARD_S0_RCB0_HI_CFG, 0x00B0, 0x00020002
+NV_SI_RO_BOARD_S0_RCB1_LO_CFG, 0x00B8, 0x00020002
+NV_SI_RO_BOARD_S0_RCB1_HI_CFG, 0x00C0, 0x00020002
+NV_SI_RO_BOARD_S0_RCB2_LO_CFG, 0x00C8, 0x00020002
+NV_SI_RO_BOARD_S0_RCB2_HI_CFG, 0x00D0, 0x00000003
+NV_SI_RO_BOARD_S0_RCB3_LO_CFG, 0x00D8, 0x00000003
+NV_SI_RO_BOARD_S0_RCB3_HI_CFG, 0x00E0, 0x00020002
+NV_SI_RO_BOARD_S1_RCA0_CFG, 0x00E8, 0x00000000
+NV_SI_RO_BOARD_S1_RCA1_CFG, 0x00F0, 0x00000000
+NV_SI_RO_BOARD_S1_RCA2_CFG, 0x00F8, 0x02020202
+NV_SI_RO_BOARD_S1_RCA3_CFG, 0x0100, 0x00030003
+NV_SI_RO_BOARD_S1_RCB0_LO_CFG, 0x0108, 0x00000003
+NV_SI_RO_BOARD_S1_RCB0_HI_CFG, 0x0110, 0x00020002
+NV_SI_RO_BOARD_S1_RCB1_LO_CFG, 0x0118, 0x00020002
+NV_SI_RO_BOARD_S1_RCB1_HI_CFG, 0x0120, 0x00000003
+NV_SI_RO_BOARD_S1_RCB2_LO_CFG, 0x0128, 0x00020002
+NV_SI_RO_BOARD_S1_RCB2_HI_CFG, 0x0130, 0x00020002
+NV_SI_RO_BOARD_S1_RCB3_LO_CFG, 0x0138, 0x00020002
+NV_SI_RO_BOARD_S1_RCB3_HI_CFG, 0x0140, 0x00020002
+NV_SI_RO_BOARD_T_LTLM_DELTA_P0, 0x0148, 0x00000001
+NV_SI_RO_BOARD_T_LTLM_DELTA_P1, 0x0150, 0x00000002
+NV_SI_RO_BOARD_T_LTLM_DELTA_P2, 0x0158, 0x00000003
+NV_SI_RO_BOARD_T_LTLM_DELTA_P3, 0x0160, 0x00000004
+NV_SI_RO_BOARD_T_LTLM_DELTA_M1, 0x0168, 0xFFFFFFFF
+NV_SI_RO_BOARD_T_LTLM_DELTA_M2, 0x0170, 0xFFFFFFFE
+NV_SI_RO_BOARD_T_LTLM_DELTA_M3, 0x0178, 0xFFFFFFFD
+NV_SI_RO_BOARD_P_LM_PID_P, 0x0180, 0x00000000
+NV_SI_RO_BOARD_P_LM_PID_I, 0x0188, 0x00000000
+NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD, 0x0190, 0x00000000
+NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD, 0x0198, 0x00000000
+NV_SI_RO_BOARD_P_LM_PID_D, 0x01A0, 0x00000000
+NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST, 0x01A8, 0x00000000
+NV_SI_RO_BOARD_TPM_ALG_ID, 0x01B0, 0x00000002
+NV_SI_RO_BOARD_DDR_SPEED_GRADE, 0x01B8, 0x00000C80
+NV_SI_RO_BOARD_DDR_S0_RTT_WR, 0x01C0, 0x00020000
+NV_SI_RO_BOARD_DDR_S1_RTT_WR, 0x01C8, 0x00020000
+NV_SI_RO_BOARD_DDR_S0_RTT_NOM, 0x01D0, 0xFF060177
+NV_SI_RO_BOARD_DDR_S1_RTT_NOM, 0x01D8, 0xFF060177
+NV_SI_RO_BOARD_DDR_S0_RTT_PARK, 0x01E0, 0x00060070
+NV_SI_RO_BOARD_DDR_S1_RTT_PARK, 0x01E8, 0x00060070
+NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC, 0x01F0, 0x00000000
+NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC, 0x01F8, 0x00000000
+NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC, 0x0200, 0x00000000
+NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC, 0x0208, 0x00000000
+NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC, 0x0210, 0x000C0CCC
+NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC, 0x0218, 0x000C0CCC
+NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC, 0x0220, 0x00030333
+NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC, 0x0228, 0x00030333
+NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC, 0x0230, 0x00030333
+NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC, 0x0238, 0x00030333
+NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC, 0x0240, 0x00030333
+NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC, 0x0248, 0x00030333
+NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC, 0x0250, 0x000EDEED
+NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC, 0x0258, 0x000DEDDE
+NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC, 0x0260, 0x000B7BB7
+NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC, 0x0268, 0x0007B77B
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC, 0x0270, 0x00000005
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC, 0x0278, 0x0090DD90
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC, 0x0280, 0x00000005
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC, 0x0288, 0x0090DD90
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC, 0x0290, 0x00000005
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC, 0x0298, 0x0090DD90
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC, 0x02A0, 0x00000005
+NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC, 0x02A8, 0x0090DD90
+NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC, 0x02B0, 0x00000024
+NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC, 0x02B8, 0x0000001A
+NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC, 0x02C0, 0x00000050
+NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC, 0x02C8, 0x00000020
+NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT, 0x02D0, 0x02800280
+NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT, 0x02D8, 0x90909090
+NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT, 0x02E0, 0x00000000
+NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT, 0x02E8, 0x00C000C0
+NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ, 0x02F0, 0x00000000
+NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ, 0x02F8, 0x00000000
+NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ, 0x0300, 0x00000000
+NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ, 0x0308, 0x00000000
+NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE, 0x0310, 0x02010201
+NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE, 0x0318, 0x00000000
+NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO, 0x0320, 0x00000000
+NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL, 0x0328, 0x00000000
+NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS, 0x0330, 0x01050106
+NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD, 0x0338, 0x000005F4
+NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE, 0x0340, 0x00000000
+NV_SI_RO_BOARD_S0_PCIE_CLK_CFG, 0x0348, 0x00000000
+NV_SI_RO_BOARD_S0_RCA4_CFG, 0x0350, 0x02020202
+NV_SI_RO_BOARD_S0_RCA5_CFG, 0x0358, 0x02020202
+NV_SI_RO_BOARD_S0_RCA6_CFG, 0x0360, 0x02020202
+NV_SI_RO_BOARD_S0_RCA7_CFG, 0x0368, 0x02020003
+NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET, 0x0370, 0x00000000
+NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET, 0x0378, 0x00000000
+NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET, 0x0380, 0x00000000
+NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET, 0x0388, 0x00000000
+NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET, 0x0390, 0x00000000
+NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET, 0x0398, 0x00000000
+NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET, 0x03A0, 0x00000000
+NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET, 0x03A8, 0x00000000
+NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET, 0x03B0, 0x00000000
+NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET, 0x03B8, 0x00000000
+NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET, 0x03C0, 0x00000000
+NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET, 0x03C8, 0x00000000
+NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET, 0x03D0, 0x00000000
+NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET, 0x03D8, 0x00000000
+NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET, 0x03E0, 0x00000000
+NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET, 0x03E8, 0x00000000
+NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET, 0x03F0, 0x57575757
+NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET, 0x03F8, 0x57575757
+NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET, 0x0400, 0x57575757
+NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET, 0x0408, 0x57575757
+NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET, 0x0410, 0x57575757
+NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET, 0x0418, 0x57575757
+NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET, 0x0420, 0x57575757
+NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET, 0x0428, 0x57575757
+NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET, 0x0430, 0x57575757
+NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET, 0x0438, 0x57575757
+NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET, 0x0440, 0x57575757
+NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET, 0x0448, 0x57575757
+NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET, 0x0450, 0x57575757
+NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET, 0x0458, 0x57575757
+NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET, 0x0460, 0x57575757
+NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET, 0x0468, 0x57575757
+NV_SI_RO_BOARD_S1_PCIE_CLK_CFG, 0x0470, 0x00000000
+NV_SI_RO_BOARD_S1_RCA4_CFG, 0x0478, 0x02020202
+NV_SI_RO_BOARD_S1_RCA5_CFG, 0x0480, 0x02020202
+NV_SI_RO_BOARD_S1_RCA6_CFG, 0x0488, 0x02020202
+NV_SI_RO_BOARD_S1_RCA7_CFG, 0x0490, 0x02020003
+NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET, 0x0498, 0x00000000
+NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET, 0x04A0, 0x00000000
+NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET, 0x04A8, 0x00000000
+NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET, 0x04B0, 0x00000000
+NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET, 0x04B8, 0x00000000
+NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET, 0x04C0, 0x00000000
+NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET, 0x04C8, 0x00000000
+NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET, 0x04D0, 0x00000000
+NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET, 0x04D8, 0x00000000
+NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET, 0x04E0, 0x00000000
+NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET, 0x04E8, 0x00000000
+NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET, 0x04F0, 0x00000000
+NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET, 0x04F8, 0x00000000
+NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET, 0x0500, 0x00000000
+NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET, 0x0508, 0x57575757
+NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET, 0x0510, 0x57575757
+NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET, 0x0518, 0x57575757
+NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET, 0x0520, 0x57575757
+NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET, 0x0528, 0x57575757
+NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET, 0x0530, 0x57575757
+NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET, 0x0538, 0x57575757
+NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET, 0x0540, 0x57575757
+NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET, 0x0548, 0x57575757
+NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET, 0x0550, 0x57575757
+NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET, 0x0558, 0x57575757
+NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET, 0x0560, 0x57575757
+NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET, 0x0568, 0x57575757
+NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET, 0x0570, 0x57575757
+NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD, 0x0578, 0x00000003
+NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL, 0x0580, 0x000001A4
+NV_SI_RO_BOARD_SX_PHY_CFG_SETTING, 0x0588, 0x00000000
+NV_SI_RO_BOARD_DDR_PHY_DC_CLK, 0x0590, 0x00018000
+NV_SI_RO_BOARD_DDR_PHY_DC_DATA, 0x0598, 0x80018000
+NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET, 0x05A0, 0x00000000
+NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET, 0x05A8, 0x00000000
+NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET, 0x05B0, 0x00000000
+NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET, 0x05B8, 0x00000000
+NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET, 0x05C0, 0x00000000
+NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET, 0x05C8, 0x00000000
+NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET, 0x05D0, 0x00000000
+NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET, 0x05D8, 0x00000000
+NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD, 0x05E0, 0x00550055
+NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US, 0x05E8, 0x00000064
+NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV, 0x05F0, 0x00000005
+NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN, 0x05F8, 0x00000001
+NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME, 0x0600, 0x00000002
+NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US, 0x0608, 0x00000005
+NV_SI_RO_BOARD_PCIE_AER_FW_FIRST, 0x0610, 0x00000000
+NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS, 0x0618, 0x00000000
+NV_SI_RO_BOARD_TPM_DISABLE, 0x0620, 0x00000000
+NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, 0x0628, 0x00000000
+NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, 0x0630, 0x00000000
+NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN, 0x0638, 0x00000000
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
new file mode 100755
index 000000000000..770aa9424eed
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
@@ -0,0 +1,45 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+/**
+ * Derived from edk2/ArmPlatformPkg/Library/ArmPlatformLibNull/AArch64/ArmPlatformHelper.S
+ **/
+
+#include <AsmMacroIoLibV8.h>
+#include <Library/ArmLib.h>
+
+ASM_FUNC(ArmPlatformPeiBootAction)
+  ret
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_FUNC(ArmPlatformGetPrimaryCoreMpId)
+  MOV32  (w0, FixedPcdGet32 (PcdArmPrimaryCore))
+  ret
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformIsPrimaryCore)
+  ldr   x0, =0x1
+  ret
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ASM_FUNC(ArmPlatformGetCorePosition)
+  and   x1, x0, #ARM_CORE_MASK
+  and   x0, x0, #ARM_CLUSTER_MASK
+  add   x0, x1, x0, LSR #7
+  ret
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni
new file mode 100644
index 000000000000..dac06405dd58
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni
@@ -0,0 +1,13 @@
+// /** @file
+// Instance of RNG (Random Number Generator) Library.
+//
+// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Instance of RNG Library"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "RngLib that uses Hardware RNG module from SMpro to generate random numbers."
-- 
2.17.1


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

* [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-05-26 10:23   ` [edk2-devel] " Nhi Pham
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
                   ` (32 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel; +Cc: Nhi Pham

Only read the Ethernet connection status at the initialization of SNP.

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 .../Drivers/UsbCdcNetDxe/SimpleNetwork.c             | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c b/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
index 05c31f4bad9e..e44898cbda47 100644
--- a/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
@@ -116,8 +116,6 @@ SnpGetStatus (
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;
 
-  DEBUG ((DEBUG_ERROR, "%a %d Entry \n", __FUNCTION__, __LINE__));
-
   if (SimpleNetwork == NULL || SimpleNetwork->Mode == NULL) {
     return EFI_INVALID_PARAMETER;
   }
@@ -154,16 +152,6 @@ SnpGetStatus (
     *InterruptStatus = 0;
   }
 
-  Status = UsbCdcGetLinkStatus (PrivateData);
-  if (EFI_ERROR (Status)) {
-    Mode->MediaPresent = FALSE;
-  } else {
-    Mode->MediaPresent = PrivateData->LinkUp;
-    DEBUG ((EFI_D_INFO, "%a %d Mode->MediaPresent = %d \n", __FUNCTION__, __LINE__, (UINT8)Mode->MediaPresent));
-  }
-
-  DEBUG ((DEBUG_ERROR, "%a %d End - %r \n", __FUNCTION__, __LINE__, Status));
-
   //
   // Restore TPL and return the operation status
   //
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
  2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:05   ` Leif Lindholm
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
                   ` (31 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

The MmCommunicationDxe module is derived from
ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf.

The MmCommunication PEI and DXE modules implement the MM Communication
protocol (EFI_MM_COMMUNICATION_PROTOCOL) as defined in the PI 1.5
specification for the interface between UEFI and MM services in the
secure world.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                |   3 +
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                            |   2 +
 Platform/Ampere/JadePkg/Jade.fdf                                                |   3 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf    |  57 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf |  34 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h        |  22 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c      | 454 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c   |  37 ++
 8 files changed, 612 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index f0a5bd04ec22..73097afaf841 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -38,5 +38,8 @@ [Guids]
   ## NVParam MM GUID
   gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
 
+  ## SPI NOR Proxy MM GUID
+  gSpiNorMmGuid                = { 0xC8D76438, 0x4D3C, 0x4BEA, { 0xBF, 0x86, 0x92, 0x6B, 0x83, 0x07, 0xA2, 0x39 } }
+
   ## Include/Guid/PlatformInfoHobGuid.h
   gPlatformHobGuid             = { 0x7f73e372, 0x7183, 0x4022, { 0xb3, 0x76, 0x78, 0x30, 0x32, 0x6d, 0x79, 0xb4 } }
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index af66c27822a3..0332473b59b0 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -517,6 +517,7 @@ [Components.common]
   ArmPlatformPkg/PlatformPei/PlatformPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
   ArmPkg/Drivers/CpuPei/CpuPei.inf
   UefiCpuPkg/CpuIoPei/CpuIoPei.inf
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
@@ -565,6 +566,7 @@ [Components.common]
   EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
   EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
   EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
 
   #
   # Environment Variables Protocol
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 8ed6df381aed..905289844378 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -101,6 +101,7 @@ [FV.FVMAIN_COMPACT]
   INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
   INF ArmPkg/Drivers/CpuPei/CpuPei.inf
   INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
   INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
@@ -141,6 +142,7 @@ [FV.FvMain]
   INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
   INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
   INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
 }
 
   INF MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -163,6 +165,7 @@ [FV.FvMain]
   INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
   INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
   INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
 
   #
   # Environment Variables Protocol
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
new file mode 100644
index 000000000000..3efff142944f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
@@ -0,0 +1,57 @@
+#/** @file
+#
+#  This module implements the MM Communication Protocol (EFI_MM_COMMUNICATION_PROTOCOL)
+#  as defined in the PI 1.5 specification.
+#
+#  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = ArmMmCommunication
+  FILE_GUID                      = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MmCommunicationInitialize
+
+#
+# The following is for reference only and not required by
+# build tools
+#
+# VALID_ARCHITECTURES            = AARCH64
+#
+
+[Sources.AARCH64]
+  MmCommunicate.h
+  MmCommunication.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  ArmLib
+  ArmSmcLib
+  BaseMemoryLib
+  DebugLib
+  DxeServicesTableLib
+  HobLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEfiMmCommunicationProtocolGuid              ## PRODUCES
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gEfiEventExitBootServicesGuid
+  gEfiEventReadyToBootGuid
+
+[Pcd.common]
+  gArmTokenSpaceGuid.PcdMmBufferBase
+  gArmTokenSpaceGuid.PcdMmBufferSize
+
+[Depex]
+  gEfiCpuArchProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
new file mode 100755
index 000000000000..3a985840a0a0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
@@ -0,0 +1,34 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = MmCommunicationPei
+  FILE_GUID                      = B5AE0F80-DF81-11EA-8B6E-0800200C9A66
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = MmCommunicationPeiEntryPoint
+
+[Sources]
+  MmCommunicationPei.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdePkg/MdePkg.dec
+
+[LibraryClasses]
+  HobLib
+  PcdLib
+  PeimEntryPoint
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdMmBufferBase
+  gArmTokenSpaceGuid.PcdMmBufferSize
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
new file mode 100644
index 000000000000..804ba58afb72
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
@@ -0,0 +1,22 @@
+/** @file
+
+  Copyright (c) 2016-2018, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MM_COMMUNICATE_H_
+#define MM_COMMUNICATE_H_
+
+#define MM_MAJOR_VER_MASK        0xEFFF0000
+#define MM_MINOR_VER_MASK        0x0000FFFF
+#define MM_MAJOR_VER_SHIFT       16
+
+#define MM_MAJOR_VER(x) (((x) & MM_MAJOR_VER_MASK) >> MM_MAJOR_VER_SHIFT)
+#define MM_MINOR_VER(x) ((x) & MM_MINOR_VER_MASK)
+
+#define MM_CALLER_MAJOR_VER      0x1UL
+#define MM_CALLER_MINOR_VER      0x0
+
+#endif /* MM_COMMUNICATE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
new file mode 100644
index 000000000000..271fc755548f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
@@ -0,0 +1,454 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC
+  Copyright (c) 2016-2018, ARM Limited. All rights reserved.
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/ArmStdSmc.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/MmCommunication.h>
+
+#include "MmCommunicate.h"
+
+#define MM_EARLY_MEM_ALLOCATE 1
+
+//
+// Address, Length of the pre-allocated buffer for communication with the secure
+// world.
+//
+STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
+
+// Notification event when virtual address map is set.
+STATIC EFI_EVENT mSetVirtualAddressMapEvent;
+
+//
+// Handle to install the MM Communication Protocol
+//
+STATIC EFI_HANDLE mMmCommunicateHandle;
+
+/**
+  Communicates with a registered handler.
+
+  This function provides an interface to send and receive messages to the
+  Standalone MM environment on behalf of UEFI services.  This function is part
+  of the MM Communication Protocol that may be called in physical mode prior to
+  SetVirtualAddressMap() and in virtual mode after SetVirtualAddressMap().
+
+  @param[in]      This                The EFI_MM_COMMUNICATION_PROTOCOL
+                                      instance.
+  @param[in, out] CommBuffer          A pointer to the buffer to convey
+                                      into MMRAM.
+  @param[in, out] CommSize            The size of the data buffer being
+                                      passed in. This is optional.
+
+  @retval EFI_SUCCESS                 The message was successfully posted.
+  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
+  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
+                                      implementation. If this error is
+                                      returned, the MessageLength field in
+                                      the CommBuffer header or the integer
+                                      pointed by CommSize are updated to reflect
+                                      the maximum payload size the
+                                      implementation can accommodate.
+  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
+                                      or CommSize parameter, if not omitted,
+                                      are in address range that cannot be
+                                      accessed by the MM environment
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+MmCommunicationCommunicate (
+  IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
+  IN OUT   VOID                          *CommBuffer,
+  IN OUT   UINTN                         *CommSize OPTIONAL
+  )
+{
+  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
+  ARM_SMC_ARGS              CommunicateSmcArgs;
+  EFI_STATUS                Status;
+  UINTN                     BufferSize;
+
+  Status = EFI_ACCESS_DENIED;
+  BufferSize = 0;
+
+  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
+
+  //
+  // Check parameters
+  //
+  if (CommBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CommunicateHeader = CommBuffer;
+  // CommBuffer is a mandatory parameter. Hence, rely on
+  // MessageLength + Header to ascertain the
+  // total size of the communication payload rather than
+  // relying on optional CommSize parameter
+  BufferSize = CommunicateHeader->MessageLength +
+               sizeof (CommunicateHeader->HeaderGuid) +
+               sizeof (CommunicateHeader->MessageLength);
+
+  // If the length of the CommBuffer is 0 then return the expected length.
+  if (CommSize != NULL) {
+    // This case can be used by the consumer of this driver to find out the
+    // max size that can be used for allocating CommBuffer.
+    if ((*CommSize == 0) ||
+        (*CommSize > mNsCommBuffMemRegion.Length))
+    {
+      *CommSize = mNsCommBuffMemRegion.Length;
+      return EFI_BAD_BUFFER_SIZE;
+    }
+    //
+    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
+    //
+    if (*CommSize != BufferSize) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  //
+  // If the buffer size is 0 or greater than what can be tolerated by the MM
+  // environment then return the expected size.
+  //
+  if ((BufferSize == 0) ||
+      (BufferSize > mNsCommBuffMemRegion.Length))
+  {
+    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
+                                       sizeof (CommunicateHeader->HeaderGuid) -
+                                       sizeof (CommunicateHeader->MessageLength);
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  // SMC Function ID
+  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
+
+  // Cookie
+  CommunicateSmcArgs.Arg1 = 0;
+
+  // Copy Communication Payload
+  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
+
+  // comm_buffer_address (64-bit physical address)
+  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
+
+  // comm_size_address (not used, indicated by setting to zero)
+  CommunicateSmcArgs.Arg3 = 0;
+
+  // Call the Standalone MM environment.
+  ArmCallSmc (&CommunicateSmcArgs);
+
+  switch (CommunicateSmcArgs.Arg0) {
+  case ARM_SMC_MM_RET_SUCCESS:
+    ZeroMem (CommBuffer, BufferSize);
+    // On successful return, the size of data being returned is inferred from
+    // MessageLength + Header.
+    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
+    BufferSize = CommunicateHeader->MessageLength +
+                 sizeof (CommunicateHeader->HeaderGuid) +
+                 sizeof (CommunicateHeader->MessageLength);
+
+    CopyMem (
+      CommBuffer,
+      (VOID *)mNsCommBuffMemRegion.VirtualBase,
+      BufferSize
+      );
+    Status = EFI_SUCCESS;
+    break;
+
+  case ARM_SMC_MM_RET_INVALID_PARAMS:
+    Status = EFI_INVALID_PARAMETER;
+    break;
+
+  case ARM_SMC_MM_RET_DENIED:
+    Status = EFI_ACCESS_DENIED;
+    break;
+
+  case ARM_SMC_MM_RET_NO_MEMORY:
+    // Unexpected error since the CommSize was checked for zero length
+    // prior to issuing the SMC
+    Status = EFI_OUT_OF_RESOURCES;
+    ASSERT (0);
+    break;
+
+  default:
+    Status = EFI_ACCESS_DENIED;
+    ASSERT (0);
+  }
+
+  return Status;
+}
+
+//
+// MM Communication Protocol instance
+//
+EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
+  MmCommunicationCommunicate
+};
+
+/**
+  Notification callback on SetVirtualAddressMap event.
+
+  This function notifies the MM communication protocol interface on
+  SetVirtualAddressMap event and converts pointers used in this driver
+  from physical to virtual address.
+
+  @param  Event          SetVirtualAddressMap event.
+  @param  Context        A context when the SetVirtualAddressMap triggered.
+
+  @retval EFI_SUCCESS    The function executed successfully.
+  @retval Other          Some error occurred when executing this function.
+
+**/
+STATIC
+VOID
+EFIAPI
+NotifySetVirtualAddressMap (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gRT->ConvertPointer (
+                  EFI_OPTIONAL_PTR,
+                  (VOID **)&mNsCommBuffMemRegion.VirtualBase
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Unable to convert MM runtime pointer. Status:0x%r\n",
+      __FUNCTION__,
+      Status
+      ));
+  }
+
+}
+
+STATIC
+EFI_STATUS
+GetMmCompatibility ()
+{
+  EFI_STATUS   Status;
+  UINT32       MmVersion;
+  ARM_SMC_ARGS MmVersionArgs;
+
+  // MM_VERSION uses SMC32 calling conventions
+  MmVersionArgs.Arg0 = ARM_SMC_ID_MM_VERSION_AARCH32;
+
+  ArmCallSmc (&MmVersionArgs);
+
+  MmVersion = MmVersionArgs.Arg0;
+
+  if ((MM_MAJOR_VER (MmVersion) == MM_CALLER_MAJOR_VER) &&
+      (MM_MINOR_VER (MmVersion) >= MM_CALLER_MINOR_VER))
+  {
+    DEBUG ((
+      DEBUG_INFO,
+      "MM Version: Major=0x%x, Minor=0x%x\n",
+      MM_MAJOR_VER (MmVersion),
+      MM_MINOR_VER (MmVersion)
+      ));
+    Status = EFI_SUCCESS;
+  } else {
+    DEBUG ((
+      DEBUG_ERROR,
+      "Incompatible MM Versions.\n Current Version: Major=0x%x, "
+      "Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
+      MM_MAJOR_VER (MmVersion),
+      MM_MINOR_VER (MmVersion),
+      MM_CALLER_MAJOR_VER,
+      MM_CALLER_MINOR_VER
+      ));
+    Status = EFI_UNSUPPORTED;
+  }
+
+  return Status;
+}
+
+STATIC EFI_GUID *CONST mGuidedEventGuid[] = {
+  &gEfiEndOfDxeEventGroupGuid,
+  &gEfiEventExitBootServicesGuid,
+  &gEfiEventReadyToBootGuid,
+};
+
+STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
+
+/**
+  Event notification that is fired when GUIDed Event Group is signaled.
+
+  @param  Event                 The Event that is being processed, not used.
+  @param  Context               Event Context, not used.
+
+**/
+STATIC
+VOID
+EFIAPI
+MmGuidedEventNotify (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_MM_COMMUNICATE_HEADER Header;
+  UINTN                     Size;
+
+  //
+  // Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure
+  //
+  CopyGuid (&Header.HeaderGuid, Context);
+  Header.MessageLength = 1;
+  Header.Data[0] = 0;
+
+  Size = sizeof (Header);
+  MmCommunicationCommunicate (&mMmCommunication, &Header, &Size);
+}
+
+/**
+  The Entry Point for MM Communication
+
+  This function installs the MM communication protocol interface and finds out
+  what type of buffer management will be required prior to invoking the
+  communication SMC.
+
+  @param  ImageHandle    The firmware allocated handle for the EFI image.
+  @param  SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS    The entry point is executed successfully.
+  @retval Other          Some error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  UINTN      Index;
+
+  // Check if we can make the MM call
+  Status = GetMmCompatibility ();
+  if (EFI_ERROR (Status)) {
+    goto ReturnErrorStatus;
+  }
+
+  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
+  // During boot, virtual and physical are same
+  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
+  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
+
+  ASSERT (mNsCommBuffMemRegion.PhysicalBase != 0);
+
+  ASSERT (mNsCommBuffMemRegion.Length != 0);
+
+#if !defined(MM_EARLY_MEM_ALLOCATE)
+  Status = gDS->AddMemorySpace (
+                  EfiGcdMemoryTypeReserved,
+                  mNsCommBuffMemRegion.PhysicalBase,
+                  mNsCommBuffMemRegion.Length,
+                  EFI_MEMORY_WB |
+                  EFI_MEMORY_XP |
+                  EFI_MEMORY_RUNTIME
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Failed to add MM-NS Buffer Memory Space\n",
+      __FUNCTION__
+      ));
+    goto ReturnErrorStatus;
+  }
+
+  Status = gDS->SetMemorySpaceAttributes (
+                  mNsCommBuffMemRegion.PhysicalBase,
+                  mNsCommBuffMemRegion.Length,
+                  EFI_MEMORY_WB | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Failed to set MM-NS Buffer Memory attributes\n",
+      __FUNCTION__
+      ));
+    goto CleanAddedMemorySpace;
+  }
+#endif
+
+  // Install the communication protocol
+  Status = gBS->InstallProtocolInterface (
+                  &mMmCommunicateHandle,
+                  &gEfiMmCommunicationProtocolGuid,
+                  EFI_NATIVE_INTERFACE,
+                  &mMmCommunication
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Failed to install MM communication protocol\n",
+      __FUNCTION__
+      ));
+    goto CleanAddedMemorySpace;
+  }
+
+  // Register notification callback when virtual address is associated
+  // with the physical address.
+  // Create a Set Virtual Address Map event.
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+                  TPL_NOTIFY,
+                  NotifySetVirtualAddressMap,
+                  NULL,
+                  &mSetVirtualAddressMapEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    MmGuidedEventNotify,
+                    mGuidedEventGuid[Index],
+                    mGuidedEventGuid[Index],
+                    &mGuidedEvent[Index]
+                    );
+    ASSERT_EFI_ERROR (Status);
+    if (EFI_ERROR (Status)) {
+      while (Index-- > 0) {
+        gBS->CloseEvent (mGuidedEvent[Index]);
+      }
+      goto UninstallProtocol;
+    }
+  }
+  return EFI_SUCCESS;
+
+UninstallProtocol:
+  gBS->UninstallProtocolInterface (
+         mMmCommunicateHandle,
+         &gEfiMmCommunicationProtocolGuid,
+         &mMmCommunication
+         );
+
+CleanAddedMemorySpace:
+#if !defined(MM_EARLY_MEM_ALLOCATE)
+  gDS->RemoveMemorySpace (
+         mNsCommBuffMemRegion.PhysicalBase,
+         mNsCommBuffMemRegion.Length
+         );
+#endif
+
+ReturnErrorStatus:
+  return EFI_INVALID_PARAMETER;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
new file mode 100644
index 000000000000..d3925015612f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
@@ -0,0 +1,37 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi/UefiSpec.h>
+
+#include <Library/HobLib.h>
+#include <Library/PeimEntryPoint.h>
+
+/**
+  Entry point function for the PEIM
+
+  @param FileHandle      Handle of the file being invoked.
+  @param PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS    If we installed our PPI
+
+**/
+EFI_STATUS
+EFIAPI
+MmCommunicationPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_PHYSICAL_ADDRESS MmBufferBase = PcdGet64 (PcdMmBufferBase);
+  UINT64               MmBufferSize = PcdGet64 (PcdMmBufferSize);
+
+  BuildMemoryAllocationHob (MmBufferBase, MmBufferSize, EfiRuntimeServicesData);
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (2 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:07   ` Leif Lindholm
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
                   ` (30 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

The Ampere Altra System Firmware provides a fail-safe feature to help
recover the system if there are setting changes such as Core voltage,
DRAM parameters that cause the UEFI failed to boot.

The FailSafeLib supports API calls to Secure World to:
* Get the FailSafe region information.
* Get the current FailSafe status.
* Inform to FailSafe monitor that the system boots successfully.
* Simulate UEFI boot failure due to config wrong NVPARAM for
  testing failsafe feature.

This library will be consumed by FailSafe DXE driver.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec               |   3 +
 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf |  41 +++
 Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h       |  62 ++++
 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c   | 320 ++++++++++++++++++++
 4 files changed, 426 insertions(+)

diff --git a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
index 7c1d1f84f780..6e33d96c7ea5 100755
--- a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
+++ b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
@@ -22,7 +22,10 @@ [Defines]
 #
 ################################################################################
 [Includes]
+  Include                        # Root include for the package
 
 [LibraryClasses]
+  ##  @libraryclass  Provides functions to support FailSafe operations.
+  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
 
 [Guids]
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
new file mode 100755
index 000000000000..456b9d5fc85b
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
@@ -0,0 +1,41 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FailSafeLib
+  FILE_GUID                      = 3403D080-6D76-11E7-907B-A6006AD3DBA0
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = FailSafeLib
+
+[Sources]
+  FailSafeLib.c
+
+[Protocols]
+  gEfiMmCommunicationProtocolGuid        ## CONSUMES
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  NVParamLib
+
+[Guids]
+  gSpiNorMmGuid
diff --git a/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
new file mode 100644
index 000000000000..7ebd1c8a74a2
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
@@ -0,0 +1,62 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FAILSAFE_LIB_H_
+#define FAILSAFE_LIB_H_
+
+enum {
+  MM_SPINOR_FUNC_GET_INFO,
+  MM_SPINOR_FUNC_READ,
+  MM_SPINOR_FUNC_WRITE,
+  MM_SPINOR_FUNC_ERASE,
+  MM_SPINOR_FUNC_GET_NVRAM_INFO,
+  MM_SPINOR_FUNC_GET_NVRAM2_INFO,
+  MM_SPINOR_FUNC_GET_FAILSAFE_INFO
+};
+
+#define MM_SPINOR_RES_SUCCESS           0xAABBCC00
+#define MM_SPINOR_RES_FAIL              0xAABBCCFF
+
+enum {
+  FAILSAFE_BOOT_NORMAL = 0,
+  FAILSAFE_BOOT_LAST_KNOWN_SETTINGS,
+  FAILSAFE_BOOT_DEFAULT_SETTINGS,
+  FAILSAFE_BOOT_DDR_DOWNGRADE,
+  FAILSAFE_BOOT_SUCCESSFUL
+};
+
+/**
+  Get the FailSafe region information.
+**/
+EFI_STATUS
+EFIAPI
+FailSafeGetRegionInfo (
+  UINT64 *Offset,
+  UINT64 *Size
+  );
+
+/**
+  Inform to FailSafe monitor that the system boots successfully.
+**/
+EFI_STATUS
+EFIAPI
+FailSafeBootSuccessfully (
+  VOID
+  );
+
+/**
+  Simulate UEFI boot failure due to config wrong NVPARAM for
+  testing failsafe feature
+**/
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (
+  VOID
+  );
+
+#endif /* FAILSAFE_LIB_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
new file mode 100644
index 000000000000..a567ab91375f
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
@@ -0,0 +1,320 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FailSafeLib.h>
+#include <Library/HobLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/MmCommunication.h>
+
+#define EFI_MM_MAX_PAYLOAD_U64_E  10
+#define EFI_MM_MAX_PAYLOAD_SIZE   (EFI_MM_MAX_PAYLOAD_U64_E * sizeof (UINT64))
+
+EFI_MM_COMMUNICATION_PROTOCOL *mFlashLibMmCommProtocol = NULL;
+
+typedef struct {
+  /* Allows for disambiguation of the message format */
+  EFI_GUID HeaderGuid;
+  /*
+   * Describes the size of Data (in bytes) and does not include the size
+   * of the header
+   */
+  UINTN MsgLength;
+} EFI_MM_COMM_HEADER_NOPAYLOAD;
+
+typedef struct {
+  UINT64 Data[EFI_MM_MAX_PAYLOAD_U64_E];
+} EFI_MM_COMM_SPINOR_PAYLOAD;
+
+typedef struct {
+  EFI_MM_COMM_HEADER_NOPAYLOAD EfiMmHdr;
+  EFI_MM_COMM_SPINOR_PAYLOAD   PayLoad;
+} EFI_MM_COMM_REQUEST;
+
+typedef struct {
+  UINT64 Status;
+} EFI_MM_COMMUNICATE_SPINOR_RES;
+
+typedef struct {
+  UINT64 Status;
+  UINT64 FailSafeBase;
+  UINT64 FailSafeSize;
+} EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES;
+
+EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
+
+#pragma pack(1)
+typedef struct {
+  UINT8  ImgMajorVer;
+  UINT8  ImgMinorVer;
+  UINT32 NumRetry1;
+  UINT32 NumRetry2;
+  UINT32 MaxRetry;
+  UINT8  Status;
+  /*
+   * Byte[3]: Reserved
+   * Byte[2]: Slave MCU Failure Mask
+   * Byte[1]: Reserved
+   * Byte[0]: Master MCU Failure Mask
+   */
+  UINT32 MCUFailsMask;
+  UINT16 CRC16;
+  UINT8  Reserved[3];
+} FAIL_SAFE_CONTEXT;
+
+#pragma pack()
+
+STATIC
+EFI_STATUS
+UefiMmCreateSpiNorReq (
+  VOID   *Data,
+  UINT64 Size
+  )
+{
+  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
+  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
+
+  if (Size != 0) {
+    ASSERT (Data);
+    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
+
+    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+INTN
+CheckCrc16 (
+  UINT8 *Pointer,
+  INTN  Count
+  )
+{
+  INTN Crc = 0;
+  INTN Index;
+
+  while (--Count >= 0) {
+    Crc = Crc ^ (INTN)*Pointer++ << 8;
+    for (Index = 0; Index < 8; ++Index) {
+      if ((Crc & 0x8000) != 0) {
+        Crc = Crc << 1 ^ 0x1021;
+      } else {
+        Crc = Crc << 1;
+      }
+    }
+  }
+
+  return Crc & 0xFFFF;
+}
+
+BOOLEAN
+FailSafeValidCRC (
+  FAIL_SAFE_CONTEXT *FailSafeBuf
+  )
+{
+  UINT8  Valid;
+  UINT16 Crc;
+  UINT32 Len;
+
+  Len = sizeof (FAIL_SAFE_CONTEXT);
+  Crc = FailSafeBuf->CRC16;
+  FailSafeBuf->CRC16 = 0;
+
+  Valid = (Crc == CheckCrc16 ((UINT8 *)FailSafeBuf, Len));
+  FailSafeBuf->CRC16 = Crc;
+
+  return Valid;
+}
+
+BOOLEAN
+FailSafeFailureStatus (
+  UINT8 Status
+  )
+{
+  if ((Status == FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) ||
+      (Status == FAILSAFE_BOOT_DEFAULT_SETTINGS) ||
+      (Status == FAILSAFE_BOOT_DDR_DOWNGRADE))
+  {
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeGetRegionInfo (
+  UINT64 *Offset,
+  UINT64 *Size
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *MmSpiNorFailSafeInfoRes;
+  UINT64                                      MmData[5];
+  UINTN                                       DataSize;
+  EFI_STATUS                                  Status;
+
+  if (mFlashLibMmCommProtocol == NULL) {
+    Status = gBS->LocateProtocol (
+                    &gEfiMmCommunicationProtocolGuid,
+                    NULL,
+                    (VOID **)&mFlashLibMmCommProtocol
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: Can't locate gEfiMmCommunicationProtocolGuid\n", __FUNCTION__));
+      return Status;
+    }
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_GET_FAILSAFE_INFO;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  DataSize = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &DataSize
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorFailSafeInfoRes = (EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorFailSafeInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Get flash information failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorFailSafeInfoRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  *Offset = MmSpiNorFailSafeInfoRes->FailSafeBase;
+  *Size   = MmSpiNorFailSafeInfoRes->FailSafeSize;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeBootSuccessfully (
+  VOID
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+  UINT64                        MmData[5];
+  UINTN                         Size;
+  EFI_STATUS                    Status;
+  UINT64                        FailSafeStartOffset;
+  UINT64                        FailSafeSize;
+  FAIL_SAFE_CONTEXT             FailSafeBuf;
+
+  Status = FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_READ;
+  MmData[1] = FailSafeStartOffset;
+  MmData[2] = (UINT64)sizeof (FAIL_SAFE_CONTEXT);
+  MmData[3] = (UINT64)&FailSafeBuf;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &Size
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Read context failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  /*
+   * If failsafe context is invalid, it is already indicate a successful boot
+   * and don't need to be cleared
+   */
+  if (!FailSafeValidCRC (&FailSafeBuf)) {
+    return EFI_SUCCESS;
+  }
+
+  /*
+   * If failsafe context is valid, and:
+   *    - The status indicate non-failure, then don't clear it
+   *    - The status indicate a failure, then go and clear it
+   */
+  if (!FailSafeFailureStatus (FailSafeBuf.Status)) {
+    return EFI_SUCCESS;
+  }
+
+  MmData[0] = MM_SPINOR_FUNC_ERASE;
+  MmData[1] = FailSafeStartOffset;
+  MmData[2] = FailSafeSize;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = mFlashLibMmCommProtocol->Communicate (
+                                      mFlashLibMmCommProtocol,
+                                      (VOID *)&mEfiMmSpiNorReq,
+                                      &Size
+                                      );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a: Erase context failed: 0x%llx\n",
+      __FUNCTION__,
+      MmSpiNorRes->Status
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value = 0;
+
+  /*
+   * Simulate UEFI boot failure due to config wrong NVPARAM for
+   * testing failsafe feature
+   */
+  Status = NVParamGet (NV_UEFI_FAILURE_FAILSAFE_OFFSET, NV_PERM_ALL, &Value);
+  if (!EFI_ERROR (Status) && (Value == 1)) {
+    while (1) {
+    }
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (3 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:12   ` Leif Lindholm
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
                   ` (29 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

The FailSafeDxe driver reverts the system's configuration to known good
values if the system fails to boot up multiple times. It also implements
the Watchdog Timer Architectural Protocol to reset the system if it
hangs.

By default, when system starts, it configures the secure watchdog timer
with a default value of 5 minutes. If the system boots up cleanly to the
considered good stage, the counter is cleared as it indicates FailSafe
monitor (ATF) that has booted up successfully. If the timer expires, it
is considered a failed boot and system is rebooted.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                  |   1 -
 Platform/Ampere/JadePkg/Jade.dsc                                      |   9 +
 Platform/Ampere/JadePkg/Jade.fdf                                      |   6 +-
 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf |  54 +++
 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h      |  20 ++
 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h      |  29 ++
 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c   | 184 ++++++++++
 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c      | 357 ++++++++++++++++++++
 8 files changed, 658 insertions(+), 2 deletions(-)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 0332473b59b0..6a6f72e995af 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -585,7 +585,6 @@ [Components.common]
   # Timer
   #
   ArmPkg/Drivers/TimerDxe/TimerDxe.inf
-  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
 
   #
   # ARM GIC Dxe
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index f68af24a0d78..f92855af99ab 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -75,6 +75,11 @@ [LibraryClasses]
   #
   RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
 
+  #
+  # Library for FailSafe support
+  #
+  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
+
 ################################################################################
 #
 # Specific Platform Pcds
@@ -98,3 +103,7 @@ [PcdsFixedAtBuild.common]
 #
 ################################################################################
 [Components.common]
+  #
+  # FailSafe and Watchdog Timer
+  #
+  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 905289844378..80a86d7c1156 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -185,7 +185,11 @@ [FV.FvMain]
   # Timer
   #
   INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
-  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+
+  #
+  # FailSafe and Watchdog Timer
+  #
+  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
 
   #
   # ARM GIC Dxe
diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
new file mode 100755
index 000000000000..60de10c95c85
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
@@ -0,0 +1,54 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FailSafeDxe
+  FILE_GUID                      = 7BC4F970-B1CF-11E6-80F5-76304DEC7EB7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FailSafeDxeEntryPoint
+
+[Sources]
+  FailSafe.h
+  FailSafeDxe.c
+  Watchdog.c
+  Watchdog.h
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  DebugLib
+  FailSafeLib
+  NVParamLib
+  PcdLib
+  TimerLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
+
+[Protocols]
+  gEfiWatchdogTimerArchProtocolGuid             ## PRODUCES
+  gHardwareInterrupt2ProtocolGuid               ## CONSUMES
+
+[Depex]
+  gHardwareInterrupt2ProtocolGuid
diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
new file mode 100644
index 000000000000..8bf3a98f1d8e
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
@@ -0,0 +1,20 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FAILSAFE_H_
+#define FAILSAFE_H_
+
+#include <Uefi.h>
+
+BOOLEAN
+EFIAPI
+IsFailSafeOff (
+  VOID
+  );
+
+#endif /* FAILSAFE_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
new file mode 100755
index 000000000000..6c9106fdbea5
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
@@ -0,0 +1,29 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef GENERIC_WATCHDOG_H_
+#define GENERIC_WATCHDOG_H_
+
+#include <Protocol/WatchdogTimer.h>
+
+/* The number of 100ns periods (the unit of time passed to these functions)
+   in a second */
+#define TIME_UNITS_PER_SECOND           10000000
+
+/**
+  The function to install Watchdog timer protocol to the system
+
+  @retval  Return         EFI_SUCCESS if install Watchdog timer protocol successfully.
+ **/
+EFI_STATUS
+EFIAPI
+WatchdogTimerInstallProtocol (
+  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
+  );
+
+#endif /* GENERIC_WATCHDOG_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
new file mode 100644
index 000000000000..1b8978b12ea7
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
@@ -0,0 +1,184 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FailSafeLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include "FailSafe.h"
+#include "Watchdog.h"
+
+STATIC UINTN                            gWatchdogOSTimeout;
+STATIC BOOLEAN                          gFailSafeOff;
+STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer;
+
+EFI_STATUS
+EFIAPI
+FailSafeTestBootFailure (
+  VOID
+  );
+
+STATIC VOID
+FailSafeTurnOff (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  if (IsFailSafeOff ()) {
+    return;
+  }
+
+  Status = FailSafeBootSuccessfully ();
+  ASSERT_EFI_ERROR (Status);
+
+  gFailSafeOff = TRUE;
+
+  /* Disable Watchdog timer */
+  gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
+}
+
+BOOLEAN
+EFIAPI
+IsFailSafeOff (
+  VOID
+  )
+{
+  return gFailSafeOff;
+}
+
+/**
+  The function to disable Watchdog timer when enter Setup screen
+ **/
+VOID
+WdtTimerEnterSetupScreenCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  /* Make sure FailSafe is turned off */
+  FailSafeTurnOff ();
+}
+
+/**
+  The function to refresh Watchdog timer in the event before booting
+ **/
+VOID
+WdtTimerBeforeBootCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  /*
+   * At this point, the system is considered boot successfully to BIOS
+   */
+  FailSafeTurnOff ();
+
+  /*
+   * It is BIOS's responsibility to setup Watchdog when load an EFI application
+   * after this step
+   */
+}
+
+/**
+  The function to refresh Watchdog timer in the event before exiting boot services
+ **/
+VOID
+WdtTimerExitBootServiceCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+
+  /* Enable Watchdog timer for OS booting */
+  if (gWatchdogOSTimeout != 0) {
+    gWatchdogTimer->SetTimerPeriod (
+                      gWatchdogTimer,
+                      gWatchdogOSTimeout * TIME_UNITS_PER_SECOND
+                      );
+  } else {
+    /* Disable Watchdog timer */
+    gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
+  }
+}
+
+/**
+  This function is a hook called when user loads the manufacturing
+  or optimal defaults.
+
+  @param Defaults : (NVRAM_VARIABLE *)optimal or manufacturing
+  @Data           : Messagebox
+
+  @retval VOID
+**/
+VOID
+LoadNVRAMDefaultConfig (
+  IN VOID  *Defaults,
+  IN UINTN Data
+  )
+{
+  NVParamClrAll ();
+}
+
+/**
+  Main entry for this driver.
+
+  @param ImageHandle     Image handle this driver.
+  @param SystemTable     Pointer to SystemTable.
+
+  @retval EFI_SUCESS     This function always complete successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+FailSafeDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_EVENT  ExitBootServicesEvent;
+  EFI_STATUS Status;
+
+  gFailSafeOff = FALSE;
+
+  FailSafeTestBootFailure ();
+
+  /* We need to setup non secure Watchdog to ensure that the system will
+   * boot to OS successfully.
+   *
+   * The BIOS doesn't handle Watchdog interrupt so we expect WS1 asserted EL3
+   * when Watchdog timeout triggered
+   */
+
+  Status = WatchdogTimerInstallProtocol (&gWatchdogTimer);
+  ASSERT_EFI_ERROR (Status);
+
+  // FIXME: We should register a callback function before entering to Setup screen
+  // rather than always call it at DXE phase.
+  FailSafeTurnOff ();
+
+  /* Register event before exit boot services */
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
+                  TPL_NOTIFY,
+                  WdtTimerExitBootServiceCallback,
+                  NULL,
+                  &ExitBootServicesEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
new file mode 100644
index 000000000000..34329d04206a
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
@@ -0,0 +1,357 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/HardwareInterrupt2.h>
+
+#include "FailSafe.h"
+#include "Watchdog.h"
+
+/* Watchdog timer controller registers */
+#define WDT_CTRL_BASE_REG                     FixedPcdGet64 (PcdGenericWatchdogControlBase)
+#define WDT_CTRL_WCS_OFF                      0x0
+#define WDT_CTRL_WCS_ENABLE_MASK              0x1
+#define WDT_CTRL_WOR_OFF                      0x8
+#define WDT_CTRL_WCV_OFF                      0x10
+#define WS0_INTERRUPT_SOURCE                  FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum)
+
+STATIC UINT64                           mNumTimerTicks;
+STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
+BOOLEAN                                 mInterruptWS0Enabled;
+
+STATIC
+VOID
+WatchdogTimerWriteOffsetRegister (
+  UINT32 Value
+  )
+{
+  MmioWrite32 (WDT_CTRL_BASE_REG + WDT_CTRL_WOR_OFF, Value);
+}
+
+STATIC
+VOID
+WatchdogTimerWriteCompareRegister (
+  UINT64 Value
+  )
+{
+  MmioWrite64 (WDT_CTRL_BASE_REG + WDT_CTRL_WCV_OFF, Value);
+}
+
+STATIC
+EFI_STATUS
+WatchdogTimerEnable (
+  IN BOOLEAN Enable
+  )
+{
+  UINT32 Val =  MmioRead32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF));
+
+  if (Enable) {
+    Val |= WDT_CTRL_WCS_ENABLE_MASK;
+  } else {
+    Val &= ~WDT_CTRL_WCS_ENABLE_MASK;
+  }
+  MmioWrite32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF), Val);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+WatchdogTimerSetup (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  /* Disable Watchdog timer */
+  WatchdogTimerEnable (FALSE);
+
+  if (!mInterruptWS0Enabled) {
+    Status = mInterruptProtocol->EnableInterruptSource (
+                                   mInterruptProtocol,
+                                   WS0_INTERRUPT_SOURCE
+                                   );
+    ASSERT_EFI_ERROR (Status);
+
+    mInterruptWS0Enabled = TRUE;
+  }
+
+  if (mNumTimerTicks == 0) {
+    return EFI_SUCCESS;
+  }
+
+  /* If the number of required ticks is greater than the max the Watchdog's
+     offset register (WOR) can hold, we need to manually compute and set
+     the compare register (WCV) */
+  if (mNumTimerTicks > MAX_UINT32) {
+    /* We need to enable the Watchdog *before* writing to the compare register,
+       because enabling the Watchdog causes an "explicit refresh", which
+       clobbers the compare register (WCV). In order to make sure this doesn't
+       trigger an interrupt, set the offset to max. */
+    WatchdogTimerWriteOffsetRegister (MAX_UINT32);
+    WatchdogTimerEnable (TRUE);
+    WatchdogTimerWriteCompareRegister (ArmGenericTimerGetSystemCount () + mNumTimerTicks);
+  } else {
+    WatchdogTimerWriteOffsetRegister ((UINT32)mNumTimerTicks);
+    WatchdogTimerEnable (TRUE);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/* This function is called when the Watchdog's first signal (WS0) goes high.
+   It uses the ResetSystem Runtime Service to reset the board.
+*/
+VOID
+EFIAPI
+WatchdogTimerInterruptHandler (
+  IN HARDWARE_INTERRUPT_SOURCE Source,
+  IN EFI_SYSTEM_CONTEXT        SystemContext
+  )
+{
+  STATIC CONST CHAR16 ResetString[]= L"The generic Watchdog timer ran out.";
+
+  mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
+
+  if (!IsFailSafeOff ()) {
+    /* Not handling interrupt as ATF is monitoring it */
+    return;
+  }
+
+  WatchdogTimerEnable (FALSE);
+
+  gRT->ResetSystem (
+         EfiResetCold,
+         EFI_TIMEOUT,
+         StrSize (ResetString),
+         (VOID *)&ResetString
+         );
+
+  /* If we got here then the reset didn't work */
+  ASSERT (FALSE);
+}
+
+/**
+  This function registers the handler NotifyFunction so it is called every time
+  the Watchdog timer expires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.
+  If NotifyFunction is not NULL and a handler is not already registered,
+  then the new handler is registered and EFI_SUCCESS is returned.
+  If NotifyFunction is NULL, and a handler is already registered,
+  then that handler is unregistered.
+  If an attempt is made to register a handler when a handler is already
+  registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not
+  registered, then EFI_INVALID_PARAMETER is returned.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  NotifyFunction   The function to call when a timer interrupt fires.
+                           This function executes at TPL_HIGH_LEVEL. The DXE
+                           Core will register a handler for the timer interrupt,
+                           so it can know how much time has passed. This
+                           information is used to signal timer based events.
+                           NULL will unregister the handler.
+
+  @retval EFI_UNSUPPORTED       The code does not support NotifyFunction.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogTimerRegisterHandler (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+  IN       EFI_WATCHDOG_TIMER_NOTIFY        NotifyFunction
+  )
+{
+  /* Not support. Watchdog will reset the board */
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This function sets the amount of time to wait before firing the Watchdog
+  timer to TimerPeriod 100ns units.  If TimerPeriod is 0, then the Watchdog
+  timer is disabled.
+
+  @param  This             The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      The amount of time in 100ns units to wait before
+                           the Watchdog timer is fired. If TimerPeriod is zero,
+                           then the Watchdog timer is disabled.
+
+  @retval EFI_SUCCESS           The Watchdog timer has been programmed to fire
+                                in Time  100ns units.
+  @retval EFI_DEVICE_ERROR      A Watchdog timer could not be programmed due
+                                to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogTimerSetPeriod (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+  IN       UINT64                           TimerPeriod   // In 100ns units
+  )
+{
+  mNumTimerTicks  = (ArmGenericTimerGetTimerFreq () * TimerPeriod) / TIME_UNITS_PER_SECOND;
+
+  if (!IsFailSafeOff ()) {
+    /* Not support Watchdog timer service until FailSafe is off as ATF is monitoring it */
+    return EFI_SUCCESS;
+  }
+
+  return WatchdogTimerSetup ();
+}
+
+/**
+  This function retrieves the period of timer interrupts in 100ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      A pointer to the timer period to retrieve in
+                           100ns units. If 0 is returned, then the timer is
+                           currently disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogTimerGetPeriod (
+  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
+  OUT      UINT64                           *TimerPeriod
+  )
+{
+  if (TimerPeriod == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerPeriod = ((TIME_UNITS_PER_SECOND / ArmGenericTimerGetTimerFreq ()) * mNumTimerTicks);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Interface structure for the Watchdog Architectural Protocol.
+
+  @par Protocol Description:
+  This protocol provides a service to set the amount of time to wait
+  before firing the Watchdog timer, and it also provides a service to
+  register a handler that is invoked when the Watchdog timer fires.
+
+  @par When the Watchdog timer fires, control will be passed to a handler
+  if one has been registered.  If no handler has been registered,
+  or the registered handler returns, then the system will be
+  reset by calling the Runtime Service ResetSystem().
+
+  @param RegisterHandler
+  Registers a handler that will be called each time the
+  Watchdogtimer interrupt fires.  TimerPeriod defines the minimum
+  time between timer interrupts, so TimerPeriod will also
+  be the minimum time between calls to the registered
+  handler.
+  NOTE: If the Watchdog resets the system in hardware, then
+        this function will not have any chance of executing.
+
+  @param SetTimerPeriod
+  Sets the period of the timer interrupt in 100ns units.
+  This function is optional, and may return EFI_UNSUPPORTED.
+  If this function is supported, then the timer period will
+  be rounded up to the nearest supported timer period.
+
+  @param GetTimerPeriod
+  Retrieves the period of the timer interrupt in 100ns units.
+
+**/
+STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
+  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER)WatchdogTimerRegisterHandler,
+  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)WatchdogTimerSetPeriod,
+  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)WatchdogTimerGetPeriod
+};
+
+EFI_STATUS
+EFIAPI
+WatchdogTimerInstallProtocol (
+  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE Handle;
+  EFI_TPL    CurrentTpl;
+
+  /* Make sure the Watchdog Timer Architectural Protocol has not been installed
+     in the system yet.
+     This will avoid conflicts with the universal Watchdog */
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
+
+  ASSERT (ArmGenericTimerGetTimerFreq () != 0);
+
+  /* Install interrupt handler */
+  Status = gBS->LocateProtocol (
+                  &gHardwareInterrupt2ProtocolGuid,
+                  NULL,
+                  (VOID **)&mInterruptProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  /*
+   * We don't want to be interrupted while registering Watchdog interrupt source as the interrupt
+   * may be trigger in the middle because the interrupt line already enabled in the EL3.
+   */
+  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  Status = mInterruptProtocol->RegisterInterruptSource (
+                                 mInterruptProtocol,
+                                 WS0_INTERRUPT_SOURCE,
+                                 WatchdogTimerInterruptHandler
+                                 );
+  ASSERT_EFI_ERROR (Status);
+
+  /* Don't enable interrupt until FailSafe off */
+  mInterruptWS0Enabled = FALSE;
+  Status = mInterruptProtocol->DisableInterruptSource (
+                                 mInterruptProtocol,
+                                 WS0_INTERRUPT_SOURCE
+                                 );
+  ASSERT_EFI_ERROR (Status);
+
+  gBS->RestoreTPL (CurrentTpl);
+
+  Status = mInterruptProtocol->SetTriggerType (
+                                 mInterruptProtocol,
+                                 WS0_INTERRUPT_SOURCE,
+                                 EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH
+                                 );
+  ASSERT_EFI_ERROR (Status);
+
+  /* Install the Timer Architectural Protocol onto a new handle */
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiWatchdogTimerArchProtocolGuid,
+                  &gWatchdogTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mNumTimerTicks = 0;
+
+  if (WatchdogTimerProtocol != NULL) {
+    *WatchdogTimerProtocol = &gWatchdogTimer;
+  }
+
+  return Status;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (4 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:21   ` Leif Lindholm
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
                   ` (28 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

The DwI2cLib library provides basic functions to control the I2C
controller on Ampere Altra processor.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec            |   3 +
 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf |  38 +
 Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h      | 100 +++
 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c   | 883 ++++++++++++++++++++
 4 files changed, 1024 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 73097afaf841..8be6a329bb26 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -28,6 +28,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to communicate with SCP.
   SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
 
+  ##  @libraryclass  Defines a set of methods to read/write to I2C devices.
+  I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
+
   ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
   MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
 
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
new file mode 100644
index 000000000000..091f5f9b310c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
@@ -0,0 +1,38 @@
+## @file
+# Component description for DwI2cLib library for the Designware I2C controller.
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = DwI2cLib
+  FILE_GUID                      = 222609E2-C181-11E6-A4A6-CEC0C932CE01
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2cLib
+  CONSTRUCTOR                    = I2cLibConstructor
+
+[Sources]
+  DwI2cLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  IoLib
+  TimerLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+  gPlatformHobGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
new file mode 100644
index 000000000000..f13794171029
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
@@ -0,0 +1,100 @@
+/** @file
+  Library implementation for the Designware I2C controller.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef I2C_LIB_H_
+#define I2C_LIB_H_
+
+#include <Uefi/UefiBaseType.h>
+
+/**
+  Write to I2C bus.
+
+  @param[in]     Bus          I2C bus Id.
+  @param[in]     SlaveAddr    The address of slave device on the bus.
+  @param[in,out] Buf          Buffer that holds data to write.
+  @param[in,out] WriteLength  Pointer to length of buffer.
+
+  @return EFI_SUCCESS            Write successfully.
+  @return EFI_INVALID_PARAMETER  A parameter is invalid.
+  @return EFI_UNSUPPORTED        The bus is not supported.
+  @return EFI_NOT_READY          The device/bus is not ready.
+  @return EFI_TIMEOUT            Timeout why transferring data.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWrite (
+  IN     UINT32 Bus,
+  IN     UINT32 SlaveAddr,
+  IN OUT UINT8  *Buf,
+  IN OUT UINT32 *WriteLength
+  );
+
+/**
+  Read data from I2C bus.
+
+  @param[in]     Bus          I2C bus Id.
+  @param[in]     SlaveAddr    The address of slave device on the bus.
+  @param[in]     BufCmd       Buffer where to send the command.
+  @param[in]     CmdLength    Pointer to length of BufCmd.
+  @param[in,out] Buf          Buffer where to put the read data to.
+  @param[in,out] ReadLength   Pointer to length of buffer.
+
+  @return EFI_SUCCESS            Read successfully.
+  @return EFI_INVALID_PARAMETER  A parameter is invalid.
+  @return EFI_UNSUPPORTED        The bus is not supported.
+  @return EFI_NOT_READY          The device/bus is not ready.
+  @return EFI_TIMEOUT            Timeout why transferring data.
+  @return EFI_CRC_ERROR          There are errors on receiving data.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cRead (
+  IN     UINT32 Bus,
+  IN     UINT32 SlaveAddr,
+  IN     UINT8  *BufCmd,
+  IN     UINT32 CmdLength,
+  IN OUT UINT8  *Buf,
+  IN OUT UINT32 *ReadLength
+  );
+
+/**
+ Setup new transaction with I2C slave device.
+
+  @param[in] Bus      I2C bus Id.
+  @param[in] BusSpeed I2C bus speed in Hz.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cProbe (
+  IN UINT32 Bus,
+  IN UINTN  BusSpeed
+  );
+
+/**
+ Setup a bus that to be used in runtime service.
+
+  @param[in] Bus I2C bus Id.
+
+  @retval EFI_SUCCESS  Success.
+  @retval Otherwise    Error code.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cSetupRuntime (
+  IN UINT32 Bus
+  );
+
+#endif /* I2C_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
new file mode 100644
index 000000000000..5e7cd020223c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
@@ -0,0 +1,883 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/HobLib.h>
+#include <Library/I2cLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <PlatformInfoHob.h>
+
+#define I2cSync() { asm volatile ("dmb ish" : : : "memory"); }
+
+//
+// Runtime needs to be 64K alignment
+//
+#define RUNTIME_ADDRESS_MASK           (~(SIZE_64KB - 1))
+#define RUNTIME_ADDRESS_LENGTH         SIZE_64KB
+
+//
+// Private I2C bus data
+//
+typedef struct {
+  UINTN  Base;
+  UINT32 BusSpeed;
+  UINT32 RxFifo;
+  UINT32 TxFifo;
+  UINT32 PollingTime;
+  UINT32 Enabled;
+} DW_I2C_CONTEXT_T;
+
+//
+// I2C SCL counter macros
+//
+typedef enum {
+  I2cSpeedModeStandard = 0,
+  I2cSpeedModeFast,
+} I2C_SPEED_MODE;
+
+#define DW_I2C_MAXIMUM_SPEED_HZ 400000
+
+typedef enum {
+  I2cSclSpkLen = 0,
+  I2cSclHcnt,
+  I2cSclLcnt,
+} I2C_SCL_PARAM;
+
+STATIC UINT32 I2cSclParam[][3] = {
+  /* SPK_LEN, HCNT, LCNT */
+  [I2cSpeedModeStandard]   = { 10, 0x3E2, 0x47D }, // SS (Standard Speed)
+  [I2cSpeedModeFast]       = { 10, 0xA4,  0x13F }, // FS (Fast Speed)
+};
+
+STATIC BOOLEAN          mI2cRuntimeEnableArray[MAX_PLATFORM_I2C_BUS_NUM] = {FALSE};
+STATIC UINTN            mI2cBaseArray[MAX_PLATFORM_I2C_BUS_NUM] = {PLATFORM_I2C_REGISTER_BASE};
+STATIC DW_I2C_CONTEXT_T mI2cBusList[MAX_PLATFORM_I2C_BUS_NUM];
+STATIC UINTN            mI2cClock = 0;
+STATIC EFI_EVENT        mVirtualAddressChangeEvent = NULL;
+
+//
+// Registers
+//
+#define DW_IC_CON                       0x0
+#define DW_IC_CON_MASTER                BIT0
+#define DW_IC_CON_SPEED_STD             BIT1
+#define DW_IC_CON_SPEED_FAST            BIT2
+#define DW_IC_CON_10BITADDR_MASTER      BIT4
+#define DW_IC_CON_RESTART_EN            BIT5
+#define DW_IC_CON_SLAVE_DISABLE         BIT6
+#define DW_IC_TAR                       0x4
+#define DW_IC_TAR_10BITS                BIT12
+#define DW_IC_SAR                       0x8
+#define DW_IC_DATA_CMD                  0x10
+#define DW_IC_DATA_CMD_RESTART          BIT10
+#define DW_IC_DATA_CMD_STOP             BIT9
+#define DW_IC_DATA_CMD_CMD              BIT8
+#define DW_IC_DATA_CMD_DAT_MASK         0xFF
+#define DW_IC_SS_SCL_HCNT               0x14
+#define DW_IC_SS_SCL_LCNT               0x18
+#define DW_IC_FS_SCL_HCNT               0x1c
+#define DW_IC_FS_SCL_LCNT               0x20
+#define DW_IC_HS_SCL_HCNT               0x24
+#define DW_IC_HS_SCL_LCNT               0x28
+#define DW_IC_INTR_STAT                 0x2c
+#define DW_IC_INTR_MASK                 0x30
+#define DW_IC_INTR_RX_UNDER             BIT0
+#define DW_IC_INTR_RX_OVER              BIT1
+#define DW_IC_INTR_RX_FULL              BIT2
+#define DW_IC_INTR_TX_EMPTY             BIT4
+#define DW_IC_INTR_TX_ABRT              BIT6
+#define DW_IC_INTR_ACTIVITY             BIT8
+#define DW_IC_INTR_STOP_DET             BIT9
+#define DW_IC_INTR_START_DET            BIT10
+#define DW_IC_ERR_CONDITION \
+                (DW_IC_INTR_RX_UNDER | DW_IC_INTR_RX_OVER | DW_IC_INTR_TX_ABRT)
+#define DW_IC_RAW_INTR_STAT             0x34
+#define DW_IC_CLR_INTR                  0x40
+#define DW_IC_CLR_RX_UNDER              0x44
+#define DW_IC_CLR_RX_OVER               0x48
+#define DW_IC_CLR_TX_ABRT               0x54
+#define DW_IC_CLR_ACTIVITY              0x5c
+#define DW_IC_CLR_STOP_DET              0x60
+#define DW_IC_CLR_START_DET             0x64
+#define DW_IC_ENABLE                    0x6c
+#define DW_IC_STATUS                    0x70
+#define DW_IC_STATUS_ACTIVITY           BIT0
+#define DW_IC_STATUS_TFE                BIT2
+#define DW_IC_STATUS_RFNE               BIT3
+#define DW_IC_STATUS_MST_ACTIVITY       BIT5
+#define DW_IC_TXFLR                     0x74
+#define DW_IC_RXFLR                     0x78
+#define DW_IC_SDA_HOLD                  0x7c
+#define DW_IC_TX_ABRT_SOURCE            0x80
+#define DW_IC_ENABLE_STATUS             0x9c
+#define DW_IC_COMP_PARAM_1              0xf4
+#define  DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) \
+           ((((x) >> 8) & 0xFF) + 1)
+#define  DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) \
+           ((((x) >> 16) & 0xFF) + 1)
+#define DW_IC_COMP_TYPE                 0xfc
+#define SB_DW_IC_CON                    0xa8
+#define SB_DW_IC_SCL_TMO_CNT            0xac
+#define SB_DW_IC_RX_PEC                 0xb0
+#define SB_DW_IC_ACK                    0xb4
+#define SB_DW_IC_FLG                    0xb8
+#define SB_DW_IC_FLG_CLR                0xbc
+#define SB_DW_IC_INTR_STAT              0xc0
+#define SB_DW_IC_INTR_STAT_MASK         0xc4
+#define SB_DW_IC_DEBUG_SEL              0xec
+#define SB_DW_IC_ACK_DEBUG              0xf0
+#define DW_IC_FS_SPKLEN                 0xa0
+#define DW_IC_HS_SPKLEN                 0xa4
+
+//
+// Timeout interval
+//
+// The interval is equal to the 10 times the signaling period
+// for the highest I2C transfer speed used in the system.
+//
+#define DW_POLL_INTERVAL_US(x) (10 * (1000000 / (x)))
+
+//
+// Maximum timeout count
+//
+#define DW_MAX_TRANSFER_POLL_COUNT 100000 // Maximum timeout: 10s
+#define DW_MAX_STATUS_POLL_COUNT   100
+
+#define DW_POLL_MST_ACTIVITY_INTERVAL_US 1000 // 1ms
+#define DW_MAX_MST_ACTIVITY_POLL_COUNT   20
+
+/**
+ Initialize I2C Bus
+ **/
+VOID
+I2cHWInit (
+  UINT32 Bus
+  )
+{
+  UINT32 Param;
+
+  mI2cBusList[Bus].Base = mI2cBaseArray[Bus];
+
+  Param = MmioRead32 (mI2cBusList[Bus].Base + DW_IC_COMP_PARAM_1);
+
+  mI2cBusList[Bus].PollingTime = DW_POLL_INTERVAL_US (mI2cBusList[Bus].BusSpeed);
+  mI2cBusList[Bus].RxFifo = DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH (Param);
+  mI2cBusList[Bus].TxFifo = DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH (Param);
+  mI2cBusList[Bus].Enabled = 0;
+
+  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d, Rx_Buffer %d, Tx_Buffer %d\n",
+    __FUNCTION__,
+    Bus,
+    mI2cBusList[Bus].RxFifo,
+    mI2cBusList[Bus].TxFifo
+    ));
+}
+
+/**
+ Enable or disable I2C Bus
+ */
+VOID
+I2cEnable (
+  UINT32 Bus,
+  UINT32 Enable
+  )
+{
+  UINT32 I2cStatusCnt;
+  UINTN  Base;
+
+  Base = mI2cBusList[Bus].Base;
+  I2cStatusCnt = DW_MAX_STATUS_POLL_COUNT;
+  mI2cBusList[Bus].Enabled = Enable;
+
+  MmioWrite32 (Base + DW_IC_ENABLE, Enable);
+
+  do {
+    if ((MmioRead32 (Base + DW_IC_ENABLE_STATUS) & 0x01) == Enable) {
+      break;
+    }
+    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
+  } while (I2cStatusCnt-- != 0);
+
+  if (I2cStatusCnt == 0) {
+    DEBUG ((DEBUG_ERROR, "%a: Enable/disable timeout\n", __FUNCTION__));
+  }
+
+  if ((Enable == 0) || (I2cStatusCnt == 0)) {
+    /* Unset the target adddress */
+    MmioWrite32 (Base + DW_IC_TAR, 0);
+    mI2cBusList[Bus].Enabled = 0;
+  }
+}
+
+/**
+ Setup Slave address
+ **/
+VOID
+I2cSetSlaveAddr (
+  UINT32 Bus,
+  UINT32 SlaveAddr
+  )
+{
+  UINTN  Base;
+  UINT32 OldEnableStatus;
+
+  Base = mI2cBusList[Bus].Base;
+  OldEnableStatus = mI2cBusList[Bus].Enabled;
+
+  I2cEnable (Bus, 0);
+  MmioWrite32 (Base + DW_IC_TAR, SlaveAddr);
+  if (OldEnableStatus != 0) {
+    I2cEnable (Bus, 1);
+  }
+}
+
+/**
+ Check for errors on I2C Bus
+ **/
+UINT32
+I2cCheckErrors (
+  UINT32 Bus
+  )
+{
+  UINTN  Base;
+  UINT32 ErrorStatus;
+
+  Base = mI2cBusList[Bus].Base;
+
+  ErrorStatus = MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_ERR_CONDITION;
+
+  if ((ErrorStatus & DW_IC_INTR_RX_UNDER) != 0) {
+    DEBUG ((DEBUG_ERROR, "%a: RX_UNDER error on i2c bus %d error status %08x\n",
+      __FUNCTION__,
+      Bus,
+      ErrorStatus
+      ));
+    MmioRead32 (Base + DW_IC_CLR_RX_UNDER);
+  }
+
+  if ((ErrorStatus & DW_IC_INTR_RX_OVER) != 0) {
+    DEBUG ((DEBUG_ERROR, "%a: RX_OVER error on i2c bus %d error status %08x\n",
+      __FUNCTION__,
+      Bus,
+      ErrorStatus
+      ));
+    MmioRead32 (Base + DW_IC_CLR_RX_OVER);
+  }
+
+  if ((ErrorStatus & DW_IC_INTR_TX_ABRT) != 0) {
+    DEBUG ((DEBUG_VERBOSE, "%a: TX_ABORT at source %08x\n",
+      __FUNCTION__,
+      MmioRead32 (Base + DW_IC_TX_ABRT_SOURCE)
+      ));
+    MmioRead32 (Base + DW_IC_CLR_TX_ABRT);
+  }
+
+  return ErrorStatus;
+}
+
+/**
+ Waiting for bus to not be busy
+ **/
+BOOLEAN
+I2cWaitBusNotBusy (
+  UINT32 Bus
+  )
+{
+  UINTN Base;
+  UINTN PollCount;
+
+  Base = mI2cBusList[Bus].Base;
+  PollCount = DW_MAX_MST_ACTIVITY_POLL_COUNT;
+
+  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_MST_ACTIVITY) != 0) {
+    if (PollCount == 0) {
+      DEBUG ((DEBUG_VERBOSE, "%a: Timeout while waiting for bus ready\n", __FUNCTION__));
+      return FALSE;
+    }
+    PollCount--;
+    /*
+     * A delay isn't absolutely necessary.
+     * But to ensure that we don't hammer the bus constantly,
+     * delay for DW_POLL_MST_ACTIVITY_INTERVAL_US as with other implementation.
+     */
+    MicroSecondDelay (DW_POLL_MST_ACTIVITY_INTERVAL_US);
+  }
+
+  return TRUE;
+}
+
+/**
+ Waiting for TX FIFO buffer available
+ **/
+EFI_STATUS
+I2cWaitTxData (
+  UINT32 Bus
+  )
+{
+  UINTN Base;
+  UINTN PollCount;
+
+  Base = mI2cBusList[Bus].Base;
+  PollCount = 0;
+
+  while (MmioRead32 (Base + DW_IC_TXFLR) == mI2cBusList[Bus].TxFifo) {
+    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
+      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX buffer available\n", __FUNCTION__));
+      return EFI_TIMEOUT;
+    }
+    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ Waiting for RX FIFO buffer available
+ **/
+EFI_STATUS
+I2cWaitRxData (
+  UINT32 Bus
+  )
+{
+  UINTN Base;
+  UINTN PollCount;
+
+  Base = mI2cBusList[Bus].Base;
+  PollCount = 0;
+
+  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_RFNE) == 0) {
+    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
+      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for RX buffer available\n", __FUNCTION__));
+      return EFI_TIMEOUT;
+    }
+
+    if ((I2cCheckErrors (Bus) & DW_IC_INTR_TX_ABRT) != 0) {
+      return EFI_ABORTED;
+    }
+
+    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ Initialize the Designware I2C SCL Counts
+
+ This functions configures SCL clock Count for Standard Speed (SS) and Fast Speed (FS) mode.
+ **/
+VOID
+I2cSclInit (
+  UINT32 Bus,
+  UINT32 I2cClkFreq,
+  UINT32 I2cSpeed
+  )
+{
+  UINT16 IcCon;
+  UINTN  Base;
+  UINT32 I2cSpeedKhz;
+
+  Base = mI2cBusList[Bus].Base;
+  I2cSpeedKhz = I2cSpeed / 1000;
+
+  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d I2cClkFreq %d I2cSpeed %d\n",
+    __FUNCTION__,
+    Bus,
+    I2cClkFreq,
+    I2cSpeed
+    ));
+
+  IcCon = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN;
+
+  if (I2cSpeedKhz <= 100) {
+    IcCon |= DW_IC_CON_SPEED_STD;
+    // Standard speed mode
+    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeStandard][I2cSclSpkLen]);
+    MmioWrite32 (Base + DW_IC_SS_SCL_HCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclHcnt]);
+    MmioWrite32 (Base + DW_IC_SS_SCL_LCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclLcnt]);
+  } else if (I2cSpeedKhz > 100 && I2cSpeedKhz <= 400) {
+    IcCon |= DW_IC_CON_SPEED_FAST;
+    // Fast speed mode
+    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeFast][I2cSclSpkLen]);
+    MmioWrite32 (Base + DW_IC_FS_SCL_HCNT, I2cSclParam[I2cSpeedModeFast][I2cSclHcnt]);
+    MmioWrite32 (Base + DW_IC_FS_SCL_LCNT, I2cSclParam[I2cSpeedModeFast][I2cSclLcnt]);
+  }
+  MmioWrite32 (Base + DW_IC_CON, IcCon);
+}
+
+/**
+ Initialize the designware i2c master hardware
+ **/
+EFI_STATUS
+I2cInit (
+  UINT32 Bus,
+  UINTN  BusSpeed
+  )
+{
+  UINTN Base;
+
+  ASSERT (mI2cClock != 0);
+
+  mI2cBusList[Bus].BusSpeed = BusSpeed;
+  I2cHWInit (Bus);
+
+  Base = mI2cBusList[Bus].Base;
+
+  /* Disable the adapter and interrupt */
+  I2cEnable (Bus, 0);
+  MmioWrite32 (Base + DW_IC_INTR_MASK, 0);
+
+  /* Set standard and fast speed divider for high/low periods */
+  I2cSclInit (Bus, mI2cClock, BusSpeed);
+  MmioWrite32 (Base + DW_IC_SDA_HOLD, 0x4b);
+
+  return EFI_SUCCESS;
+}
+
+/**
+ Wait the transaction finished
+ **/
+EFI_STATUS
+I2cFinish (
+  UINT32 Bus
+  )
+{
+  UINTN Base;
+  UINTN PollCount;
+
+  Base = mI2cBusList[Bus].Base;
+  PollCount = 0;
+
+  /* Wait for TX FIFO empty */
+  do {
+    if ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_TFE) != 0) {
+      break;
+    }
+    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
+  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
+
+  if (PollCount >= DW_MAX_TRANSFER_POLL_COUNT) {
+    DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX FIFO empty\n", __FUNCTION__));
+    return EFI_TIMEOUT;
+  }
+
+  /* Wait for STOP signal detected on the bus */
+  PollCount = 0;
+  do {
+    if ((MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_INTR_STOP_DET) != 0) {
+      MmioRead32 (Base + DW_IC_CLR_STOP_DET);
+      return EFI_SUCCESS;
+    }
+    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
+  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
+
+  DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for transaction finished\n", __FUNCTION__));
+  return EFI_TIMEOUT;
+}
+
+EFI_STATUS
+InternalI2cWrite (
+  UINT32 Bus,
+  UINT8  *Buf,
+  UINT32 *Length
+  )
+{
+  EFI_STATUS Status;
+  UINTN      WriteCount;
+  UINTN      Base;
+
+  Status = EFI_SUCCESS;
+  Base = mI2cBusList[Bus].Base;
+
+  DEBUG ((DEBUG_VERBOSE, "%a: Write Bus %d Buf %p Length %d\n",
+    __FUNCTION__,
+    Bus,
+    Buf,
+    *Length
+    ));
+  I2cEnable (Bus, 1);
+
+  WriteCount = 0;
+  while ((*Length - WriteCount) != 0) {
+    Status = I2cWaitTxData (Bus);
+    if (EFI_ERROR (Status)) {
+      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
+      I2cSync ();
+      goto Exit;
+    }
+
+    if (WriteCount == *Length - 1) {
+      MmioWrite32 (
+        Base + DW_IC_DATA_CMD,
+        (Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK) | DW_IC_DATA_CMD_STOP
+        );
+    } else {
+      MmioWrite32 (
+        Base + DW_IC_DATA_CMD,
+        Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK
+        );
+    }
+    I2cSync ();
+    WriteCount++;
+  }
+
+Exit:
+  *Length = WriteCount;
+  I2cFinish (Bus);
+  I2cWaitBusNotBusy (Bus);
+  I2cEnable (Bus, 0);
+
+  return Status;
+}
+
+EFI_STATUS
+InternalI2cRead (
+  UINT32  Bus,
+  UINT8  *BufCmd,
+  UINT32 CmdLength,
+  UINT8  *Buf,
+  UINT32 *Length
+  )
+{
+  EFI_STATUS Status;
+  UINTN      Base;
+  UINT32     CmdSend;
+  UINT32     TxLimit, RxLimit;
+  UINTN      Idx;
+  UINTN      Count;
+  UINTN      ReadCount;
+  UINTN      WriteCount;
+
+  Status = EFI_SUCCESS;
+  Base = mI2cBusList[Bus].Base;
+  Count = 0;
+
+  DEBUG ((DEBUG_VERBOSE, "%a: Read Bus %d Buf %p Length:%d\n",
+    __FUNCTION__,
+    Bus,
+    Buf,
+    *Length
+    ));
+
+  I2cEnable (Bus, 1);
+
+  /* Write command data */
+  WriteCount = 0;
+  while (CmdLength != 0) {
+    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
+    Count = CmdLength > TxLimit ? TxLimit : CmdLength;
+
+    for (Idx = 0; Idx < Count; Idx++ ) {
+      CmdSend = BufCmd[WriteCount++] & DW_IC_DATA_CMD_DAT_MASK;
+      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
+      I2cSync ();
+
+      if (I2cCheckErrors (Bus) != 0) {
+        Status = EFI_CRC_ERROR;
+        goto Exit;
+      }
+      CmdLength--;
+    }
+
+    Status = I2cWaitTxData (Bus);
+    if (EFI_ERROR (Status)) {
+      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
+      I2cSync ();
+      goto Exit;
+    }
+  }
+
+  ReadCount = 0;
+  WriteCount = 0;
+  while ((*Length - ReadCount) != 0) {
+    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
+    RxLimit = mI2cBusList[Bus].RxFifo - MmioRead32 (Base + DW_IC_RXFLR);
+    Count = *Length - ReadCount;
+    Count = Count > RxLimit ? RxLimit : Count;
+    Count = Count > TxLimit ? TxLimit : Count;
+
+    for (Idx = 0; Idx < Count; Idx++ ) {
+      CmdSend = DW_IC_DATA_CMD_CMD;
+      if (WriteCount == *Length - 1) {
+        CmdSend |= DW_IC_DATA_CMD_STOP;
+      }
+      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
+      I2cSync ();
+      WriteCount++;
+
+      if (I2cCheckErrors (Bus) != 0) {
+        DEBUG ((DEBUG_VERBOSE,
+          "%a: Sending reading command remaining length %d CRC error\n",
+          __FUNCTION__,
+          *Length
+          ));
+        Status = EFI_CRC_ERROR;
+        goto Exit;
+      }
+    }
+
+    for (Idx = 0; Idx < Count; Idx++ ) {
+      Status = I2cWaitRxData (Bus);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_VERBOSE,
+          "%a: Reading remaining length %d failed to wait data\n",
+          __FUNCTION__,
+          *Length
+          ));
+
+        if (Status != EFI_ABORTED) {
+          MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
+          I2cSync ();
+        }
+
+        goto Exit;
+      }
+
+      Buf[ReadCount++] = MmioRead32 (Base + DW_IC_DATA_CMD) & DW_IC_DATA_CMD_DAT_MASK;
+      I2cSync ();
+
+      if (I2cCheckErrors (Bus) != 0) {
+        DEBUG ((DEBUG_VERBOSE, "%a: Reading remaining length %d CRC error\n",
+          __FUNCTION__,
+          *Length
+          ));
+        Status = EFI_CRC_ERROR;
+        goto Exit;
+      }
+    }
+  }
+
+Exit:
+  *Length = ReadCount;
+  I2cFinish (Bus);
+  I2cWaitBusNotBusy (Bus);
+  I2cEnable (Bus, 0);
+
+  return Status;
+}
+
+/**
+  Write to I2C bus.
+
+  @param[in]     Bus          I2C bus Id.
+  @param[in]     SlaveAddr    The address of slave device on the bus.
+  @param[in,out] Buf          Buffer that holds data to write.
+  @param[in,out] WriteLength  Pointer to length of buffer.
+
+  @return EFI_SUCCESS            Write successfully.
+  @return EFI_INVALID_PARAMETER  A parameter is invalid.
+  @return EFI_UNSUPPORTED        The bus is not supported.
+  @return EFI_NOT_READY          The device/bus is not ready.
+  @return EFI_TIMEOUT            Timeout why transferring data.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cWrite (
+  IN     UINT32 Bus,
+  IN     UINT32 SlaveAddr,
+  IN OUT UINT8  *Buf,
+  IN OUT UINT32 *WriteLength
+  )
+{
+  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
+      || Buf == NULL
+      || WriteLength == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  I2cSetSlaveAddr (Bus, SlaveAddr);
+
+  return InternalI2cWrite (Bus, Buf, WriteLength);
+}
+
+/**
+  Read data from I2C bus.
+
+  @param[in]     Bus          I2C bus Id.
+  @param[in]     SlaveAddr    The address of slave device on the bus.
+  @param[in]     BufCmd       Buffer where to send the command.
+  @param[in]     CmdLength    Pointer to length of BufCmd.
+  @param[in,out] Buf          Buffer where to put the read data to.
+  @param[in,out] ReadLength   Pointer to length of buffer.
+
+  @return EFI_SUCCESS            Read successfully.
+  @return EFI_INVALID_PARAMETER  A parameter is invalid.
+  @return EFI_UNSUPPORTED        The bus is not supported.
+  @return EFI_NOT_READY          The device/bus is not ready.
+  @return EFI_TIMEOUT            Timeout why transferring data.
+  @return EFI_CRC_ERROR          There are errors on receiving data.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cRead (
+  IN     UINT32 Bus,
+  IN     UINT32 SlaveAddr,
+  IN     UINT8  *BufCmd,
+  IN     UINT32 CmdLength,
+  IN OUT UINT8  *Buf,
+  IN OUT UINT32 *ReadLength
+  )
+{
+  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
+      || Buf == NULL
+      || ReadLength == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  I2cSetSlaveAddr (Bus, SlaveAddr);
+
+  return InternalI2cRead (Bus, BufCmd, CmdLength, Buf, ReadLength);
+}
+
+/**
+ Setup new transaction with I2C slave device.
+
+  @param[in] Bus      I2C bus Id.
+  @param[in] BusSpeed I2C bus speed in Hz.
+
+  @retval EFI_SUCCESS           Success.
+  @retval EFI_INVALID_PARAMETER A parameter is invalid.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cProbe (
+  IN UINT32 Bus,
+  IN UINTN  BusSpeed
+  )
+{
+  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
+      || BusSpeed > DW_I2C_MAXIMUM_SPEED_HZ)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return I2cInit (Bus, BusSpeed);
+}
+
+/**
+ * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+ *
+ * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ * It convers pointer to new virtual address.
+ *
+ * @param  Event        Event whose notification function is being invoked.
+ * @param  Context      Pointer to the notification function's context.
+ */
+VOID
+EFIAPI
+I2cVirtualAddressChangeEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  UINTN Count;
+
+  EfiConvertPointer (0x0, (VOID **)&mI2cBusList);
+  EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray);
+  EfiConvertPointer (0x0, (VOID **)&mI2cClock);
+  for (Count = 0; Count < MAX_PLATFORM_I2C_BUS_NUM; Count++) {
+    if (!mI2cRuntimeEnableArray[Count]) {
+      continue;
+    }
+    EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray[Count]);
+    EfiConvertPointer (0x0, (VOID **)&mI2cBusList[Count].Base);
+  }
+}
+
+/**
+ Setup a bus that to be used in runtime service.
+
+  @param[in] Bus I2C bus Id.
+
+  @retval EFI_SUCCESS  Success.
+  @retval Otherwise    Error code.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cSetupRuntime (
+  IN UINT32 Bus
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+
+  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mVirtualAddressChangeEvent == NULL) {
+    /*
+     * Register for the virtual address change event
+     */
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_NOTIFY,
+                    I2cVirtualAddressChangeEvent,
+                    NULL,
+                    &gEfiEventVirtualAddressChangeGuid,
+                    &mVirtualAddressChangeEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = gDS->GetMemorySpaceDescriptor (
+                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
+                  &Descriptor
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gDS->SetMemorySpaceAttributes (
+                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
+                  RUNTIME_ADDRESS_LENGTH,
+                  Descriptor.Attributes | EFI_MEMORY_RUNTIME
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  mI2cRuntimeEnableArray[Bus] = TRUE;
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+I2cLibConstructor (
+  VOID
+  )
+{
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  /* Get I2C Clock from the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return EFI_NOT_FOUND;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+  mI2cClock = PlatformHob->AhbClk;
+  ASSERT (mI2cClock != 0);
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (5 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:22   ` Leif Lindholm
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
                   ` (27 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

The DwGpioLib library provides basic functions to control the GPIO
controller on Ampere Altra processor.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec              |   3 +
 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf |  33 ++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h       |  76 +++++
 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c   | 314 ++++++++++++++++++++
 4 files changed, 426 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 8be6a329bb26..be827dd19a96 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -31,6 +31,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to read/write to I2C devices.
   I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
 
+  ##  @libraryclass  Defines a set of methods to get/set GPIO.
+  GpioLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
+
   ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
   MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
 
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
new file mode 100644
index 000000000000..36ce0c3be2c8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
@@ -0,0 +1,33 @@
+## @file
+# Component description for DwGpioLib library for the Designware GPIO controller.
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = DwGpioLib
+  FILE_GUID                      = E7D9CAE1-6930-46E3-BDF9-0027446E7DF2
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GpioLib
+
+[Sources.common]
+  DwGpioLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  IoLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
new file mode 100755
index 000000000000..cb201bc98322
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
@@ -0,0 +1,76 @@
+/** @file
+  Library implementation for the Designware GPIO controller.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef GPIO_LIB_H_
+#define GPIO_LIB_H_
+
+enum SocGpioConfigMode {
+  GPIO_CONFIG_OUT_LOW = 0,
+  GPIO_CONFIG_OUT_HI,
+  GPIO_CONFIG_OUT_LOW_TO_HIGH,
+  GPIO_CONFIG_OUT_HIGH_TO_LOW,
+  GPIO_CONFIG_IN,
+  MAX_GPIO_CONFIG_MODE
+};
+
+/*
+ *  GpioWriteBit: Use to Set/Clear GPIOs
+ *  Input:
+ *              Pin : Pin Identification
+ *              Val : 1 to Set, 0 to Clear
+ */
+VOID
+EFIAPI
+GpioWriteBit (
+  IN UINT32 Pin,
+  IN UINT32 Val
+  );
+
+/*
+ *   GpioReadBit:
+ *   Input:
+ *              Pin : Pin Identification
+ *   Return:
+ *              1 : On/High
+ *              0 : Off/Low
+ */
+UINTN
+EFIAPI
+GpioReadBit (
+  IN UINT32 Pin
+  );
+
+/*
+ *  GpioModeConfig: Use to configure GPIOs as Input/Output
+ *  Input:
+ *              Pin : Pin Identification
+ *              InOut : GPIO_OUT/1 as Output
+ *                      GPIO_IN/0  as Input
+ */
+EFI_STATUS
+EFIAPI
+GpioModeConfig (
+  UINT8 Pin,
+  UINTN Mode
+  );
+
+/*
+ *  Setup a controller that to be used in runtime service.
+ *  Input:
+ *              Pin: Pin belongs to the controller.
+ *  return:     0 for success.
+ *              Otherwise, error code.
+ */
+EFI_STATUS
+EFIAPI
+GpioSetupRuntime (
+  IN UINT32 Pin
+  );
+
+#endif /* GPIO_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
new file mode 100644
index 000000000000..dbb53f7d57d2
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
@@ -0,0 +1,314 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Platform/Ac01.h>
+
+/* Runtime needs to be 64K alignment */
+#define RUNTIME_ADDRESS_MASK           (~(SIZE_64KB - 1))
+#define RUNTIME_ADDRESS_LENGTH         SIZE_64KB
+
+#define GPIO_MUX_VAL(Gpio)              (0x00000001 << (Gpio))
+#define GPIO_IN                         0
+#define GPIO_OUT                        1
+
+/* Address GPIO_REG Registers */
+#define GPIO_SWPORTA_DR_ADDR            0x00000000
+#define GPIO_SWPORTA_DDR_ADDR           0x00000004
+#define GPIO_EXT_PORTA_ADDR             0x00000050
+
+STATIC UINT64    GpioBaseAddr[] = { GPIO_DWAPB_BASE_ADDR };
+STATIC UINT64    GpiBaseAddr[] = { GPI_DWAPB_BASE_ADDR };
+STATIC BOOLEAN   GpioRuntimeEnableArray[sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0])] = { FALSE };
+STATIC EFI_EVENT mVirtualAddressChangeEvent = NULL;
+
+UINT64
+GetBaseAddr (
+  IN UINT32 Pin
+  )
+{
+  UINT32 NumberOfControllers = sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0]);
+  UINT32 TotalPins = GPIO_DWAPB_PINS_PER_CONTROLLER * NumberOfControllers;
+
+  if (NumberOfControllers == 0 || Pin >= TotalPins) {
+    return 0;
+  }
+
+  return GpioBaseAddr[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER];
+}
+
+VOID
+GpioWrite (
+  IN UINT64 Base,
+  IN UINT32 Val
+  )
+{
+  MmioWrite32 ((UINTN)Base, Val);
+}
+
+VOID
+GpioRead (
+  IN  UINT64 Base,
+  OUT UINT32 *Val
+  )
+{
+  ASSERT (Val != NULL);
+  *Val = MmioRead32 (Base);
+}
+
+VOID
+EFIAPI
+GpioWriteBit (
+  IN UINT32 Pin,
+  IN UINT32 Val
+  )
+{
+  UINT64 Reg;
+  UINT32 GpioPin;
+  UINT32 ReadVal;
+
+  Reg = GetBaseAddr (Pin);
+  if (Reg == 0) {
+    return;
+  }
+
+  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
+
+  Reg += GPIO_SWPORTA_DR_ADDR;
+  GpioRead (Reg, &ReadVal);
+
+  if (Val != 0) {
+    GpioWrite (Reg, ReadVal | GPIO_MUX_VAL (GpioPin));
+  } else {
+    GpioWrite (Reg, ReadVal & ~GPIO_MUX_VAL (GpioPin));
+  }
+}
+
+UINTN
+EFIAPI
+GpioReadBit (
+  IN UINT32 Pin
+  )
+{
+  UINT64 Reg;
+  UINT32 Val;
+  UINT32 GpioPin;
+  UINT8  Index;
+  UINT32 MaxIndex;
+
+  Reg = GetBaseAddr (Pin);
+  if (Reg == 0) {
+    return 0;
+  }
+
+  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
+
+  /* Check if a base address is GPI */
+  MaxIndex = sizeof (GpiBaseAddr) / sizeof (GpiBaseAddr[0]);
+  for (Index = 0; Index < MaxIndex; Index++) {
+    if (Reg == GpiBaseAddr[Index]) {
+      break;
+    }
+  }
+  if (Index == MaxIndex) {
+    /* Only GPIO has GPIO_EXT_PORTA register, not for GPI */
+    Reg +=  GPIO_EXT_PORTA_ADDR;
+  }
+
+  GpioRead (Reg, &Val);
+
+  return Val & GPIO_MUX_VAL (GpioPin) ? 1 : 0;
+}
+
+EFI_STATUS
+GpioConfig (
+  IN UINT32 Pin,
+  IN UINT32 InOut
+  )
+{
+  INTN   GpioPin;
+  UINT32 Val;
+  UINT64 Reg;
+
+  /*
+   * Caculate GPIO Pin Number for Direction Register
+   * GPIO_SWPORTA_DDR for GPIO[31...0]
+   * GPIO_SWPORTB_DDR for GPIO[51...32]
+   */
+
+  Reg = GetBaseAddr (Pin);
+  if (Reg == 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  Reg += GPIO_SWPORTA_DDR_ADDR;
+  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
+  GpioRead (Reg, &Val);
+
+  if (InOut == GPIO_OUT) {
+    Val |= GPIO_MUX_VAL (GpioPin);
+  } else {
+    Val &= ~GPIO_MUX_VAL (GpioPin);
+  }
+  GpioWrite (Reg, Val);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+GpioModeConfig (
+  UINT8 Pin,
+  UINTN Mode
+  )
+{
+  UINT32 NumberOfControllers = sizeof (GpioBaseAddr) / sizeof (UINT64);
+  UINT32 NumersOfPins = NumberOfControllers * GPIO_DWAPB_PINS_PER_CONTROLLER;
+  UINT32 Delay = 10;
+
+  if (Mode < GPIO_CONFIG_OUT_LOW
+      || Mode >= MAX_GPIO_CONFIG_MODE
+      || Pin > NumersOfPins - 1
+      || Pin < 0)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (Mode) {
+  case GPIO_CONFIG_OUT_LOW:
+    GpioConfig (Pin, GPIO_OUT);
+    GpioWriteBit (Pin, 0);
+    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low\n", Pin));
+    break;
+
+  case GPIO_CONFIG_OUT_HI:
+    GpioConfig (Pin, GPIO_OUT);
+    GpioWriteBit (Pin, 1);
+    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high\n", Pin));
+    break;
+
+  case GPIO_CONFIG_OUT_LOW_TO_HIGH:
+    GpioConfig (Pin, GPIO_OUT);
+    GpioWriteBit (Pin, 0);
+    MicroSecondDelay (1000 * Delay);
+    GpioWriteBit (Pin, 1);
+    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low->high\n", Pin));
+    break;
+
+  case GPIO_CONFIG_OUT_HIGH_TO_LOW:
+    GpioConfig (Pin, GPIO_OUT);
+    GpioWriteBit (Pin, 1);
+    MicroSecondDelay (1000 * Delay);
+    GpioWriteBit (Pin, 0);
+    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high->low\n", Pin));
+    break;
+
+  case GPIO_CONFIG_IN:
+    GpioConfig (Pin, GPIO_IN);
+    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as input\n", Pin));
+    break;
+
+  default:
+    break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+ *
+ * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
+ * It convers pointer to new virtual address.
+ *
+ * @param  Event        Event whose notification function is being invoked.
+ * @param  Context      Pointer to the notification function's context.
+ */
+VOID
+EFIAPI
+GpioVirtualAddressChangeEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  UINTN Count;
+
+  EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr);
+  for (Count = 0; Count < sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0]); Count++) {
+    if (!GpioRuntimeEnableArray[Count]) {
+      continue;
+    }
+    EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr[Count]);
+  }
+}
+
+/**
+ Setup a controller that to be used in runtime service.
+
+ @Bus:      Bus ID.
+ @return:   0 for success.
+            Otherwise, error code.
+ **/
+EFI_STATUS
+EFIAPI
+GpioSetupRuntime (
+  IN UINT32 Pin
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+
+  if (GetBaseAddr (Pin) == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mVirtualAddressChangeEvent == NULL) {
+    /*
+    * Register for the virtual address change event
+    */
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_NOTIFY,
+                    GpioVirtualAddressChangeEvent,
+                    NULL,
+                    &gEfiEventVirtualAddressChangeGuid,
+                    &mVirtualAddressChangeEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  Status = gDS->GetMemorySpaceDescriptor (
+                  GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK,
+                  &Descriptor
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = gDS->SetMemorySpaceAttributes (
+                  GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK,
+                  RUNTIME_ADDRESS_LENGTH,
+                  Descriptor.Attributes | EFI_MEMORY_RUNTIME
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  GpioRuntimeEnableArray[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER] = TRUE;
+
+  return Status;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (6 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
@ 2021-05-26 10:06 ` Nhi Pham
  2021-06-04 23:26   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
                   ` (26 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:06 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This library adds the support for retrieving and updating system
datetime over real RTC PCF85063 device on Mt. Jade platform instead of
using virtual RTC.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                  |   2 +
 Platform/Ampere/JadePkg/Jade.dsc                                                      |   2 +-
 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf |  44 +++
 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h                   |  91 ++++++
 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c                   | 317 ++++++++++++++++++++
 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c   | 257 ++++++++++++++++
 6 files changed, 712 insertions(+), 1 deletion(-)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 6a6f72e995af..9f19f495fad2 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -84,6 +84,8 @@ [LibraryClasses.common]
   SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
   AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
   TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
+  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
   MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
 
   #
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index f92855af99ab..f37ab1a92e44 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -73,7 +73,7 @@ [LibraryClasses]
   #
   # RTC Library: Common RTC
   #
-  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
 
   #
   # Library for FailSafe support
diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
new file mode 100644
index 000000000000..1fe561cc0ec9
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
@@ -0,0 +1,44 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                      = 0x0001001B
+  MODULE_TYPE                      = BASE
+  BASE_NAME                        = PCF85063RealTimeClockLib
+  FILE_GUID                        = 271569F6-5522-4006-9FF5-F07A59473AAC
+  LIBRARY_CLASS                    = RealTimeClockLib
+  VERSION_STRING                   = 1.0
+
+[Sources.common]
+  PCF85063.c
+  PCF85063.h
+  PCF85063RealTimeClockLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmGenericTimerCounterLib
+  ArmLib
+  BaseLib
+  DebugLib
+  GpioLib
+  DxeServicesTableLib
+  I2cLib
+  TimeBaseLib
+  TimerLib
+  UefiLib
+  UefiRuntimeLib
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
new file mode 100644
index 000000000000..03ce4d29a03f
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
@@ -0,0 +1,91 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCF85063_H_
+#define PCF85063_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/RealTimeClockLib.h>
+
+//
+// I2C bus address that RTC connected to
+//
+#define I2C_RTC_BUS_ADDRESS        1
+
+//
+// I2C RTC bus speed
+//
+#define I2C_RTC_BUS_SPEED          100000
+
+//
+// I2C chip address that RTC connected to
+//
+#define I2C_RTC_CHIP_ADDRESS       0x51
+
+//
+// The GPI PIN that tell if RTC can be access
+//
+#define I2C_RTC_ACCESS_GPIO_PIN    28
+
+/**
+ * Returns the current time and date information of the hardware platform.
+ *
+ * @param  Time                  A pointer to storage to receive a snapshot of the current time.
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER Time is NULL.
+ * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+ */
+EFI_STATUS
+EFIAPI
+PlatformGetTime (
+  OUT EFI_TIME *Time
+  );
+
+/**
+ * Set the time and date information to the hardware platform.
+ *
+ * @param  Time                  A pointer to storage to set the current time to hardware platform.
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER Time is NULL.
+ * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+ **/
+EFI_STATUS
+EFIAPI
+PlatformSetTime (
+  IN EFI_TIME *Time
+  );
+
+/**
+ * Callback function for hardware platform to convert data pointers to virtual address
+ */
+VOID
+EFIAPI
+PlatformVirtualAddressChangeEvent (
+  VOID
+  );
+
+/**
+ * Callback function for hardware platform to initialize private data
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval Others                The error status indicates the error
+ */
+EFI_STATUS
+EFIAPI
+PlatformInitialize (
+  VOID
+  );
+
+#endif /* PCF85063_H_ */
diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
new file mode 100644
index 000000000000..f9fa125d9d7e
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
@@ -0,0 +1,317 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/I2cLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include "PCF85063.h"
+
+#define RTC_TIMEOUT_WAIT_ACCESS        100000 /* 100 miliseconds */
+#define RTC_DEFAULT_MIN_YEAR           2000
+#define RTC_DEFAULT_MAX_YEAR           2099
+
+#define RTC_ADDR                       0x4
+#define RTC_DATA_BUF_LEN               8
+
+/**
+ * PCF85063 register offsets
+ */
+#define PCF85063_OFFSET_SEC            0x0
+#define PCF85063_OFFSET_MIN            0x1
+#define PCF85063_OFFSET_HR             0x2
+#define PCF85063_OFFSET_DAY            0x3
+#define PCF85063_OFFSET_WKD            0x4
+#define PCF85063_OFFSET_MON            0x5
+#define PCF85063_OFFSET_YEA            0x6
+
+/**
+ * PCF85063 encoding macros
+ */
+#define PCF85063_SEC_ENC(s) (((((s) / 10) & 0x7) << 4) | (((s) % 10) & 0xf))
+#define PCF85063_MIN_ENC(m) (((((m) / 10) & 0x7) << 4) | (((m) % 10) & 0xf))
+#define PCF85063_HR_ENC(h)  (((((h) / 10) & 0x3) << 4) | (((h) % 10) & 0xf))
+#define PCF85063_DAY_ENC(d) (((((d) / 10) & 0x3) << 4) | (((d) % 10) & 0xf))
+#define PCF85063_WKD_ENC(w) ((w) & 0x7)
+#define PCF85063_MON_ENC(m) (((((m) / 10) & 0x1) << 4) | (((m) % 10) & 0xf))
+#define PCF85063_YEA_ENC(y) (((((y) / 10) & 0xf) << 4) | (((y) % 10) & 0xf))
+
+/**
+ * PCF85063 decoding macros
+ */
+#define PCF85063_SEC_DEC(s) (((((s) & 0x70) >> 4) * 10) + ((s) & 0xf))
+#define PCF85063_MIN_DEC(m) (((((m) & 0x70) >> 4) * 10) + ((m) & 0xf))
+#define PCF85063_HR_DEC(h)  (((((h) & 0x30) >> 4) * 10) + ((h) & 0xf))
+#define PCF85063_DAY_DEC(d) (((((d) & 0x30) >> 4)* 10) + ((d) & 0xf))
+#define PCF85063_WKD_DEC(w) ((w) & 0x7)
+#define PCF85063_MON_DEC(m) (((((m) & 0x10) >> 4) * 10) + ((m) & 0xf))
+#define PCF85063_YEA_DEC(y) (((((y) & 0xf0) >> 4) * 10) + ((y) & 0xf))
+
+/* Buffer pointers to convert Vir2Phys and Phy2Vir */
+STATIC volatile UINT64 RtcBufVir;
+STATIC volatile UINT64 RtcBufPhy;
+
+STATIC
+EFI_STATUS
+RtcI2cWaitAccess (
+  VOID
+  )
+{
+  INTN Timeout;
+
+  Timeout = RTC_TIMEOUT_WAIT_ACCESS;
+  while ((GpioReadBit (I2C_RTC_ACCESS_GPIO_PIN) != 0) && (Timeout > 0)) {
+    MicroSecondDelay (100);
+    Timeout -= 100;
+  }
+
+  if (Timeout <= 0) {
+    DEBUG ((DEBUG_ERROR, "%a: Timeout while waiting access RTC\n", __FUNCTION__));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+RtcI2cRead (
+  IN     UINT8  Addr,
+  IN OUT UINT64 Data,
+  IN     UINT32 DataLen
+  )
+{
+  EFI_STATUS Status;
+  UINT32     TmpLen;
+
+  if (EFI_ERROR (RtcI2cWaitAccess ())) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Send the slave address for read
+  //
+  TmpLen = 1;
+  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, (UINT8 *)&Addr, &TmpLen);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // Read back the time
+  //
+  Status = I2cRead (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, NULL, 0, (UINT8 *)Data, &DataLen);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RtcI2cWrite (
+  IN UINT8  Addr,
+  IN UINT64 Data,
+  IN UINT32 DataLen
+  )
+{
+  EFI_STATUS Status;
+  UINT8      TmpBuf[RTC_DATA_BUF_LEN + 1];
+  UINT32     TmpLen;
+
+  if (EFI_ERROR (RtcI2cWaitAccess ())) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (DataLen > sizeof (TmpBuf) - 1) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  //
+  // The first byte is the address
+  //
+  TmpBuf[0] = Addr;
+  TmpLen = DataLen + 1;
+  CopyMem ((VOID *)(TmpBuf + 1), (VOID *)Data, DataLen);
+
+  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, TmpBuf, &TmpLen);
+  if (EFI_ERROR (Status)) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * Returns the current time and date information of the hardware platform.
+ *
+ * @param  Time                  A pointer to storage to receive a snapshot of the current time.
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER Time is NULL.
+ * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+ */
+EFI_STATUS
+EFIAPI
+PlatformGetTime (
+  OUT EFI_TIME *Time
+  )
+{
+  EFI_STATUS Status;
+  UINT8      *Data;
+
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = RtcI2cRead (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
+
+  Data = (UINT8 *)RtcBufVir;
+  if (Status == EFI_SUCCESS) {
+    Time->Second = PCF85063_SEC_DEC (Data[PCF85063_OFFSET_SEC]);
+    Time->Minute = PCF85063_MIN_DEC (Data[PCF85063_OFFSET_MIN]);
+    Time->Hour   = PCF85063_HR_DEC (Data[PCF85063_OFFSET_HR]);
+    Time->Day    = PCF85063_DAY_DEC (Data[PCF85063_OFFSET_DAY]);
+    Time->Month  = PCF85063_MON_DEC (Data[PCF85063_OFFSET_MON]);
+    Time->Year   = PCF85063_YEA_DEC (Data[PCF85063_OFFSET_YEA]);
+    Time->Year  += RTC_DEFAULT_MIN_YEAR;
+    if (Time->Year > RTC_DEFAULT_MAX_YEAR) {
+      Time->Year = RTC_DEFAULT_MAX_YEAR;
+    }
+    if (Time->Year < RTC_DEFAULT_MIN_YEAR) {
+      Time->Year = RTC_DEFAULT_MIN_YEAR;
+    }
+  }
+
+  return Status;
+}
+
+/**
+ * Set the time and date information to the hardware platform.
+ *
+ * @param  Time                  A pointer to storage to set the current time to hardware platform.
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER Time is NULL.
+ * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+ **/
+EFI_STATUS
+EFIAPI
+PlatformSetTime (
+  IN EFI_TIME *Time
+  )
+{
+  UINT8 *Data;
+
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Time->Year < RTC_DEFAULT_MIN_YEAR ||
+      Time->Year > RTC_DEFAULT_MAX_YEAR)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Data = (UINT8 *)RtcBufVir;
+  Data[PCF85063_OFFSET_SEC] = PCF85063_SEC_ENC (Time->Second);
+  Data[PCF85063_OFFSET_MIN] = PCF85063_MIN_ENC (Time->Minute);
+  Data[PCF85063_OFFSET_HR]  = PCF85063_HR_ENC (Time->Hour);
+  Data[PCF85063_OFFSET_DAY] = PCF85063_DAY_ENC (Time->Day);
+  Data[PCF85063_OFFSET_MON] = PCF85063_MON_ENC (Time->Month);
+  Data[PCF85063_OFFSET_YEA] = PCF85063_YEA_ENC (Time->Year - RTC_DEFAULT_MIN_YEAR);
+
+  return RtcI2cWrite (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
+}
+
+/**
+ * Callback function for hardware platform to convert data pointers to virtual address
+ */
+VOID
+EFIAPI
+PlatformVirtualAddressChangeEvent (
+  VOID
+  )
+{
+  EfiConvertPointer (0x0, (VOID **)&RtcBufVir);
+}
+
+/**
+ * Callback function for hardware platform to initialize private data
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval Others                The error status indicates the error
+ */
+EFI_STATUS
+EFIAPI
+PlatformInitialize (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  /*
+   * Allocate the buffer for RTC data
+   * The buffer can be accessible after ExitBootServices
+   */
+  RtcBufVir = (UINT64)AllocateRuntimeZeroPool (RTC_DATA_BUF_LEN);
+  ASSERT_EFI_ERROR (RtcBufVir);
+  RtcBufPhy = (UINT64)RtcBufVir;
+
+  Status = I2cSetupRuntime (I2C_RTC_BUS_ADDRESS);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a:%d I2cSetupRuntime() failed - %r \n",
+      __FUNCTION__,
+      __LINE__,
+      Status
+      ));
+    return Status;
+  }
+
+  Status = GpioSetupRuntime (I2C_RTC_ACCESS_GPIO_PIN);
+  ASSERT_EFI_ERROR (Status);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a:%d GpioSetupRuntime() failed - %r \n",
+      __FUNCTION__,
+      __LINE__,
+      Status
+      ));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
new file mode 100755
index 000000000000..ef8c71e92c18
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
@@ -0,0 +1,257 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/RealTimeClockLib.h>
+#include <Library/TimeBaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/RealTimeClock.h>
+
+#include "PCF85063.h"
+
+#define TICKS_PER_SEC     (ArmGenericTimerGetTimerFreq ())
+
+STATIC EFI_EVENT          mVirtualAddressChangeEvent = NULL;
+
+STATIC UINT64             mLastSavedSystemCount = 0;
+STATIC UINT64             mLastSavedTimeEpoch = 0;
+
+/**
+ * Returns the current time and date information, and the time-keeping capabilities
+ * of the hardware platform.
+ *
+ * @param  Time                  A pointer to storage to receive a snapshot of the current time.
+ * @param  Capabilities          An optional pointer to a buffer to receive the real time clock
+ *                               device's capabilities.
+ *
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER Time is NULL.
+ * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+ */
+EFI_STATUS
+EFIAPI
+LibGetTime (
+  OUT EFI_TIME                *Time,
+  OUT EFI_TIME_CAPABILITIES   *Capabilities
+  )
+{
+  EFI_STATUS    Status;
+  UINT64        CurrentSystemCount;
+  UINT64        TimeElapsed;
+  UINTN         EpochSeconds;
+
+  if ((mLastSavedTimeEpoch == 0) || EfiAtRuntime ()) {
+    Status = PlatformGetTime (Time);
+    if (EFI_ERROR (Status)) {
+      // Failed to read platform RTC so create fake time
+      Time->Second = 0;
+      Time->Minute = 0;
+      Time->Hour = 10;
+      Time->Day = 1;
+      Time->Month = 1;
+      Time->Year = 2017;
+    }
+
+    EpochSeconds = EfiTimeToEpoch (Time);
+    if (!EfiAtRuntime ()) {
+      mLastSavedTimeEpoch = EpochSeconds;
+      mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
+    }
+  } else {
+    CurrentSystemCount = ArmGenericTimerGetSystemCount ();
+    if (CurrentSystemCount >= mLastSavedSystemCount) {
+      TimeElapsed = (CurrentSystemCount - mLastSavedSystemCount) / MultU64x32 (1, TICKS_PER_SEC);
+      EpochSeconds = mLastSavedTimeEpoch + TimeElapsed;
+    } else {
+      // System counter overflow 64 bits
+      // Call GetTime again to read the date from RTC HW, not using generic timer system counter
+      mLastSavedTimeEpoch = 0;
+      return LibGetTime (Time, Capabilities);
+    }
+  }
+
+  // Adjust for the correct timezone
+  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
+    EpochSeconds += Time->TimeZone * SEC_PER_MIN;
+  }
+
+  // Adjust for the correct period
+  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
+    // Convert to adjusted time, i.e. spring forwards one hour
+    EpochSeconds += SEC_PER_HOUR;
+  }
+
+  EpochToEfiTime (EpochSeconds, Time);
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * Sets the current local time and date information.
+ *
+ * @param  Time                  A pointer to the current time.
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ * @retval EFI_INVALID_PARAMETER A time field is out of range.
+ * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+ */
+EFI_STATUS
+EFIAPI
+LibSetTime (
+  IN EFI_TIME                *Time
+  )
+{
+  EFI_STATUS    Status;
+  UINTN         EpochSeconds;
+
+  EpochSeconds = EfiTimeToEpoch (Time);
+
+  // Adjust for the correct time zone, i.e. convert to UTC time zone
+  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
+    EpochSeconds -= Time->TimeZone * SEC_PER_MIN;
+  }
+
+  // Adjust for the correct period, i.e. fall back one hour
+  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
+    EpochSeconds -= SEC_PER_HOUR;
+  }
+
+  EpochToEfiTime (EpochSeconds, Time);
+
+  Status = PlatformSetTime (Time);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if (!EfiAtRuntime ()) {
+    mLastSavedTimeEpoch = EpochSeconds;
+    mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+ * Returns the current wakeup alarm clock setting.
+ *
+ * @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+ * @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+ * @param  Time                  The current alarm setting.
+ *
+ * @retval EFI_SUCCESS           The alarm settings were returned.
+ * @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+ * @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+ */
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+  OUT BOOLEAN     *Enabled,
+  OUT BOOLEAN     *Pending,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+ * Sets the system wakeup alarm clock time.
+ *
+ * @param  Enabled               Enable or disable the wakeup alarm.
+ * @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+ *
+ * @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+ *                               Enable is FALSE, then the wakeup alarm was disabled.
+ * @retval EFI_INVALID_PARAMETER A time field is out of range.
+ * @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+ * @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+ */
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+  IN BOOLEAN      Enabled,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  //
+  // Only needed if you are going to support the OS calling RTC functions in virtual mode.
+  // You will need to call EfiConvertPointer (). To convert any stored physical addresses
+  // to virtual address. After the OS transitions to calling in virtual mode, all future
+  // runtime calls will be made in virtual mode.
+  //
+  PlatformVirtualAddressChangeEvent ();
+}
+
+/**
+ * This is the declaration of an EFI image entry point. This can be the entry point to an application
+ * written to this specification, an EFI boot service driver, or an EFI runtime driver.
+ *
+ * @param  ImageHandle           Handle that identifies the loaded image.
+ * @param  SystemTable           System Table for this image.
+ *
+ * @retval EFI_SUCCESS           The operation completed successfully.
+ */
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = PlatformInitialize ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Register for the virtual address change event
+  //
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  LibRtcVirtualNotifyEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &mVirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (7 preceding siblings ...)
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:27   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
                   ` (25 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Quan Nguyen <quan@os.amperecomputing.com>

BootProgress will send 32-bit UEFI Status Code via doorbell to report
its progress status.
Currently support reporting Progress Status Code and Error Status Code
only. Other types of Status Code are ignored.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                     |   2 +
 Platform/Ampere/JadePkg/Jade.fdf                                                         |   2 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf   |  51 +++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf |  49 +++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c     | 211 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c   | 210 +++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni   |  16 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni |  18 ++
 8 files changed, 559 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 9f19f495fad2..9f75da6f05ad 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -529,6 +529,7 @@ [Components.common]
   }
   MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
   MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
 
   #
   # DXE Phase modules
@@ -539,6 +540,7 @@ [Components.common]
   }
   MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
   MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
 
   #
   # PCD
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 80a86d7c1156..1857296a8ea5 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -102,6 +102,7 @@ [FV.FVMAIN_COMPACT]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
   INF ArmPkg/Drivers/CpuPei/CpuPei.inf
   INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
   INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
@@ -149,6 +150,7 @@ [FV.FvMain]
   INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
   INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
   INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
 
   #
   # PI DXE Drivers producing Architectural Protocols (EFI Services)
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
new file mode 100644
index 000000000000..2211a213a6df
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
@@ -0,0 +1,51 @@
+## @file
+#  This module installs Boot Progress Dxe.
+#
+#  This module registers report status code listener to report boot progress
+#  to SMpro.
+#
+#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BootProgressDxe
+  MODULE_UNI_FILE                = BootProgressDxe.uni
+  FILE_GUID                      = 6E12F248-F0C1-11EA-B37C-9798918A2163
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = BootProgressDxeEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  BootProgressDxe.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  DebugLib
+  DxeServicesLib
+  SystemFirmwareInterfaceLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiRscHandlerProtocolGuid                    ## CONSUMES
+
+[Depex]
+  gEfiRscHandlerProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
new file mode 100644
index 000000000000..1dd0ec31ac37
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
@@ -0,0 +1,49 @@
+## @file
+#  Boot Progress Pei Module.
+#
+#  Updates to SCP with Boot Progress information during boot.
+#
+#  This module register report status code listener to collect boot progress
+#  information and keep SCP posted.
+#
+#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BootProgressPeim
+  MODULE_UNI_FILE                = BootProgressPeim.uni
+  FILE_GUID                      = 2E8A3B3E-F26C-11EA-BDE5-6726AD8F88BD
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = BootProgressPeiEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = AARCH64
+#
+
+[Sources]
+  BootProgressPeim.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  PeiServicesLib
+  PeimEntryPoint
+  SystemFirmwareInterfaceLib
+
+[Ppis]
+  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
+
+[Depex]
+  gEfiPeiRscHandlerPpiGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
new file mode 100644
index 000000000000..f87a4d53179f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
@@ -0,0 +1,211 @@
+/** @file
+
+  This module installs Boot Progress Dxe that report boot progress to SMpro.
+
+  This module registers report status code listener to report boot progress
+  to SMpro.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/AmpereCpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DxeServicesLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Pi/PiStatusCode.h>
+#include <Protocol/ReportStatusCodeHandler.h>
+
+typedef struct {
+  UINT8                 Byte;
+  EFI_STATUS_CODE_VALUE Value;
+} STATUS_CODE_TO_CHECKPOINT;
+
+enum BOOT_PROGRESS_STATE {
+  BOOT_NOTSTART = 0,
+  BOOT_START    = 1,
+  BOOT_COMPLETE = 2,
+  BOOT_FAILED   = 3,
+};
+
+UINT32 DxeProgressCode[] = {
+  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),                     // DXE Core is started
+  (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_HB_INIT),                    // PCI host bridge initialization
+  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT),                 // Boot Device Selection (BDS) phase is started 
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS),     // Driver connecting is started
+  (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT),                                           // PCI Bus initialization is started
+  (EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT),                                      // PCI Bus Hot Plug Controller Initialization
+  (EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM),                                      // PCI Bus Enumeration
+  (EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC),                                     // PCI Bus Request Resources
+  (EFI_IO_BUS_PCI | EFI_IOB_PC_ENABLE),                                         // PCI Bus Assign Resources
+  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_INIT),                               // Console Output devices connect
+  (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT),                                    // Console input devices connect
+  (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),                                           // Super IO Initialization
+  (EFI_IO_BUS_USB | EFI_IOB_PC_INIT),                                           // USB initialization is started
+  (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),                                          // USB Reset
+  (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT),                                         // USB Detect
+  (EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE),                                         // USB Enable
+  (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),                                          // SCSI initialization is started
+  (EFI_IO_BUS_SCSI | EFI_IOB_PC_RESET),                                         // SCSI Reset
+  (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),                                        // SCSI Detect
+  (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),                                        // SCSI Enable
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD),           // Setup Verifying Password
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP),                          // Start of Setup
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT),                          // Setup Input Wait
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT),          // Ready To Boot event
+  (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES),            // Exit Boot Services event
+  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP),    // Runtime Set Virtual Address MAP Begin
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT), // Runtime Set Virtual Address MAP End
+  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM),               // System Reset
+  (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG),                                        // USB hot plug
+  (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG),                                        // PCI bus hot plug
+  0                                                                             // Must ended by 0
+};
+
+UINT32 DxeErrorCode[] = {
+  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH),                   // Some of the Architectural Protocols are not available
+  (EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT),                        // PCI resource allocation error. Out of Resources
+  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED),                 // No Console Output Devices are found
+  (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED),                      // No Console Input Devices are found
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_PASSWORD),       // Invalid password
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR), // Error loading Boot Option (LoadImage returned error)
+  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED),     // Boot Option is failed (StartImage returned error)
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UPDATE_FAIL),             // Flash update is failed
+  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),  // Reset protocol is not available
+  0                                                                       // Must end by 0
+};
+
+EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
+
+STATIC UINT8 mBootstate = BOOT_START;
+
+STATIC
+BOOLEAN
+StatusCodeFilter (
+  UINT32                *Map,
+  EFI_STATUS_CODE_VALUE Value
+  )
+{
+  UINTN Index = 0;
+
+  while (Map[Index] != 0) {
+    if (Map[Index] == Value) {
+      return TRUE;
+    }
+    Index++;
+  }
+  return FALSE;
+}
+
+/**
+  Report status code listener of Boot Progress Dxe.
+
+  @param[in]  CodeType            Indicates the type of status code being reported.
+  @param[in]  Value               Describes the current status of a hardware or software entity.
+                                  This included information about the class and subclass that is used to
+                                  classify the entity as well as an operation.
+  @param[in]  Instance            The enumeration of a hardware or software entity within
+                                  the system. Valid instance numbers start with 1.
+  @param[in]  CallerId            This optional parameter may be used to identify the caller.
+                                  This parameter allows the status code driver to apply different rules to
+                                  different callers.
+  @param[in]  Data                This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS             Status code is what we expected.
+  @retval EFI_UNSUPPORTED         Status code not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+BootProgressListenerDxe (
+  IN EFI_STATUS_CODE_TYPE  CodeType,
+  IN EFI_STATUS_CODE_VALUE Value,
+  IN UINT32                Instance,
+  IN EFI_GUID              *CallerId,
+  IN EFI_STATUS_CODE_DATA  *Data
+  )
+{
+  BOOLEAN IsProgress = FALSE;
+  BOOLEAN IsError = FALSE;
+
+  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    IsProgress = StatusCodeFilter (DxeProgressCode, Value);
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    IsError = StatusCodeFilter (DxeErrorCode, Value);
+  } else {
+    return EFI_SUCCESS;
+  }
+
+  if (!IsProgress && !IsError) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "BootProgressDxe: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
+    CodeType,
+    Value,
+    Instance,
+    CallerId,
+    Data
+    ));
+
+  if (IsError) {
+    mBootstate = BOOT_FAILED;
+  } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)) {
+    /* Set boot complete when reach to ReadyToBoot event */
+    mBootstate = BOOT_COMPLETE;
+  }
+
+  MailboxMsgSetBootProgress (0, mBootstate, Value);
+
+  if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) &&
+      mRscHandlerProtocol != NULL)
+  {
+    mRscHandlerProtocol->Unregister (BootProgressListenerDxe);
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  The module Entry Point of the Firmware Performance Data Table DXE driver.
+
+  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in]  SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS    The entry point is executed successfully.
+  @retval Other          Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+BootProgressDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  //
+  // Get Report Status Code Handler Protocol.
+  //
+  Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **)&mRscHandlerProtocol);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Register report status code listener for OS Loader load and start.
+  //
+  if (!EFI_ERROR (Status)) {
+    Status = mRscHandlerProtocol->Register (BootProgressListenerDxe, TPL_HIGH_LEVEL);
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
new file mode 100644
index 000000000000..c677e27a00ce
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
@@ -0,0 +1,210 @@
+/** @file
+
+  This module installs Boot Progress Pei to report boot progress to SMpro.
+
+  This module registers report status code listener to report boot progress
+  to SMpro.
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+
+#include <Library/AmpereCpuLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <Pi/PiStatusCode.h>
+#include <Ppi/ReportStatusCodeHandler.h>
+
+enum BOOT_PROGRESS_STATE {
+  BOOT_NOTSTART = 0,
+  BOOT_START    = 1,
+  BOOT_COMPLETE = 2,
+  BOOT_FAILED   = 3,
+};
+
+UINT32 PeiProgressStatusCode[] = {
+  // Regular boot
+  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_ENTRY_POINT),         // PEI Core is started
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT), // Pre-memory CPU initialization is started
+  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_INSTALL_PEI_MEMORY),     // Memory Installed
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_PC_INIT_BEGIN),       // CPU post-memory initialization is started
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT),    // CPU post-memory initialization. Cache initialization
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT),       // CPU post-memory initialization. Application Processor(s) (AP) initialization
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT),    // CPU post-memory initialization. Boot Strap Processor (BSP) selection
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT),      // CPU post-memory initialization. System Management Mode (SMM) initialization
+  // DXE IPL is started
+  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT), // DXE IPL is started
+  // DXE Core is started
+  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),     // DXE Core is started
+  // Recovery
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_AUTO),  // Recovery condition triggered by firmware (Auto recovery)
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_USER),  // Recovery condition triggered by user (Forced recovery)
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN), // Recovery process started
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD),   // Recovery firmware image is found
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START),  // Recovery firmware image is loaded
+  // S3
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT), // S3 Boot Script execution
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE),        // OS S3 wake vector call
+  0                                                         // Must end with 0
+};
+
+UINT32 PeiErrorStatusCode[] = {
+  // Regular boot
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_TYPE),       // Memory initialization error. Invalid memory type
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SPEED),      // Memory initialization error. Incompatible memory speed
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_SPD_FAIL),           // Memory initialization error. SPD reading has failed
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SIZE),       // Memory initialization error. Invalid memory size
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH),           // Memory initialization error. Memory modules do not match
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED),      // Memory initialization error. No usable memory detected
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL),        // Memory initialization error. No usable memory detected
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_EC_NON_SPECIFIC),              // Unspecified memory initialization error.
+  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED), // Memory not installed
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_TYPE),   // Invalid CPU type
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_SPEED),  // Invalid CPU Speed
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MISMATCH),       // CPU mismatch
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST),      // CPU self test failed
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CACHE),          // possible CPU cache error
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INTERNAL),       // Internal CPU error
+  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_NON_SPECIFIC),      // Internal CPU error
+  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),     // reset PPI is not available
+  // Recovery
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND),     // Recovery PPI is not available
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE),        // Recovery capsule is not found
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR), // Invalid recovery capsule
+  // S3 Resume
+  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_S3_RESUME_FAIL),     // S3 Resume Failed
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND), // S3 Resume PPI not found
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR),    // S3 Resume Boot Script Error
+  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR),        // S3 OS Wake Error
+  0
+};
+
+// Should always be BOOT_START when start
+STATIC UINT8 mBootstate = BOOT_START;
+
+STATIC
+BOOLEAN
+StatusCodeFilter (
+  UINT32                *Map,
+  EFI_STATUS_CODE_VALUE Value
+  )
+{
+  UINTN Index = 0;
+
+  while (Map[Index] != 0) {
+    if (Map[Index] == Value) {
+      return TRUE;
+    }
+    Index++;
+  }
+
+  return FALSE;
+}
+
+/**
+  Report status code listener for PEI. This is used to record the boot progress info
+  and report it to SMpro.
+
+  @param[in]  PeiServices         An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
+  @param[in]  CodeType            Indicates the type of status code being reported.
+  @param[in]  Value               Describes the current status of a hardware or software entity.
+                                  This included information about the class and subclass that is used to
+                                  classify the entity as well as an operation.
+  @param[in]  Instance            The enumeration of a hardware or software entity within
+                                  the system. Valid instance numbers start with 1.
+  @param[in]  CallerId            This optional parameter may be used to identify the caller.
+                                  This parameter allows the status code driver to apply different rules to
+                                  different callers.
+  @param[in]  Data                This optional parameter may be used to pass additional data.
+
+  @retval EFI_SUCCESS             Status code is what we expected.
+  @retval EFI_UNSUPPORTED         Status code not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+BootProgressListenerPei (
+  IN       CONST EFI_PEI_SERVICES **PeiServices,
+  IN       EFI_STATUS_CODE_TYPE   CodeType,
+  IN       EFI_STATUS_CODE_VALUE  Value,
+  IN       UINT32                 Instance,
+  IN CONST EFI_GUID               *CallerId,
+  IN CONST EFI_STATUS_CODE_DATA   *Data
+  )
+{
+  BOOLEAN IsProgress = FALSE;
+  BOOLEAN IsError = FALSE;
+
+  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
+    IsProgress = StatusCodeFilter (PeiProgressStatusCode, Value);
+  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
+    IsError = StatusCodeFilter (PeiErrorStatusCode, Value);
+  } else {
+    return EFI_SUCCESS;
+  }
+
+  // No interested status found
+  if (!IsProgress && !IsError) {
+    return EFI_SUCCESS;
+  }
+
+  DEBUG ((
+    DEBUG_INFO,
+    "BootProgressPeim: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
+    CodeType,
+    Value,
+    Instance,
+    CallerId,
+    Data
+    ));
+
+  if (IsError) {
+    mBootstate = BOOT_FAILED;
+  }
+
+  MailboxMsgSetBootProgress (0, mBootstate, Value);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Main entry for Boot Progress PEIM.
+
+  This routine is to register report status code listener for Boot Progress PEIM.
+
+  @param[in]  FileHandle              Handle of the file being invoked.
+  @param[in]  PeiServices             Pointer to PEI Services table.
+
+  @retval EFI_SUCCESS Report status code listener is registered successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+BootProgressPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  EFI_STATUS              Status;
+  EFI_PEI_RSC_HANDLER_PPI *RscHandler;
+
+  Status = PeiServicesLocatePpi (
+             &gEfiPeiRscHandlerPpiGuid,
+             0,
+             NULL,
+             (VOID **)&RscHandler
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  if (!EFI_ERROR (Status)) {
+    Status = RscHandler->Register (BootProgressListenerPei);
+  }
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
new file mode 100644
index 000000000000..492e85404631
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
@@ -0,0 +1,16 @@
+//
+// This module installs Boot Progress Dxe that report boot progress to SMpro.
+//
+// This module registers report status code listener to report boot progress
+// for SMpro.
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Installs Boot Progress Driver"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module registers report status code listener to collect and report boot progress to SMpro."
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
new file mode 100644
index 000000000000..0371fc4f9a80
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
@@ -0,0 +1,18 @@
+//
+// Boot Progress Pei Module.
+//
+// Updates to SCP with Boot Progress information during boot
+//
+// This module register report status code listener to collect boot progress
+// information and keep SCP posted.
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+//
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Boot Progress Pei Module."
+
+#string STR_MODULE_DESCRIPTION          #language en-US "Updates SCP with boot progress information during boot. This module register report status code listener to collect boot progress information and post to SCP."
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (8 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:36   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
                   ` (24 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Non-volatile variables now can be stored on flash. MM communication
protocol is used to access storage on flash.

Included in this change are:
* FlashPei module is used to compare saved UUID with firmware's
  UEFI_UUID on each boot. If UUIDs match, data is stored to RAM.
  Otherwise fill the storage with default value from NVRAM FV.
* FlashLib provide APIs to access flash through MM Communication
  protocol
* FlashFvbDxe installs gEfiFirmwareVolumeBlock protocol which will be
  used by the variable services to get/set variables.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                  |   3 +
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec              |   3 +
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc              |  11 +-
 Platform/Ampere/JadePkg/Jade.dsc                                  |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                  |  62 ++-
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf |  54 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf       |  51 ++
 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf       |  36 ++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h          |  42 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c   | 525 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c         | 283 +++++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c         | 358 +++++++++++++
 12 files changed, 1425 insertions(+), 4 deletions(-)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index be827dd19a96..d5b12a81e9bf 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -37,6 +37,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
   MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
 
+  ##  @libraryclass  Defines a set of methods to access flash memory.
+  FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
+
   ##  @libraryclass  Defines a set of methods to generate random numbers by using Hardware RNG.
   TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
 
diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index 6ebdf7db0a57..26e020715290 100755
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -44,3 +44,6 @@ [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
   # Firmware Volume Pcds
   #
   gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
+
+  # NVRam Pcds
+  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 9f75da6f05ad..65973569a41d 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -14,6 +14,7 @@ [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
 
 [BuildOptions]
   GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
+  GCC:*_*_*_CC_FLAGS = -DUEFI_UUID=$(UEFI_UUID)
 
 [LibraryClasses.common]
 !if $(TARGET) == RELEASE
@@ -224,6 +225,7 @@ [LibraryClasses.common.DXE_DRIVER]
   SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
   PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
   MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
 
 [LibraryClasses.common.UEFI_APPLICATION]
   UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
@@ -254,6 +256,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
 
   EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
   ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
 
 [LibraryClasses.ARM,LibraryClasses.AARCH64]
   #
@@ -500,6 +503,8 @@ [PcdsDynamicDefault.common]
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0
   gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
 
+  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE
+
 ################################################################################
 #
 # Component Section - list of all EDK II Component Entries defined by this Platform
@@ -520,8 +525,10 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
   ArmPkg/Drivers/CpuPei/CpuPei.inf
   UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
   MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
   MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
     <LibraryClasses>
@@ -575,9 +582,9 @@ [Components.common]
   #
   # Environment Variables Protocol
   #
+  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
+  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
   MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
-    <PcdsFixedAtBuild>
-      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
     <LibraryClasses>
       BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
       TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index f37ab1a92e44..9b9a5d0bad0f 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -52,6 +52,7 @@ [Defines]
   DEFINE EDK2_SKIP_PEICORE       = TRUE
   DEFINE SECURE_BOOT_ENABLE      = FALSE
   DEFINE INCLUDE_TFTP_COMMAND    = TRUE
+  DEFINE UEFI_UUID               = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5
 
   #
   # Network definition
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 1857296a8ea5..375455086d0b 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -26,7 +26,7 @@ [FD.BL33_JADE_UEFI]
 ErasePolarity = 1
 
 # This one is tricky, it must be: BlockSize * NumBlocks = Size
-BlockSize     = 0x10000
+BlockSize     = 0x10000|gAmpereTokenSpaceGuid.PcdFvBlockSize
 NumBlocks     = 0x7C
 
 ################################################################################
@@ -56,8 +56,61 @@ [FD.BL33_JADE_UEFI]
 
 #
 # NV Variables
-# T.B.D
+# Offset: 0x00740000
+# Size:   0x00080000
 #
+0x00740000|0x00030000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+DATA = {
+  ## This is the EFI_FIRMWARE_VOLUME_HEADER
+  # ZeroVector []
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
+  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
+  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
+  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
+  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
+  # FvLength: 0x80000
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+  # Signature "_FVH"       # Attributes
+  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
+  # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
+  0x48, 0x00, 0x2D, 0x09, 0x00, 0x00, 0x00, 0x02,
+  # Blockmap[0]: 0x2 Blocks * 0x40000 Bytes / Block
+  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+  # Blockmap[1]: End
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  ## This is the VARIABLE_STORE_HEADER
+  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
+  # Signature: gEfiAuthenticatedVariableGuid =
+  #   { 0xaaf32c78, 0x947b, 0x439a,
+  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
+  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
+  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
+  # Size: 0x30000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
+  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x2FFB8
+  # This can speed up the Variable Dispatch a bit.
+  0xB8, 0xFF, 0x02, 0x00,
+  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
+  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00770000|0x00010000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+DATA = {
+  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
+  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
+  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
+  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
+  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
+  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
+  # WriteQueueSize: UINT64 Size: 0x10000 - 0x20 (FTW_WORKING_HEADER) = 0xFFE0
+  0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+}
+
+0x00780000|0x00040000
+gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
 
 ################################################################################
 #
@@ -102,9 +155,11 @@ [FV.FVMAIN_COMPACT]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
   INF ArmPkg/Drivers/CpuPei/CpuPei.inf
   INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
   INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
   INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
   INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
@@ -144,6 +199,7 @@ [FV.FvMain]
   INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
   INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
 }
 
   INF MdeModulePkg/Core/Dxe/DxeMain.inf
@@ -173,6 +229,8 @@ [FV.FvMain]
   # Environment Variables Protocol
   #
   INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
 
   #
   # Multiple Console IO support
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
new file mode 100644
index 000000000000..782278615094
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
@@ -0,0 +1,54 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FlashFvbDxe
+  FILE_GUID                      = 9E6EA240-DF80-11EA-8B6E-0800200C9A66
+  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
+  VERSION_STRING                 = 0.1
+  ENTRY_POINT                    = FlashFvbDxeInitialize
+
+[Sources]
+  FlashFvbDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  FlashLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeLib
+
+[FixedPcd]
+  gAmpereTokenSpaceGuid.PcdFvBlockSize
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+
+[Guids]
+  gEfiEventVirtualAddressChangeGuid
+  gSpiNorMmGuid
+
+[Protocols]
+  gEfiFirmwareVolumeBlockProtocolGuid             ## PRODUCES
+  gEfiMmCommunicationProtocolGuid                 ## CONSUMES
+
+[Depex]
+  gEfiMmCommunicationProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
new file mode 100644
index 000000000000..a4eaf5039bb0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
@@ -0,0 +1,51 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = FlashPei
+  FILE_GUID                      = 967CFBD0-DF81-11EA-8B6E-0800200C9A66
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = FlashPeiEntryPoint
+
+[Sources]
+  FlashPei.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmSmcLib
+  BaseMemoryLib
+  DebugLib
+  MmCommunicationLib
+  PcdLib
+  PeimEntryPoint
+
+[Guids]
+  gSpiNorMmGuid
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
+
+  gAmpereTokenSpaceGuid.PcdNvramErased
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
new file mode 100644
index 000000000000..2d5003d1af17
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
@@ -0,0 +1,36 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = FlashLib
+  FILE_GUID                     = 9E9D093D-6484-45AE-BA49-0745AA0BB481
+  MODULE_TYPE                   = DXE_DRIVER
+  VERSION_STRING                = 0.1
+  LIBRARY_CLASS                 = FlashLib
+  CONSTRUCTOR                   = FlashLibConstructor
+
+[Sources.common]
+  FlashLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+
+[Guids]
+  gSpiNorMmGuid
+
+[Protocols]
+  gEfiMmCommunicationProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
new file mode 100644
index 000000000000..9207dee643a5
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
@@ -0,0 +1,42 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FLASH_LIB_H_
+#define FLASH_LIB_H_
+
+EFI_STATUS
+EFIAPI
+FlashGetNvRamInfo (
+  OUT UINT64 *NvRamBase,
+  OUT UINT32 *NvRamSize
+  );
+
+EFI_STATUS
+EFIAPI
+FlashEraseCommand (
+  IN UINT8  *pBlockAddress,
+  IN UINT32 Length
+  );
+
+EFI_STATUS
+EFIAPI
+FlashProgramCommand (
+  IN     UINT8 *pByteAddress,
+  IN     UINT8 *Byte,
+  IN OUT UINTN *Length
+  );
+
+EFI_STATUS
+EFIAPI
+FlashReadCommand (
+  IN     UINT8 *pByteAddress,
+  OUT    UINT8 *Byte,
+  IN OUT UINTN *Length
+  );
+
+#endif /* FLASH_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
new file mode 100644
index 000000000000..dcd92151b7d2
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
@@ -0,0 +1,525 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/FlashLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeLib.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+
+//
+// These temporary buffers are used to calculate and convert linear virtual
+// to physical address
+//
+STATIC UINT64 mNvFlashBase;
+STATIC UINT32 mNvFlashSize;
+STATIC UINT32 mFlashBlockSize;
+STATIC UINT64 mNvStorageBase;
+STATIC UINT64 mNvStorageSize;
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+FlashFvbAddressChangeEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EfiConvertPointer (0x0, (VOID **)&mNvStorageBase);
+}
+
+/**
+  The GetAttributes() function retrieves the attributes and
+  current settings of the block.
+
+  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
+                    attributes and current settings are
+                    returned. Type EFI_FVB_ATTRIBUTES_2 is defined
+                    in EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS The firmware volume attributes were
+                      returned.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  OUT      EFI_FVB_ATTRIBUTES_2                *Attributes
+  )
+{
+  ASSERT (Attributes != NULL);
+
+  *Attributes = EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
+                EFI_FVB2_READ_STATUS        | // Reads are currently enabled
+                EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
+                EFI_FVB2_WRITE_ENABLED_CAP  | // Writes may be enabled
+                EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
+                EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
+                EFI_FVB2_ALIGNMENT          |
+                EFI_FVB2_ERASE_POLARITY;      // After erasure all bits take this value (i.e. '1')
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The SetAttributes() function sets configurable firmware volume
+  attributes and returns the new settings of the firmware volume.
+
+  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Attributes   On input, Attributes is a pointer to
+                      EFI_FVB_ATTRIBUTES_2 that contains the
+                      desired firmware volume settings. On
+                      successful return, it contains the new
+                      settings of the firmware volume. Type
+                      EFI_FVB_ATTRIBUTES_2 is defined in
+                      EFI_FIRMWARE_VOLUME_HEADER.
+
+  @retval EFI_SUCCESS           The firmware volume attributes were returned.
+
+  @retval EFI_INVALID_PARAMETER The attributes requested are in
+                                conflict with the capabilities
+                                as declared in the firmware
+                                volume header.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeSetAttributes (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN OUT   EFI_FVB_ATTRIBUTES_2                *Attributes
+  )
+{
+  return EFI_SUCCESS;  // ignore for now
+}
+
+/**
+  The GetPhysicalAddress() function retrieves the base address of
+  a memory-mapped firmware volume. This function should be called
+  only for memory-mapped firmware volumes.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Address  Pointer to a caller-allocated
+                  EFI_PHYSICAL_ADDRESS that, on successful
+                  return from GetPhysicalAddress(), contains the
+                  base address of the firmware volume.
+
+  @retval EFI_SUCCESS       The firmware volume base address was returned.
+
+  @retval EFI_UNSUPPORTED   The firmware volume is not memory mapped.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetPhysicalAddress (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  OUT      EFI_PHYSICAL_ADDRESS                *Address
+  )
+{
+  ASSERT (Address != NULL);
+
+  *Address = (EFI_PHYSICAL_ADDRESS)mNvStorageBase;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  The GetBlockSize() function retrieves the size of the requested
+  block. It also returns the number of additional blocks with
+  the identical size. The GetBlockSize() function is used to
+  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
+
+
+  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba            Indicates the block for which to return the size.
+
+  @param BlockSize      Pointer to a caller-allocated UINTN in which
+                        the size of the block is returned.
+
+  @param NumberOfBlocks Pointer to a caller-allocated UINTN in
+                        which the number of consecutive blocks,
+                        starting with Lba, is returned. All
+                        blocks in this range have a size of
+                        BlockSize.
+
+
+  @retval EFI_SUCCESS             The firmware volume base address was returned.
+
+  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeGetBlockSize (
+  IN  CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN        EFI_LBA                             Lba,
+  OUT       UINTN                               *BlockSize,
+  OUT       UINTN                               *NumberOfBlocks
+  )
+{
+  UINTN TotalNvStorageBlocks;
+
+  ASSERT (BlockSize != NULL);
+  ASSERT (NumberOfBlocks != NULL);
+
+  TotalNvStorageBlocks = mNvStorageSize / mFlashBlockSize;
+
+  if (TotalNvStorageBlocks <= (UINTN)Lba) {
+    DEBUG ((DEBUG_ERROR, "The requested LBA is out of range\n"));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *NumberOfBlocks = TotalNvStorageBlocks - (UINTN)Lba;
+  *BlockSize = mFlashBlockSize;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads the specified number of bytes into a buffer from the specified block.
+
+  The Read() function reads the requested number of bytes from the
+  requested block and stores them in the provided buffer.
+  Implementations should be mindful that the firmware volume
+  might be in the ReadDisabled state. If it is in this state,
+  the Read() function must return the status code
+  EFI_ACCESS_DENIED without modifying the contents of the
+  buffer. The Read() function must also prevent spanning block
+  boundaries. If a read is requested that would span a block
+  boundary, the read must read up to the boundary but not
+  beyond. The output parameter NumBytes must be set to correctly
+  indicate the number of bytes actually read. The caller must be
+  aware that a read may be partially completed.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba      The starting logical block index
+                  from which to read.
+
+  @param Offset   Offset into the block at which to begin reading.
+
+  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
+                  contains the total size of the buffer. At
+                  exit, *NumBytes contains the total number of
+                  bytes read.
+
+  @param Buffer   Pointer to a caller-allocated buffer that will
+                  be used to hold the data that is read.
+
+  @retval EFI_SUCCESS         The firmware volume was read successfully,
+                              and contents are in Buffer.
+
+  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
+                              boundary. On output, NumBytes
+                              contains the total number of bytes
+                              returned in Buffer.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              ReadDisabled state.
+
+  @retval EFI_DEVICE_ERROR    The block device is not
+                              functioning correctly and could
+                              not be read.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeRead (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN       EFI_LBA                             Lba,
+  IN       UINTN                               Offset,
+  IN OUT   UINTN                               *NumBytes,
+  IN OUT   UINT8                               *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Buffer != NULL);
+
+  if (Offset + *NumBytes > mFlashBlockSize) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Status = FlashReadCommand (
+             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
+             Buffer,
+             NumBytes
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash read\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Writes the specified number of bytes from the input buffer to the block.
+
+  The Write() function writes the specified number of bytes from
+  the provided buffer to the specified block and offset. If the
+  firmware volume is sticky write, the caller must ensure that
+  all the bits of the specified range to write are in the
+  EFI_FVB_ERASE_POLARITY state before calling the Write()
+  function, or else the result will be unpredictable. This
+  unpredictability arises because, for a sticky-write firmware
+  volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
+  state but cannot flip it back again.  Before calling the
+  Write() function,  it is recommended for the caller to first call
+  the EraseBlocks() function to erase the specified block to
+  write. A block erase cycle will transition bits from the
+  (NOT)EFI_FVB_ERASE_POLARITY state back to the
+  EFI_FVB_ERASE_POLARITY state. Implementations should be
+  mindful that the firmware volume might be in the WriteDisabled
+  state. If it is in this state, the Write() function must
+  return the status code EFI_ACCESS_DENIED without modifying the
+  contents of the firmware volume. The Write() function must
+  also prevent spanning block boundaries. If a write is
+  requested that spans a block boundary, the write must store up
+  to the boundary but not beyond. The output parameter NumBytes
+  must be set to correctly indicate the number of bytes actually
+  written. The caller must be aware that a write may be
+  partially completed. All writes, partial or otherwise, must be
+  fully flushed to the hardware before the Write() service
+  returns.
+
+  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
+
+  @param Lba      The starting logical block index to write to.
+
+  @param Offset   Offset into the block at which to begin writing.
+
+  @param NumBytes The pointer to a UINTN. At entry, *NumBytes
+                  contains the total size of the buffer. At
+                  exit, *NumBytes contains the total number of
+                  bytes actually written.
+
+  @param Buffer   The pointer to a caller-allocated buffer that
+                  contains the source for the write.
+
+  @retval EFI_SUCCESS         The firmware volume was written successfully.
+
+  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
+                              LBA boundary. On output, NumBytes
+                              contains the total number of bytes
+                              actually written.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              WriteDisabled state.
+
+  @retval EFI_DEVICE_ERROR    The block device is malfunctioning
+                              and could not be written.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeWrite (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  IN       EFI_LBA                             Lba,
+  IN       UINTN                               Offset,
+  IN OUT   UINTN                               *NumBytes,
+  IN       UINT8                               *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  ASSERT (NumBytes != NULL);
+  ASSERT (Buffer != NULL);
+
+  if (Offset + *NumBytes > mFlashBlockSize) {
+    return EFI_BAD_BUFFER_SIZE;
+  }
+
+  Status = FlashProgramCommand (
+             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
+             Buffer,
+             NumBytes
+             );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash program\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return Status;
+}
+
+/**
+  Erases and initializes a firmware volume block.
+
+  The EraseBlocks() function erases one or more blocks as denoted
+  by the variable argument list. The entire parameter list of
+  blocks must be verified before erasing any blocks. If a block is
+  requested that does not exist within the associated firmware
+  volume (it has a larger index than the last block of the
+  firmware volume), the EraseBlocks() function must return the
+  status code EFI_INVALID_PARAMETER without modifying the contents
+  of the firmware volume. Implementations should be mindful that
+  the firmware volume might be in the WriteDisabled state. If it
+  is in this state, the EraseBlocks() function must return the
+  status code EFI_ACCESS_DENIED without modifying the contents of
+  the firmware volume. All calls to EraseBlocks() must be fully
+  flushed to the hardware before the EraseBlocks() service
+  returns.
+
+  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
+                instance.
+
+  @param ...    The variable argument list is a list of tuples.
+                Each tuple describes a range of LBAs to erase
+                and consists of the following:
+                - An EFI_LBA that indicates the starting LBA
+                - A UINTN that indicates the number of blocks to
+                  erase.
+
+                The list is terminated with an
+                EFI_LBA_LIST_TERMINATOR. For example, the
+                following indicates that two ranges of blocks
+                (5-7 and 10-11) are to be erased: EraseBlocks
+                (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
+
+  @retval EFI_SUCCESS The erase request successfully
+                      completed.
+
+  @retval EFI_ACCESS_DENIED   The firmware volume is in the
+                              WriteDisabled state.
+  @retval EFI_DEVICE_ERROR  The block device is not functioning
+                            correctly and could not be written.
+                            The firmware device may have been
+                            partially erased.
+  @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
+                                in the variable argument list do
+                                not exist in the firmware volume.
+
+**/
+EFI_STATUS
+EFIAPI
+FlashFvbDxeErase (
+  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
+  ...
+  )
+{
+  VA_LIST    Args;
+  EFI_LBA    Start;
+  UINTN      Length;
+  EFI_STATUS Status;
+
+  Status = EFI_SUCCESS;
+
+  VA_START (Args, This);
+
+  for (Start = VA_ARG (Args, EFI_LBA);
+       Start != EFI_LBA_LIST_TERMINATOR;
+       Start = VA_ARG (Args, EFI_LBA))
+  {
+    Length = VA_ARG (Args, UINTN);
+    Status = FlashEraseCommand (
+               (UINT8 *)(mNvFlashBase + Start * mFlashBlockSize),
+               Length * mFlashBlockSize
+               );
+  }
+
+  VA_END (Args);
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to do flash erase\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFlashFvbProtocol = {
+  FlashFvbDxeGetAttributes,
+  FlashFvbDxeSetAttributes,
+  FlashFvbDxeGetPhysicalAddress,
+  FlashFvbDxeGetBlockSize,
+  FlashFvbDxeRead,
+  FlashFvbDxeWrite,
+  FlashFvbDxeErase
+};
+
+EFI_STATUS
+EFIAPI
+FlashFvbDxeInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE FvbHandle = NULL;
+  EFI_EVENT  VirtualAddressChangeEvent;
+
+  // Get NV store FV info
+  mFlashBlockSize = FixedPcdGet32 (PcdFvBlockSize);
+  mNvStorageBase = PcdGet64 (PcdFlashNvStorageVariableBase64);
+  mNvStorageSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+                   FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+                   FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n",
+    __FUNCTION__,
+    mNvStorageBase,
+    mNvStorageSize
+    ));
+
+  // Get NV Flash information
+  Status = FlashGetNvRamInfo ((UINT64 *)&mNvFlashBase, (UINT32 *)&mNvFlashSize);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash info\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (mNvFlashSize >= (mNvStorageSize * 2)) {
+    DEBUG ((DEBUG_INFO, "%a: NV store on Flash is valid\n", __FUNCTION__));
+  } else {
+    DEBUG ((DEBUG_ERROR, "%a: NV store on Flash is invalid\n", __FUNCTION__));
+    return EFI_DEVICE_ERROR;
+  }
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  FlashFvbAddressChangeEvent,
+                  NULL,
+                  &gEfiEventVirtualAddressChangeGuid,
+                  &VirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &FvbHandle,
+                  &gEfiFirmwareVolumeBlockProtocolGuid,
+                  &mFlashFvbProtocol,
+                  NULL
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to install Firmware Volume Block protocol\n"));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
new file mode 100644
index 000000000000..6bfbbbebaa85
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
@@ -0,0 +1,283 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Library/ArmSmcLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MmCommunicationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <MmLib.h>
+
+// Convert to string
+#define _STR(x)          #x
+
+// Make sure the argument is expanded before converting to string
+#define STR(x)          _STR(x)
+
+// Use dynamic UEFI_UUID of each build time
+#define UEFI_UUID_BUILD      STR(UEFI_UUID)
+
+EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
+
+STATIC CHAR8 mBuildUuid[sizeof (UEFI_UUID_BUILD)];
+STATIC CHAR8 mStoredUuid[sizeof (UEFI_UUID_BUILD)];
+
+STATIC
+EFI_STATUS
+UefiMmCreateSpiNorReq (
+  VOID   *Data,
+  UINT64 Size
+  )
+{
+  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
+  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
+
+  if (Size != 0) {
+    ASSERT (Data);
+    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
+
+    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Entry point function for the PEIM
+
+  @param FileHandle      Handle of the file being invoked.
+  @param PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS    If we installed our PPI
+
+**/
+EFI_STATUS
+EFIAPI
+FlashPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  UINT64                               FWNvRamStartOffset;
+  EFI_STATUS                           Status;
+  EFI_MM_COMMUNICATE_SPINOR_RES        *MmSpiNorRes;
+  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
+  UINT64                               MmData[5];
+  UINTN                                Size;
+  VOID                                 *NvRamAddress;
+  UINTN                                NvRamSize;
+
+#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
+  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNV2InfoRes;
+  UINT64                               NV2Base, NV2Size;
+#endif
+
+  NvRamAddress = (VOID *)PcdGet64 (PcdFlashNvStorageVariableBase64);
+  NvRamSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
+              FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
+              FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
+
+  /* Find out about the start offset of NVRAM to be passed to SMC */
+  ZeroMem ((VOID *)MmData, sizeof (MmData));
+  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mEfiMmSpiNorReq,
+             &Size
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorNVInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
+    /* Old FW so just exit */
+    return EFI_SUCCESS;
+  }
+  FWNvRamStartOffset = MmSpiNorNVInfoRes->NVBase;
+
+  CopyMem ((VOID *)mBuildUuid, (VOID *)UEFI_UUID_BUILD, sizeof (UEFI_UUID_BUILD));
+  if (MmSpiNorNVInfoRes->NVSize < (NvRamSize * 2 + sizeof (mBuildUuid))) {
+    /* NVRAM size provided by FW is not enough */
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /* We stored BIOS UUID build at the offset NVRAM_SIZE * 2 */
+  ZeroMem ((VOID *)MmData, sizeof (MmData));
+  MmData[0] = MM_SPINOR_FUNC_READ;
+  MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
+  MmData[2] = (UINT64)sizeof (mStoredUuid);
+  MmData[3] = (UINT64)mStoredUuid;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mEfiMmSpiNorReq,
+             &Size
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    return Status;
+  }
+
+  if (CompareMem ((VOID *)mStoredUuid, (VOID *)mBuildUuid, sizeof (mBuildUuid))) {
+    ZeroMem ((VOID *)MmData, sizeof (MmData));
+    MmData[0] = MM_SPINOR_FUNC_ERASE;
+    MmData[1] = (UINT64)FWNvRamStartOffset;
+    MmData[2] = (UINT64)(NvRamSize * 2);
+    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = MmCommunicationCommunicate (
+               (VOID *)&mEfiMmSpiNorReq,
+               &Size
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      return Status;
+    }
+
+    ZeroMem ((VOID *)MmData, sizeof (MmData));
+    MmData[0] = MM_SPINOR_FUNC_WRITE;
+    MmData[1] = (UINT64)FWNvRamStartOffset;
+    MmData[2] = (UINT64)(NvRamSize * 2);
+    MmData[3] = (UINT64)NvRamAddress;
+    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = MmCommunicationCommunicate (
+               (VOID *)&mEfiMmSpiNorReq,
+               &Size
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      return Status;
+    }
+
+    /* Update UUID */
+    ZeroMem ((VOID *)MmData, sizeof (MmData));
+    MmData[0] = MM_SPINOR_FUNC_ERASE;
+    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
+    MmData[2] = (UINT64)sizeof (mBuildUuid);
+    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = MmCommunicationCommunicate (
+               (VOID *)&mEfiMmSpiNorReq,
+               &Size
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      return Status;
+    }
+
+    ZeroMem ((VOID *)MmData, sizeof (MmData));
+    MmData[0] = MM_SPINOR_FUNC_WRITE;
+    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
+    MmData[2] = (UINT64)sizeof (mBuildUuid);
+    MmData[3] = (UINT64)mBuildUuid;
+    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = MmCommunicationCommunicate (
+               (VOID *)&mEfiMmSpiNorReq,
+               &Size
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      return Status;
+    }
+    DEBUG ((DEBUG_INFO, "UUID Changed, Update Storage with FV NVRAM\n"));
+
+    /* Indicate that NVRAM was cleared */
+    PcdSetBoolS (PcdNvramErased, TRUE);
+  } else {
+    /* Copy the stored NVRAM to RAM */
+    ZeroMem ((VOID *)MmData, sizeof (MmData));
+    MmData[0] = MM_SPINOR_FUNC_READ;
+    MmData[1] = (UINT64)FWNvRamStartOffset;
+    MmData[2] = (UINT64)(NvRamSize * 2);
+    MmData[3] = (UINT64)NvRamAddress;
+    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = MmCommunicationCommunicate (
+               (VOID *)&mEfiMmSpiNorReq,
+               &Size
+               );
+    ASSERT_EFI_ERROR (Status);
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      return Status;
+    }
+    DEBUG ((DEBUG_INFO, "Identical UUID, copy stored NVRAM to RAM\n"));
+  }
+
+#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
+  /* Find out about the start offset of NVRAM2 to be passed to SMC */
+  ZeroMem ((VOID *)MmData, sizeof (MmData));
+  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM2_INFO;
+  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = MmCommunicationCommunicate (
+             (VOID *)&mEfiMmSpiNorReq,
+             &Size
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  MmSpiNorNV2InfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
+  if (MmSpiNorNV2InfoRes->Status == MM_SPINOR_RES_SUCCESS) {
+    NV2Base = MmSpiNorNV2InfoRes->NVBase;
+    NV2Size = MmSpiNorNV2InfoRes->NVSize;
+    /* Make sure the requested size is smaller than allocated */
+    if (RAM_BLOCKIO_SIZE <= NV2Size) {
+      /* Copy the ramdisk image to RAM */
+      ZeroMem ((VOID *)MmData, sizeof (MmData));
+      MmData[0] = MM_SPINOR_FUNC_READ;
+      MmData[1] = (UINT64)NV2Base; /* Start virtual address */
+      MmData[2] = (UINT64)RAM_BLOCKIO_SIZE;
+      MmData[3] = (UINT64)RAM_BLOCKIO_START_ADDRESS;
+      UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+
+      Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+      Status = MmCommunicationCommunicate (
+                 (VOID *)&mEfiMmSpiNorReq,
+                 &Size
+                 );
+      ASSERT_EFI_ERROR (Status);
+
+      MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
+      ASSERT (MmSpiNorRes->Status == MM_SPINOR_RES_SUCCESS);
+    }
+
+    BuildMemoryAllocationHob (
+      (EFI_PHYSICAL_ADDRESS)RAM_BLOCKIO_START_ADDRESS,
+      EFI_SIZE_TO_PAGES (RAM_BLOCKIO_SIZE) * EFI_PAGE_SIZE,
+      EfiLoaderData
+      );
+  }
+#endif
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
new file mode 100644
index 000000000000..cd77aed3cfe1
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
@@ -0,0 +1,358 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FlashLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <MmLib.h>
+#include <Protocol/MmCommunication.h>
+
+STATIC EFI_MM_COMMUNICATION_PROTOCOL *mMmCommunicationProtocol = NULL;
+STATIC EFI_MM_COMM_REQUEST           *mCommBuffer              = NULL;
+
+BOOLEAN mIsEfiRuntime;
+UINT8   *mTmpBufVirt;
+UINT8   *mTmpBufPhy;
+
+/**
+  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
+  event. It converts a pointer to a new virtual address.
+
+  @param  Event        Event whose notification function is being invoked.
+  @param  Context      Pointer to the notification function's context
+
+**/
+VOID
+EFIAPI
+FlashLibAddressChangeEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  gRT->ConvertPointer (0x0, (VOID **)&mTmpBufVirt);
+  gRT->ConvertPointer (0x0, (VOID **)&mCommBuffer);
+  gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol);
+
+  mIsEfiRuntime = TRUE;
+}
+
+EFI_STATUS
+EFIAPI
+FlashLibConstructor (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_EVENT  VirtualAddressChangeEvent = NULL;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  mCommBuffer = AllocateRuntimeZeroPool (sizeof (EFI_MM_COMM_REQUEST));
+  ASSERT (mCommBuffer != NULL);
+
+  mTmpBufPhy = AllocateRuntimeZeroPool (EFI_MM_MAX_TMP_BUF_SIZE);
+  mTmpBufVirt = mTmpBufPhy;
+  ASSERT (mTmpBufPhy != NULL);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiMmCommunicationProtocolGuid,
+                  NULL,
+                  (VOID **)&mMmCommunicationProtocol
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+                  TPL_CALLBACK,
+                  FlashLibAddressChangeEvent,
+                  NULL,
+                  &VirtualAddressChangeEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+FlashMmCommunicate (
+  IN OUT VOID  *CommBuffer,
+  IN OUT UINTN *CommSize
+  )
+{
+  if (mMmCommunicationProtocol == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return mMmCommunicationProtocol->Communicate (
+                                     mMmCommunicationProtocol,
+                                     CommBuffer,
+                                     CommSize
+                                     );
+}
+
+STATIC
+EFI_STATUS
+UefiMmCreateSpiNorReq (
+  IN VOID   *Data,
+  IN UINT64 Size
+  )
+{
+  if (mCommBuffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  CopyGuid (&mCommBuffer->EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
+  mCommBuffer->EfiMmHdr.MsgLength = Size;
+
+  if (Size != 0) {
+    ASSERT (Data);
+    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
+
+    CopyMem (mCommBuffer->PayLoad.Data, Data, Size);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Convert Virtual Address to Physical Address at Runtime Services
+
+  @param  VirtualPtr          Virtual Address Pointer
+  @param  Size                Total bytes of the buffer
+
+  @retval Ptr                 Return the pointer of the converted address
+
+**/
+STATIC
+UINT8 *
+ConvertVirtualToPhysical (
+  IN UINT8 *VirtualPtr,
+  IN UINTN Size
+  )
+{
+  if (mIsEfiRuntime) {
+    ASSERT (VirtualPtr != NULL);
+    CopyMem ((VOID *)mTmpBufVirt, (VOID *)VirtualPtr, Size);
+    return (UINT8 *)mTmpBufPhy;
+  }
+
+  return (UINT8 *)VirtualPtr;
+}
+
+/**
+  Convert Physical Address to Virtual Address at Runtime Services
+
+  @param  VirtualPtr          Physical Address Pointer
+  @param  Size                Total bytes of the buffer
+
+**/
+STATIC
+VOID
+ConvertPhysicaltoVirtual (
+  IN UINT8 *PhysicalPtr,
+  IN UINTN Size
+  )
+{
+  if (mIsEfiRuntime) {
+    ASSERT (PhysicalPtr != NULL);
+    CopyMem ((VOID *)PhysicalPtr, (VOID *)mTmpBufVirt, Size);
+  }
+}
+
+EFI_STATUS
+EFIAPI
+FlashGetNvRamInfo (
+  OUT UINT64 *NvRamBase,
+  OUT UINT32 *NvRamSize
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
+  EFI_STATUS                           Status;
+  UINT64                               MmData[5];
+  UINTN                                Size;
+
+  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
+
+  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = FlashMmCommunicate (
+             mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mCommBuffer->PayLoad;
+  if (MmSpiNorNVInfoRes->Status == MM_SPINOR_RES_SUCCESS) {
+    *NvRamBase = MmSpiNorNVInfoRes->NVBase;
+    *NvRamSize = MmSpiNorNVInfoRes->NVSize;
+    DEBUG ((DEBUG_INFO, "NVInfo Base 0x%llx, Size 0x%lx\n", *NvRamBase, *NvRamSize));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlashEraseCommand (
+  IN UINT8  *pBlockAddress,
+  IN UINT32 Length
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+  EFI_STATUS                    Status;
+  UINT64                        MmData[5];
+  UINTN                         Size;
+
+  ASSERT (pBlockAddress != NULL);
+
+  MmData[0] = MM_SPINOR_FUNC_ERASE;
+  MmData[1] = (UINT64)pBlockAddress;
+  MmData[2] = Length;
+
+  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+  Status = FlashMmCommunicate (
+             mCommBuffer,
+             &Size
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
+  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "Flash Erase: Device error %llx\n", MmSpiNorRes->Status));
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlashProgramCommand (
+  IN     UINT8 *pByteAddress,
+  IN     UINT8 *Byte,
+  IN OUT UINTN *Length
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+  EFI_STATUS                    Status;
+  UINT64                        MmData[5];
+  UINTN                         Remain, Size, NumWrite;
+  UINTN                         Count = 0;
+
+  ASSERT (pByteAddress != NULL);
+  ASSERT (Byte != NULL);
+  ASSERT (Length != NULL);
+
+  Remain = *Length;
+  while (Remain > 0) {
+    NumWrite = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
+
+    MmData[0] = MM_SPINOR_FUNC_WRITE;
+    MmData[1] = (UINT64)pByteAddress;
+    MmData[2] = NumWrite;
+    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumWrite);
+
+    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = FlashMmCommunicate (
+               mCommBuffer,
+               &Size
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Flash program: Device error 0x%llx\n", MmSpiNorRes->Status));
+      return EFI_DEVICE_ERROR;
+    }
+
+    Remain -= NumWrite;
+    Count += NumWrite;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlashReadCommand (
+  IN     UINT8 *pByteAddress,
+  OUT    UINT8 *Byte,
+  IN OUT UINTN *Length
+  )
+{
+  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
+  EFI_STATUS                    Status;
+  UINT64                        MmData[5];
+  UINTN                         Remain, Size, NumRead;
+  UINTN                         Count = 0;
+
+  ASSERT (pByteAddress != NULL);
+  ASSERT (Byte != NULL);
+  ASSERT (Length != NULL);
+
+  Remain = *Length;
+  while (Remain > 0) {
+    NumRead = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
+
+    MmData[0] = MM_SPINOR_FUNC_READ;
+    MmData[1] = (UINT64)pByteAddress;
+    MmData[2] = NumRead;
+    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumRead);
+
+    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
+    Status = FlashMmCommunicate (
+               mCommBuffer,
+               &Size
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
+    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
+      DEBUG ((DEBUG_ERROR, "Flash Read: Device error %llx\n", MmSpiNorRes->Status));
+      return EFI_DEVICE_ERROR;
+    }
+
+    ConvertPhysicaltoVirtual (Byte + Count, NumRead);
+    Remain -= NumRead;
+    Count += NumRead;
+  }
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (9 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:37   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
                   ` (23 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

The idea came from DeviceManagerUiLib that all related menu settings can be
placed under a common entry. This change intends to provide a central point
for all platform menus by creating a Platform Manager entry located under
Device Manager entry of UiApp.

New classuuid called gPlatformManagerFormsetGuid was introduced for
platform menus which want to be reached through this Platform Manager.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                             |  19 ++
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                             |   1 +
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf   |  47 +++
 Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h                |  31 ++
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h          |  51 +++
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h       |  28 ++
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c          | 354 ++++++++++++++++++++
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni |  21 ++
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni   |  13 +
 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr     |  29 ++
 10 files changed, 594 insertions(+)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index 26e020715290..a72205aa5316 100755
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -22,12 +22,31 @@ [Defines]
 #
 ################################################################################
 [Includes.common]
+  Include                        # Root include for the package
 
 [LibraryClasses]
 
 [Guids]
   gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
 
+  #
+  # Platform Manager formset UUID
+  #
+  ## Include/Guid/PlatformManagerHii.h
+  gPlatformManagerFormsetGuid  = { 0x83ABD546, 0x7AD9, 0x4DE7, { 0xBD, 0x52, 0x12, 0x23, 0xF6, 0xE8, 0xFD, 0x4B } }
+
+  #
+  # Platform Manager entry UUID
+  #
+  ## Include/Guid/PlatformManagerHii.h
+  gPlatformManagerEntryEventGuid = { 0x28A4731E, 0x14A9, 0x488A, { 0xA8, 0x19, 0xFF, 0x27, 0x80, 0x6E, 0xDB, 0x0E } }
+
+  #
+  # Platform Manager exit UUID
+  #
+  ## Include/Guid/PlatformManagerHii.h
+  gPlatformManagerExitEventGuid  = { 0xE8887242, 0x4EFF, 0x4323, { 0x81, 0xF4, 0xC9, 0x5F, 0xD5, 0x8D, 0x80, 0xD5 } }
+
 [Ppis]
 
 [PcdsFixedAtBuild]
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 65973569a41d..3c47099b8edc 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -649,6 +649,7 @@ [Components.common]
   MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
   MdeModulePkg/Application/UiApp/UiApp.inf {
     <LibraryClasses>
+      NULL|Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
       NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
       NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
       NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
new file mode 100644
index 000000000000..1cc5788bcebb
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
@@ -0,0 +1,47 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PlatformManagerUiLib
+  MODULE_UNI_FILE                = PlatformManagerUiLib.uni
+  FILE_GUID                      = 9264993E-2E15-478A-8928-14573E34C606
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION
+  CONSTRUCTOR                    = PlatformManagerUiLibConstructor
+  DESTRUCTOR                     = PlatformManagerUiLibDestructor
+
+[Sources]
+  PlatformManager.h
+  PlatformManagerVfr.Vfr
+  PlatformManagerStrings.uni
+  PlatformManager.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  DevicePathLib
+  BaseLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  HiiLib
+  UefiLib
+  UefiHiiServicesLib
+
+[Guids]
+  gPlatformManagerFormsetGuid                   ## CONSUMES ## GUID (Indicate the formset class guid to be displayed)
+  gEfiIfrTianoGuid                              ## CONSUMES ## GUID (Extended IFR Guid Opcode)
+  gEfiIfrFrontPageGuid                          ## CONSUMES ## GUID (Indicate the formset in this library need to display in which page)
+  gPlatformManagerEntryEventGuid                ## CONSUMES ## GUID (Indicate enter PlatformManager)
+  gPlatformManagerExitEventGuid                 ## CONSUMES ## GUID (Indicate exit PlatformManager)
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
new file mode 100644
index 000000000000..ee3ca13ddeb1
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
@@ -0,0 +1,31 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_MANAGER_HII_GUID_H_
+#define PLATFORM_MANAGER_HII_GUID_H_
+
+#define PLATFORM_MANAGER_FORMSET_GUID  \
+  { \
+  0x83ABD546, 0x7AD9, 0x4DE7, { 0xBD, 0x52, 0x12, 0x23, 0xF6, 0xE8, 0xFD, 0x4B } \
+  }
+
+#define PLATFORM_MANAGER_ENTRY_EVENT_GUID  \
+  { \
+  0x28A4731E, 0x14A9, 0x488A, { 0xA8, 0x19, 0xFF, 0x27, 0x80, 0x6E, 0xDB, 0x0E } \
+  }
+
+#define PLATFORM_MANAGER_EXIT_EVENT_GUID  \
+  { \
+  0xE8887242, 0x4EFF, 0x4323, { 0x81, 0xF4, 0xC9, 0x5F, 0xD5, 0x8D, 0x80, 0xD5 } \
+  }
+
+extern EFI_GUID gPlatformManagerFormsetGuid;
+extern EFI_GUID gPlatformManagerEntryEventGuid;
+extern EFI_GUID gPlatformManagerExitEventGuid;
+
+#endif
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
new file mode 100644
index 000000000000..49157e0cea47
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
@@ -0,0 +1,51 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_MANAGER_H_
+#define PLATFORM_MANAGER_H_
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformManagerHii.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/UefiLib.h>
+
+#include "PlatformManagerVfr.h"
+
+//
+// These are the VFR compiler generated data representing our VFR data.
+//
+extern UINT8 PlatformManagerVfrBin[];
+extern UINT8 PlatformManagerUiLibStrings[];
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+typedef struct {
+  ///
+  /// Platform Manager HII relative handles
+  ///
+  EFI_HII_HANDLE HiiHandle;
+  EFI_HANDLE     DriverHandle;
+
+} PLATFORM_MANAGER_CALLBACK_DATA;
+
+#endif
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
new file mode 100644
index 000000000000..205907d3777a
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
@@ -0,0 +1,28 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_MANAGER_VFR_H_
+#define PLATFORM_MANAGER_VFR_H_
+
+#define FORMSET_GUID \
+  { \
+  0x6E7233C5, 0x2B79, 0x4383, { 0x81, 0x46, 0xD8, 0x6A, 0x9F, 0x0A, 0x0B, 0x99 } \
+  }
+
+//
+// These are defined as the same with vfr file
+//
+#define LABEL_FORM_ID_OFFSET                 0x0100
+#define ENTRY_KEY_OFFSET                     0x4000
+
+#define PLATFORM_MANAGER_FORM_ID             0x1000
+
+#define LABEL_ENTRY_LIST                     0x1100
+#define LABEL_END                            0xffff
+
+#endif /* PLATFORM_MANAGER_VFR_H_ */
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
new file mode 100644
index 000000000000..1872aa80ed18
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
@@ -0,0 +1,354 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformManager.h"
+
+PLATFORM_MANAGER_CALLBACK_DATA gPlatformManagerPrivate = {
+  NULL,
+  NULL
+};
+
+EFI_GUID mPlatformManagerGuid = FORMSET_GUID;
+
+HII_VENDOR_DEVICE_PATH mPlatformManagerHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    //
+    // {FC587265-0750-44D1-B68D-D1DDD3F29B0B}
+    //
+    { 0xFC587265, 0x0750, 0x44D1, {0xB6, 0x8D, 0xD1, 0xDD, 0xD3, 0xF2, 0x9B, 0x0B} }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+/**
+  Extract device path for given HII handle and class guid.
+
+  @param Handle          The HII handle.
+
+  @retval  NULL          Fail to get the device path string.
+  @return  PathString    Get the device path string.
+
+**/
+CHAR16 *
+PmExtractDevicePathFromHiiHandle (
+  IN EFI_HII_HANDLE Handle
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE DriverHandle;
+
+  ASSERT (Handle != NULL);
+
+  if (Handle == NULL) {
+    return NULL;
+  }
+
+  Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
+  if (EFI_ERROR (Status)) {
+    return NULL;
+  }
+  //
+  // Get device path string.
+  //
+  return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
+}
+
+/**
+  Dynamic create Hii information for Platform Manager.
+
+  @param   NextShowFormId     The FormId which need to be show.
+
+**/
+VOID
+CreatePlatformManagerForm (
+  IN EFI_FORM_ID NextShowFormId
+  )
+{
+  UINTN              Index;
+  EFI_STRING         String;
+  EFI_STRING_ID      Token;
+  EFI_STRING_ID      TokenHelp;
+  EFI_HII_HANDLE     *HiiHandles;
+  EFI_HII_HANDLE     HiiHandle;
+  EFI_GUID           FormSetGuid;
+  VOID               *StartOpCodeHandle;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  EFI_IFR_GUID_LABEL *EndLabel;
+  CHAR16             *DevicePathStr;
+  EFI_STRING_ID      DevicePathId;
+  EFI_IFR_FORM_SET   *Buffer;
+  UINTN              BufferSize;
+  UINT8              ClassGuidNum;
+  EFI_GUID           *ClassGuid;
+  UINTN              TempSize;
+  UINT8              *Ptr;
+  EFI_STATUS         Status;
+
+  TempSize = 0;
+  BufferSize = 0;
+  Buffer = NULL;
+
+  HiiHandle = gPlatformManagerPrivate.HiiHandle;
+
+  //
+  // Allocate space for creation of UpdateData Buffer
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  ASSERT (StartLabel != NULL);
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  //
+  // According to the next show Form id(mNextShowFormId) to decide which form need to update.
+  //
+  StartLabel->Number       = (UINT16)(LABEL_FORM_ID_OFFSET + NextShowFormId);
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  ASSERT (EndLabel != NULL);
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  //
+  // Get all the Hii handles
+  //
+  HiiHandles = HiiGetHiiHandles (NULL);
+  ASSERT (HiiHandles != NULL);
+
+  //
+  // Search for formset of each class type
+  //
+  for (Index = 0; HiiHandles[Index] != NULL; Index++) {
+    Status = HiiGetFormSetFromHiiHandle (HiiHandles[Index], &Buffer,&BufferSize);
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    Ptr = (UINT8 *)Buffer;
+
+    while(TempSize < BufferSize) {
+      TempSize += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
+      if (((EFI_IFR_OP_HEADER *)Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
+        Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
+        continue;
+      }
+
+      ClassGuidNum = (UINT8)(((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
+      ClassGuid = (EFI_GUID *)(VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
+      while (ClassGuidNum-- > 0) {
+        if (CompareGuid (&gPlatformManagerFormsetGuid, ClassGuid)== 0) {
+          ClassGuid++;
+          continue;
+        }
+
+        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);
+        if (String == NULL) {
+          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
+          ASSERT (String != NULL);
+        }
+        Token = HiiSetString (HiiHandle, 0, String, NULL);
+        FreePool (String);
+
+        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);
+        if (String == NULL) {
+          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
+          ASSERT (String != NULL);
+        }
+        TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
+        FreePool (String);
+
+        CopyMem (&FormSetGuid, &((EFI_IFR_FORM_SET *)Ptr)->Guid, sizeof (EFI_GUID));
+
+        if (NextShowFormId == PLATFORM_MANAGER_FORM_ID) {
+          DevicePathStr = PmExtractDevicePathFromHiiHandle (HiiHandles[Index]);
+          DevicePathId  = 0;
+          if (DevicePathStr != NULL) {
+            DevicePathId =  HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
+            FreePool (DevicePathStr);
+          }
+
+          HiiCreateGotoExOpCode (
+            StartOpCodeHandle,
+            0,
+            Token,
+            TokenHelp,
+            0,
+            (EFI_QUESTION_ID)(Index + ENTRY_KEY_OFFSET),
+            0,
+            &FormSetGuid,
+            DevicePathId
+            );
+        }
+        break;
+      }
+
+      Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
+    }
+
+    FreePool (Buffer);
+    Buffer = NULL;
+    TempSize = 0;
+    BufferSize = 0;
+  }
+
+  HiiUpdateForm (
+    HiiHandle,
+    &mPlatformManagerGuid,
+    NextShowFormId,
+    StartOpCodeHandle,
+    EndOpCodeHandle
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+  FreePool (HiiHandles);
+}
+
+/**
+  Install Boot Manager Menu driver.
+
+  @param ImageHandle     The image handle.
+  @param SystemTable     The system table.
+
+  @retval  EFI_SUCEESS  Install Boot manager menu success.
+  @retval  Other        Return error status.
+
+**/
+EFI_STATUS
+EFIAPI
+PlatformManagerUiLibConstructor (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  PlatformUiEntryEvent;
+
+  gPlatformManagerPrivate.DriverHandle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &gPlatformManagerPrivate.DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mPlatformManagerHiiVendorDevicePath,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Publish our HII data.
+  //
+  gPlatformManagerPrivate.HiiHandle = HiiAddPackages (
+                                        &mPlatformManagerGuid,
+                                        gPlatformManagerPrivate.DriverHandle,
+                                        PlatformManagerVfrBin,
+                                        PlatformManagerUiLibStrings,
+                                        NULL
+                                        );
+  if (gPlatformManagerPrivate.HiiHandle != NULL) {
+    //
+    // Update platform manager page
+    //
+    CreatePlatformManagerForm (PLATFORM_MANAGER_FORM_ID);
+  } else {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to add Hii package\n", __FUNCTION__));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Signal Entry event
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  EfiEventEmptyFunction,
+                  NULL,
+                  &gPlatformManagerEntryEventGuid,
+                  &PlatformUiEntryEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  gBS->SignalEvent (PlatformUiEntryEvent);
+  gBS->CloseEvent (PlatformUiEntryEvent);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unloads the application and its installed protocol.
+
+  @param  ImageHandle     Handle that identifies the image to be unloaded.
+  @param  SystemTable     The system table.
+
+  @retval EFI_SUCCESS           The image has been unloaded.
+**/
+EFI_STATUS
+EFIAPI
+PlatformManagerUiLibDestructor (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  PlatformUiExitEvent;
+
+  Status = gBS->UninstallMultipleProtocolInterfaces (
+                  gPlatformManagerPrivate.DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mPlatformManagerHiiVendorDevicePath,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  HiiRemovePackages (gPlatformManagerPrivate.HiiHandle);
+
+  // Signal Exit event
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  EfiEventEmptyFunction,
+                  NULL,
+                  &gPlatformManagerExitEventGuid,
+                  &PlatformUiExitEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+  gBS->SignalEvent (PlatformUiExitEvent);
+  gBS->CloseEvent (PlatformUiExitEvent);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
new file mode 100644
index 000000000000..3bb39413bc4b
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
@@ -0,0 +1,21 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+/=#
+
+#langdef   en-US "English"
+
+#string STR_EDKII_MENU_TITLE           #language en-US  "Platform Manager"
+#string STR_EDKII_MENU_HELP            #language en-US  "This selection will take you to the Platform Manager"
+#string STR_PLATFORM_LIST              #language en-US  "Platform Configuration"
+#string STR_MISSING_STRING             #language en-US  "Missing String"
+#string STR_EMPTY_STRING               #language en-US  ""
+#string STR_EXIT_STRING                #language en-US  "Press ESC to exit."
+//
+// Ensure that this is the last string.  We are using it programmatically
+// to do string token re-usage settings for the Device Manager since we are
+// constantly recreating this page based on HII population.
+////
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
new file mode 100644
index 000000000000..217a7e999dab
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
@@ -0,0 +1,13 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT
+#language en-US
+"Platform Manager Library used by UiApp"
+
+#string STR_MODULE_DESCRIPTION
+#language en-US
+"Platform Manager Library used by UiApp"
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
new file mode 100644
index 000000000000..bfda75319416
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
@@ -0,0 +1,29 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/HiiPlatformSetupFormset.h>
+#include "PlatformManagerVfr.h"
+
+formset
+  guid      = FORMSET_GUID,
+  title     = STRING_TOKEN(STR_EDKII_MENU_TITLE),
+  help      = STRING_TOKEN(STR_EDKII_MENU_HELP),
+  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
+
+  form formid = PLATFORM_MANAGER_FORM_ID,
+    title  = STRING_TOKEN(STR_EDKII_MENU_TITLE);
+    subtitle text = STRING_TOKEN(STR_PLATFORM_LIST);
+
+    label LABEL_ENTRY_LIST;
+    label LABEL_END;
+
+    subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+    subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
+    subtitle text = STRING_TOKEN(STR_EXIT_STRING);
+  endform;
+endformset;
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (10 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:44   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
                   ` (22 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

The AcpiPccLib provides functions to allocate and get the physical
address of PCC shared memory.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                |   2 +
 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf |  41 ++++
 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h        | 166 ++++++++++++++
 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c   | 241 ++++++++++++++++++++
 4 files changed, 450 insertions(+)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index a72205aa5316..8193ff617600 100755
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -25,6 +25,8 @@ [Includes.common]
   Include                        # Root include for the package
 
 [LibraryClasses]
+  ##  @libraryclass  Provides functions to create the ACPI PCCT Table which which advertises PCC mailbox channel information.
+  AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
 
 [Guids]
   gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
new file mode 100755
index 000000000000..9f38e1e77145
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
@@ -0,0 +1,41 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = AcpiPccLib
+  FILE_GUID                     = 790519F0-F344-11E3-AC10-0800200C9A66
+  MODULE_TYPE                   = BASE
+  VERSION_STRING                = 1.0
+  LIBRARY_CLASS                 = AcpiPccLib
+
+[Sources.common]
+  AcpiPccLib.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  MailboxInterfaceLib
+  PrintLib
+  SystemFirmwareInterfaceLib
+  TimerLib
+  UefiBootServicesTableLib
+
+[Pcd]
+  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
+  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
new file mode 100644
index 000000000000..d8ae48e7612a
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
@@ -0,0 +1,166 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_PCC_LIB_H_
+#define ACPI_PCC_LIB_H_
+
+#include <Library/MailboxInterfaceLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+
+// Send a message with dummy payload is to advertise the shared memory address
+#define DB_PCC_PAYLOAD_DUMMY         0x0F000000
+
+#define DB_PCC_MSG_PAYLOAD_SIZE      12 // Number of Bytes
+
+//
+// ACPI Platform Communication Channel (PCC)
+//
+#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE  0x50434300 // "PCC"
+#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE       0x4000     // Number of Bytes
+
+//
+// Reserved Doorbell Mask
+// Bit 0 --> 31 correspond to Doorbell 0 --> 31
+//
+// List of reserved Doorbells
+//  1. Doorbell 4: PCIe Hot-plug
+//
+#define ACPI_PCC_AVAILABLE_DOORBELL_MASK        0xEFFFEFFF
+#define ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS   1
+
+// Supported doorbells in the platform
+#define ACPI_PCC_MAX_DOORBELL              (NUMBER_OF_DOORBELLS_PER_SOCKET * PLATFORM_CPU_MAX_SOCKET)
+
+// Valid doorbells for use
+#define ACPI_PCC_MAX_SUBPACE_PER_SOCKET    (NUMBER_OF_DOORBELLS_PER_SOCKET - ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS)
+#define ACPI_PCC_MAX_SUBPACE               (ACPI_PCC_MAX_SUBPACE_PER_SOCKET * PLATFORM_CPU_MAX_SOCKET)
+
+#define ACPI_PCC_NOMINAL_LATENCY_US                1000 // us
+#define ACPI_PCC_MAX_PERIODIC_ACCESS_RATE          0    // no limitation
+#define ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US        0
+
+// Polling interval for PCC Command Complete
+#define ACPI_PCC_COMMAND_POLL_INTERVAL_US          10
+
+#define ACPI_PCC_COMMAND_POLL_COUNT  (ACPI_PCC_NOMINAL_LATENCY_US / ACPI_PCC_COMMAND_POLL_INTERVAL_US)
+
+//
+// PCC subspace 2 (PMpro Doorbell Channel 2) is used for ACPI CPPC
+//
+#define ACPI_PCC_CPPC_DOORBELL_ID                  (PMproDoorbellChannel2)
+
+#define ACPI_PCC_CPPC_NOMINAL_LATENCY_US           100
+#define ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US   110
+
+
+/**
+  Allocate memory pages for the PCC shared memory region.
+
+  @param  PccSharedMemoryPtr     Pointer to the shared memory address.
+  @param  NumberOfSubspaces      Number of subspaces slot in the shared memory region.
+
+  @retval EFI_SUCCESS            Send the message successfully.
+  @retval EFI_INVALID_PARAMETER  TheNumberOfSubspaces is out of the valid range.
+  @retval Otherwise              Return errors from call to gBS->AllocatePages().
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccAllocateSharedMemory (
+  OUT EFI_PHYSICAL_ADDRESS *PccSharedMemPointer,
+  IN  UINT16               NumberOfSubspaces
+  );
+
+/**
+  Free the whole shared memory region that is allocated by
+  the AcpiPccAllocateSharedMemory() function.
+
+**/
+VOID
+EFIAPI
+AcpiPccFreeSharedMemory (
+  VOID
+  );
+
+/**
+  Send a PCC message to the platform (SMpro/PMpro).
+
+  @param  Socket    The Socket ID.
+  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
+  @param  Subspace  The Subspace index in the shared memory region.
+
+  @retval EFI_SUCCESS            Send the message successfully.
+  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
+                                 The data buffer is NULL or the size of data buffer is zero.
+  @retval EFI_NOT_READY          The shared memory region is NULL.
+  @retval EFI_TIMEOUT            Timeout occurred when polling the PCC Command Complete bit.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccSendMessage (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell,
+  IN UINT16 Subspace,
+  IN VOID   *DataBuffer,
+  IN UINT32 DataSize
+  );
+
+/**
+  Initialize the shared memory in the SMpro/PMpro Doorbell handler.
+  This function is to advertise the shared memory region address to the platform (SMpro/PMpro).
+
+  @param  Socket    The Socket ID.
+  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
+  @param  Subspace  The Subspace index in the shared memory region.
+
+  @retval EFI_SUCCESS            Initialize successfully.
+  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccInitSharedMemory (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell,
+  IN UINT16 Subspace
+  );
+
+/**
+  Unmask the Doorbell interrupt.
+
+  @param  Socket    The Socket ID.
+  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
+
+  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
+  @retval EFI_INVALID_PARAMETER  The Socket or Doorbell is out of the valid range.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccUnmaskDoorbellInterrupt (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell
+  );
+
+/**
+  Check whether the Doorbell is reserved or not.
+
+  @param  Doorbell   The Doorbell index from supported Doorbells.
+
+  @retval TRUE         The Doorbell is reserved for private use or invalid.
+  @retval FALSE        The Doorbell is available.
+
+**/
+BOOLEAN
+EFIAPI
+AcpiPccIsDoorbellReserved (
+  IN UINT16 Doorbell
+  );
+
+#endif /* ACPI_PCC_LIB_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
new file mode 100644
index 000000000000..48e0b9e876ef
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
@@ -0,0 +1,241 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/AcpiPccLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Platform/Ac01.h>
+
+STATIC EFI_PHYSICAL_ADDRESS mPccSharedMemoryAddress;
+STATIC UINTN                mPccSharedMemorySize;
+
+EFI_STATUS
+AcpiPccGetSharedMemoryAddress (
+  IN  UINT8  Socket,
+  IN  UINT16 Subspace,
+  OUT VOID   **SharedMemoryAddress
+  )
+{
+  if (Socket >= PLATFORM_CPU_MAX_SOCKET
+      || Subspace >= ACPI_PCC_MAX_SUBPACE)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (mPccSharedMemoryAddress == 0) {
+    return EFI_NOT_READY;
+  }
+
+  *SharedMemoryAddress = (VOID *)(mPccSharedMemoryAddress + ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Allocate memory pages for the PCC shared memory region.
+
+  @param  PccSharedMemoryPtr     Pointer to the shared memory address.
+  @param  NumberOfSubspaces      Number of subspaces slot in the shared memory region.
+
+  @retval EFI_SUCCESS            Send the message successfully.
+  @retval EFI_INVALID_PARAMETER  TheNumberOfSubspaces is out of the valid range.
+  @retval Otherwise              Return errors from call to gBS->AllocatePages().
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccAllocateSharedMemory (
+  OUT EFI_PHYSICAL_ADDRESS *PccSharedMemoryPtr,
+  IN  UINT16               NumberOfSubspaces
+  )
+{
+  EFI_STATUS Status;
+
+  if (NumberOfSubspaces > ACPI_PCC_MAX_SUBPACE) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  mPccSharedMemorySize = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * NumberOfSubspaces;
+
+  Status = gBS->AllocatePages (
+                  AllocateAnyPages,
+                  EfiRuntimeServicesData,
+                  EFI_SIZE_TO_PAGES (mPccSharedMemorySize),
+                  &mPccSharedMemoryAddress
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to allocate PCC shared memory\n"));
+    mPccSharedMemorySize = 0;
+    return Status;
+  }
+
+  *PccSharedMemoryPtr = mPccSharedMemoryAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Free the whole shared memory region that is allocated by
+  the AcpiPccAllocateSharedMemory() function.
+
+**/
+VOID
+EFIAPI
+AcpiPccFreeSharedMemory (
+  VOID
+  )
+{
+  if (mPccSharedMemoryAddress != 0 && mPccSharedMemorySize != 0)
+  {
+    gBS->FreePages (
+           mPccSharedMemoryAddress,
+           EFI_SIZE_TO_PAGES (mPccSharedMemorySize)
+           );
+
+    mPccSharedMemoryAddress = 0;
+  }
+}
+
+/**
+  Initialize the shared memory in the SMpro/PMpro Doorbell handler.
+  This function is to advertise the shared memory region address to the platform (SMpro/PMpro).
+
+  @param  Socket    The Socket ID.
+  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
+  @param  Subspace  The Subspace index in the shared memory region.
+
+  @retval EFI_SUCCESS            Initialize successfully.
+  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccInitSharedMemory (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell,
+  IN UINT16 Subspace
+  )
+{
+  EFI_STATUS                                            Status;
+  EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER *PcctSharedMemoryRegion;
+  UINT32                                                CommunicationData;
+  UINTN                                                 Timeout;
+
+  if (Socket >= PLATFORM_CPU_MAX_SOCKET
+      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
+      || Subspace >= ACPI_PCC_MAX_SUBPACE)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = AcpiPccGetSharedMemoryAddress (Socket, Subspace, (VOID **)&PcctSharedMemoryRegion);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Zero shared memory region for each PCC subspace
+  //
+  SetMem (
+    (VOID *)PcctSharedMemoryRegion,
+    sizeof (EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER) + DB_PCC_MSG_PAYLOAD_SIZE,
+    0
+    );
+
+  // Advertise shared memory address to Platform (SMpro/PMpro)
+  // by ringing the doorbell with dummy PCC message
+  //
+  CommunicationData = DB_PCC_PAYLOAD_DUMMY;
+
+  //
+  // Write Data into Communication Space Region
+  //
+  CopyMem ((VOID *)(PcctSharedMemoryRegion + 1), &CommunicationData, sizeof (CommunicationData));
+
+  PcctSharedMemoryRegion->Status.CommandComplete = 0;
+  PcctSharedMemoryRegion->Signature = ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE | Subspace;
+
+  Status = MailboxMsgSetPccSharedMem (Socket, Doorbell, TRUE, (UINT64)PcctSharedMemoryRegion);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Failed to send mailbox message!\n", __FUNCTION__));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  //
+  // Polling CMD_COMPLETE bit
+  //
+  Timeout = ACPI_PCC_COMMAND_POLL_COUNT;
+  while (PcctSharedMemoryRegion->Status.CommandComplete != 1) {
+    if (--Timeout <= 0) {
+      DEBUG ((DEBUG_ERROR, "%a - Timeout occurred when polling the PCC Status Complete\n", __FUNCTION__));
+      return EFI_TIMEOUT;
+    }
+    MicroSecondDelay (ACPI_PCC_COMMAND_POLL_INTERVAL_US);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Unmask the Doorbell interrupt.
+
+  @param  Socket    The Socket ID.
+  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
+
+  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
+  @retval EFI_INVALID_PARAMETER  The Socket or Doorbell is out of the valid range.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiPccUnmaskDoorbellInterrupt (
+  IN UINT8  Socket,
+  IN UINT16 Doorbell
+  )
+{
+  return MailboxUnmaskInterrupt (Socket, Doorbell);
+}
+
+/**
+  Check whether the Doorbell is reserved or not.
+
+  @param  Doorbell   The Doorbell index from supported Doorbells.
+
+  @retval TRUE         The Doorbell is reserved for private use or invalid.
+  @retval FALSE        The Doorbell is available.
+
+**/
+BOOLEAN
+EFIAPI
+AcpiPccIsDoorbellReserved (
+  IN UINT16 Doorbell
+  )
+{
+  if (Doorbell >= ACPI_PCC_MAX_DOORBELL) {
+    ASSERT (FALSE);
+    return TRUE;
+  }
+
+  if (((1 << Doorbell) & ACPI_PCC_AVAILABLE_DOORBELL_MASK) == 0) {
+    //
+    // The doorbell is reserved for private use.
+    //
+    return TRUE;
+  }
+
+  return FALSE;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (11 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:47   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
                   ` (21 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

The AcpiHelperLib provides functions to update the ACPI DSDT table after
this table is installed.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                      |   3 +
 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf |  33 +++
 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h           | 109 +++++++++
 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c   | 246 ++++++++++++++++++++
 4 files changed, 391 insertions(+)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index 8193ff617600..0ac075047276 100755
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -28,6 +28,9 @@ [LibraryClasses]
   ##  @libraryclass  Provides functions to create the ACPI PCCT Table which which advertises PCC mailbox channel information.
   AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
 
+  ##  @libraryclass  Provides helper functions to update ACPI DSDT Table.
+  AcpiHelperLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
+
 [Guids]
   gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
 
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
new file mode 100755
index 000000000000..df26a2810bd3
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
@@ -0,0 +1,33 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = AcpiHelperLib
+  FILE_GUID                      = E4F89216-E722-11E6-BF01-FE55135034F3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = AcpiHelperLib
+
+[Sources]
+  AcpiHelperLib.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  UefiBootServicesTableLib
+  UefiLib
+
+[Protocols]
+  gEfiAcpiSdtProtocolGuid         ## COMSUMED
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
new file mode 100644
index 000000000000..f98118a0f6a2
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
@@ -0,0 +1,109 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPIHELPERLIB_H_
+#define ACPIHELPERLIB_H_
+
+#include <Uefi.h>
+
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+#define MAX_ACPI_NODE_PATH    256
+
+
+typedef struct {
+  EFI_ACPI_SDT_HEADER    *Table;
+  EFI_ACPI_TABLE_VERSION TableVersion;
+  UINTN                  TableKey;
+} ACPI_TABLE_DESCRIPTOR;
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in]  Buffer          Pointer to buffer to checksum
+  @param[in]  Size            Number of bytes to checksum
+
+**/
+VOID
+EFIAPI
+AcpiTableChecksum (
+  IN UINT8 *Buffer,
+  IN UINTN Size
+  );
+
+/**
+  This function calculates and updates the ACPI DSDT checksum.
+
+  @param[in]  AcpiTableProtocol          Pointer to ACPI table protocol
+
+**/
+VOID
+EFIAPI
+AcpiDSDTUpdateChecksum (
+  IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol
+  );
+
+/**
+  This function update the _STA value of a ACPI DSDT node.
+
+  @param[in]  AsciiNodePath          Pointer to the path of the node.
+  @param[in]  NodeStatus             The status value needed to be updated.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiDSDTSetNodeStatusValue (
+  IN CHAR8 *AsciiNodePath,
+  IN CHAR8 NodeStatus
+  );
+
+/**
+  This function return the handle of the ACPI DSDT table.
+
+  @param[in]   AcpiTableProtocol          Pointer to ACPI table protocol.
+  @param[out]  TableHandle                Pointer to table handle.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiOpenDSDT (
+  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
+  OUT EFI_ACPI_HANDLE       *TableHandle
+  );
+
+/**
+  This function return the ACPI table matching a signature.
+
+  @param[in]   TableDescriptor        Pointer to ACPI table descriptor.
+  @param[in]   TableSignature         ACPI table signature.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiGetTable (
+  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol,
+  IN  UINT32                TableSignature,
+  OUT ACPI_TABLE_DESCRIPTOR *TableDescriptor
+  );
+
+/**
+  Check whether the ACPI table is installed or not.
+
+  @param[in]    AcpiTableSignature        ACPI table signature.
+
+  @retval       TRUE     Already installed.
+  @retval       FALSE    Not installed.
+
+**/
+BOOLEAN
+EFIAPI
+IsAcpiInstalled (
+  IN UINT32 AcpiTableSignature
+  );
+
+#endif /* ACPIHELPERLIB_H_ */
diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
new file mode 100644
index 000000000000..4a85dd5dc8c5
--- /dev/null
+++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
@@ -0,0 +1,246 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/Acpi63.h>
+#include <IndustryStandard/AcpiAml.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/AcpiTable.h>
+
+#define DSDT_SIGNATURE                  0x54445344
+#define FADT_SIGNATURE                  0x50434146
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in]  Buffer          Pointer to buffer to checksum
+  @param[in]  Size            Number of bytes to checksum
+
+**/
+VOID
+EFIAPI
+AcpiTableChecksum (
+  IN UINT8 *Buffer,
+  IN UINTN Size
+  )
+{
+  UINTN ChecksumOffset;
+
+  ASSERT (Buffer != NULL);
+
+  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
+
+  /*
+   * Set checksum to 0 first.
+   */
+  Buffer[ChecksumOffset] = 0;
+
+  /*
+   * Update checksum value.
+   */
+  Buffer[ChecksumOffset] = 0 - CalculateSum8 (Buffer, Size);
+}
+
+/**
+  This function calculates and updates the ACPI DSDT checksum.
+
+  @param[in]  AcpiTableProtocol          Pointer to ACPI table protocol
+
+**/
+VOID
+EFIAPI
+AcpiDSDTUpdateChecksum (
+  IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol
+  )
+{
+  EFI_STATUS                                Status = EFI_SUCCESS;
+  EFI_ACPI_SDT_HEADER                       *DsdtHdr = NULL;
+  ACPI_TABLE_DESCRIPTOR                     TableDescriptor;
+  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPtr = NULL;
+
+  ASSERT (AcpiTableProtocol != NULL);
+
+  Status = AcpiGetTable (AcpiTableProtocol, FADT_SIGNATURE, &TableDescriptor);
+  if (EFI_ERROR (Status) || TableDescriptor.Table == NULL) {
+    return;
+  }
+
+  FadtPtr = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)TableDescriptor.Table;
+
+  if (FadtPtr->Dsdt) {
+    DsdtHdr = (EFI_ACPI_SDT_HEADER *)(UINT64)FadtPtr->Dsdt;
+  } else if (FadtPtr->XDsdt) {
+    DsdtHdr = (EFI_ACPI_SDT_HEADER *)FadtPtr->XDsdt;
+  }
+
+  if (DsdtHdr != NULL) {
+    AcpiTableChecksum ((UINT8 *)DsdtHdr, DsdtHdr->Length);
+  }
+}
+
+/**
+  This function return the handle of the ACPI DSDT table.
+
+  @param[in]   AcpiTableProtocol          Pointer to ACPI table protocol.
+  @param[out]  TableHandle                Pointer to table handle.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiOpenDSDT (
+  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
+  OUT EFI_ACPI_HANDLE       *TableHandle
+  )
+{
+  EFI_STATUS            Status = EFI_SUCCESS;
+  ACPI_TABLE_DESCRIPTOR TableDescriptor;
+
+  Status = AcpiGetTable (AcpiTableProtocol, DSDT_SIGNATURE, &TableDescriptor);
+  if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) {
+    return AcpiTableProtocol->OpenSdt (TableDescriptor.TableKey, TableHandle);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiDSDTSetNodeStatusValue (
+  IN CHAR8 *AsciiNodePath,
+  IN CHAR8 NodeStatus
+  )
+{
+  EFI_STATUS            Status = EFI_SUCCESS;
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
+  EFI_ACPI_HANDLE       TableHandle;
+  EFI_ACPI_HANDLE       ChildHandle;
+  EFI_ACPI_DATA_TYPE    DataType;
+  CHAR8                 *Buffer;
+  UINTN                 DataSize;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
+    return Status;
+  }
+
+  /* Open DSDT Table */
+  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = AcpiTableProtocol->FindPath (TableHandle, AsciiNodePath, &ChildHandle);
+  if (EFI_ERROR (Status)) {
+    /* Close DSDT Table */
+    AcpiTableProtocol->Close (TableHandle);
+    return EFI_SUCCESS;
+  }
+
+  Status = AcpiTableProtocol->GetOption (ChildHandle, 2, &DataType, (VOID *)&Buffer, &DataSize);
+  if (Status == EFI_SUCCESS && Buffer[2] == AML_BYTE_PREFIX) {
+    /*
+     * Only patch when the initial value is byte object.
+     */
+    Buffer[3] = NodeStatus;
+  }
+
+  /* Close DSDT Table */
+  AcpiTableProtocol->Close (TableHandle);
+
+  /* Update DSDT Checksum */
+  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function return the ACPI table matching a signature.
+
+  @param[in]   AcpiTableSdtProtocol   Pointer to ACPI SDT protocol.
+  @param[in]   TableSignature         ACPI table signature.
+  @param[out]  TableDescriptor        Pointer to ACPI table descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+AcpiGetTable (
+  IN  EFI_ACPI_SDT_PROTOCOL  *AcpiTableSdtProtocol,
+  IN  UINT32                 TableSignature,
+  OUT ACPI_TABLE_DESCRIPTOR  *TableDescriptor
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  UINTN      TableIndex = 0;
+
+  ASSERT (AcpiTableSdtProtocol != NULL);
+  ASSERT (TableDescriptor != NULL);
+
+  /*
+   * Search for ACPI Table Signature
+   */
+  while (!EFI_ERROR (Status)) {
+    Status = AcpiTableSdtProtocol->GetAcpiTable (
+                                     TableIndex,
+                                     &(TableDescriptor->Table),
+                                     &(TableDescriptor->TableVersion),
+                                     &(TableDescriptor->TableKey)
+                                     );
+    if (!EFI_ERROR (Status)) {
+      TableIndex++;
+
+      if (((EFI_ACPI_SDT_HEADER *)TableDescriptor->Table)->Signature == TableSignature) {
+        return EFI_SUCCESS;
+      }
+    }
+  }
+
+  /* Nothing was found.  Clear the table descriptor. */
+  ZeroMem (&TableDescriptor, sizeof (TableDescriptor));
+
+  return EFI_NOT_FOUND;
+}
+
+/**
+  Check whether the ACPI table is installed or not.
+
+  @param[in]    AcpiTableSignature        ACPI table signature.
+
+  @retval       TRUE     Already installed.
+  @retval       FALSE    Not installed.
+
+**/
+BOOLEAN
+EFIAPI
+IsAcpiInstalled (
+  IN UINT32 AcpiTableSignature
+  )
+{
+  EFI_STATUS            Status;
+  ACPI_TABLE_DESCRIPTOR TableDescriptor;
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol = NULL;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = AcpiGetTable (AcpiTableSdtProtocol, AcpiTableSignature, &TableDescriptor);
+  if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) {
+    return TRUE;
+  }
+
+  return FALSE;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (12 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-04 23:50   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
                   ` (20 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Add various ACPI tables for the Mt. Jade platform including: DSDT, SPCR,
DBG2, GTDT, FACP, SSDT, MADT, PPTT, PCCT, SLIT, SRAT, and NFIT.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |    8 +
 Platform/Ampere/JadePkg/Jade.dsc                                    |   23 +
 Platform/Ampere/JadePkg/Jade.fdf                                    |    8 +
 Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf                   |   20 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf |   75 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf |   44 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h          |  121 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h          |   49 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h      |   76 +
 Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h                  |   37 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c          |  457 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c          |  445 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c          |  351 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c          |  599 +++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c          |  196 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c   |  178 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c          |  378 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c          |  190 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c          |  274 +
 Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi                       | 5639 ++++++++++++++++++++
 Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi                       | 5639 ++++++++++++++++++++
 Platform/Ampere/JadePkg/AcpiTables/CPU.asi                          |  127 +
 Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl                         |  575 ++
 Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi                     |  217 +
 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi                 |  681 +++
 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi                       | 2078 ++++++++
 Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi                       | 2087 ++++++++
 Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi                       | 1303 +++++
 Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi                       | 1303 +++++
 Platform/Ampere/JadePkg/AcpiTables/PMU.asi                          |   10 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc            |   33 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc            |   87 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl             |  165 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc            |   87 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc            |  180 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl             |  330 ++
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl             |   17 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc            |   81 +
 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl             |   15 +
 39 files changed, 24183 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 3c47099b8edc..11f50f2f09cd 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -466,6 +466,14 @@ [PcdsFixedAtBuild.common]
   #
   gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
 
+  #
+  # ACPI table
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013
+
   #
   # Enable strict image permissions for all images. (This applies
   # only to images that were built with >= 4 KB section alignment.)
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 9b9a5d0bad0f..0f9d0adbd34e 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -81,12 +81,24 @@ [LibraryClasses]
   #
   FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
 
+  #
+  # ACPI Libraries
+  #
+  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
+  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
+  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
+
 ################################################################################
 #
 # Specific Platform Pcds
 #
 ################################################################################
 [PcdsFeatureFlag.common]
+  #
+  # Activate AcpiSdtProtocol
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
 [PcdsFixedAtBuild.common]
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
@@ -108,3 +120,14 @@ [Components.common]
   # FailSafe and Watchdog Timer
   #
   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
+
+  #
+  # ACPI
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2B
+  }
+  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
+  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 375455086d0b..2c6f9fac76fd 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -289,4 +289,12 @@ [FV.FvMain]
   #
 !include NetworkPkg/Network.fdf.inc
 
+  #
+  # ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
+  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
+
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
new file mode 100644
index 000000000000..1cf632f8a406
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
@@ -0,0 +1,20 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = JadeAcpiTables
+  FILE_GUID                      = 5ADDBC13-8634-480C-9B94-671B7855CDB8
+  MODULE_TYPE                    = USER_DEFINED
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  Dsdt.asl
+
+[Packages]
+  MdePkg/MdePkg.dec
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
new file mode 100644
index 000000000000..a1a323eee472
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -0,0 +1,75 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = AcpiPlatformDxe
+  FILE_GUID                      = CDA4ED56-6960-4092-885D-FEF37D29093E
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiPlatformDxeInitialize
+
+[Sources.common]
+  AcpiApei.c
+  AcpiApei.h
+  AcpiDsdt.c
+  AcpiMadt.c
+  AcpiNfit.c
+  AcpiPcct.c
+  AcpiPptt.c
+  AcpiPlatform.h
+  AcpiPlatformDxe.c
+  AcpiSlit.c
+  AcpiSrat.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AcpiHelperLib
+  AcpiLib
+  AcpiPccLib
+  AmpereCpuLib
+  BaseLib
+  DebugLib
+  FlashLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Pcd]
+  gArmPlatformTokenSpaceGuid.PcdCoreCount
+  gArmPlatformTokenSpaceGuid.PcdClusterCount
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
+  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
+
+[Guids]
+  gArmMpCoreInfoGuid
+  gEfiAcpiTableGuid
+  gEfiEventReadyToBootGuid
+  gPlatformHobGuid
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid                     ## ALWAYS_CONSUMED
+  gEfiAcpiSdtProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+
+[Depex]
+  gEfiAcpiTableProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
new file mode 100644
index 000000000000..acc4092c650d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
@@ -0,0 +1,44 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = AcpiCommonTables
+  FILE_GUID                      = CEFA2AEB-357E-4F48-8066-EA950853056E
+  MODULE_TYPE                    = USER_DEFINED
+  VERSION_STRING                 = 1.0
+
+[Sources]
+  Bert.aslc
+  Dbg2.aslc
+  Einj.asl
+  Fadt.aslc
+  Gtdt.aslc
+  Hest.asl
+  Sdei.asl
+  Spcr.aslc
+  Ssdt.asl
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[FixedPcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase            ## CONSUMES
+  gArmPlatformTokenSpaceGuid.PL011UartInterrupt                   ## CONSUMES
+  gArmPlatformTokenSpaceGuid.PcdWatchdogCount                     ## CONSUMES
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision        ## CONSUMES
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision    ## CONSUMES
+
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase             ## CONSUMES
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate                 ## CONSUMES
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
new file mode 100644
index 000000000000..c207142459ad
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
@@ -0,0 +1,121 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_APEI_H_
+#define ACPI_APEI_H_
+
+#include <Base.h>
+#include <IndustryStandard/Acpi63.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/AcpiTable.h>
+
+#pragma pack(1)
+#define BERT_MSG_SIZE                0x2C
+#define BERT_ERROR_TYPE              0x7F
+#define BERT_UEFI_FAILURE            5
+#define RAS_2P_TYPE                  0x03
+#define BERT_DEFAULT_ERROR_SEVERITY  0x1
+#define GENERIC_ERROR_DATA_REVISION  0x300
+
+
+#define PLAT_CRASH_ITERATOR_SIZE     0x398
+#define SMPRO_CRASH_SIZE             0x800
+#define PMPRO_CRASH_SIZE             0x800
+#define HEST_NUM_ENTRIES_PER_SOC     3
+
+#define CURRENT_BERT_VERSION         0x10
+#define BERT_FLASH_OFFSET            0x91B30000ULL
+#define BERT_DDR_OFFSET              0x88230000ULL
+#define BERT_DDR_LENGTH              0x50000
+
+typedef struct {
+  UINT8  Type;
+  UINT8  SubType;
+  UINT16 Instance;
+  CHAR8  Msg[BERT_MSG_SIZE];
+} APEI_BERT_ERROR_DATA;
+
+typedef struct {
+  APEI_BERT_ERROR_DATA Vendor;
+  UINT8                BertRev;
+  UINT8                S0PmproRegisters[PMPRO_CRASH_SIZE];
+  UINT8                S0SmproRegisters[SMPRO_CRASH_SIZE];
+  UINT8                S1PmproRegisters[PMPRO_CRASH_SIZE];
+  UINT8                S1SmproRegisters[SMPRO_CRASH_SIZE];
+  UINT8                AtfDump[PLATFORM_CPU_MAX_NUM_CORES * PLAT_CRASH_ITERATOR_SIZE];
+} APEI_CRASH_DUMP_DATA;
+
+typedef struct {
+  EFI_ACPI_6_3_GENERIC_ERROR_STATUS_STRUCTURE     Ges;
+  EFI_ACPI_6_3_GENERIC_ERROR_DATA_ENTRY_STRUCTURE Ged;
+  APEI_CRASH_DUMP_DATA                            Bed;
+} APEI_CRASH_DUMP_BERT_ERROR;
+#pragma pack()
+
+VOID
+EFIAPI
+CreateDefaultBertData (
+  APEI_BERT_ERROR_DATA *Data
+  );
+
+VOID
+EFIAPI
+WrapBertErrorData (
+  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
+  );
+
+VOID
+EFIAPI
+PullBertSpinorData (
+  APEI_CRASH_DUMP_DATA *BertErrorData
+  );
+
+VOID
+EFIAPI
+AdjustBERTRegionLen (
+  UINT32 Len
+  );
+
+BOOLEAN
+EFIAPI
+IsBertEnabled (
+  VOID
+  );
+
+VOID
+EFIAPI
+WriteDDRBertTable (
+  APEI_CRASH_DUMP_BERT_ERROR *Data
+  );
+
+VOID
+WriteSpinorDefaultBertTable (
+  APEI_CRASH_DUMP_DATA *SpiRefrenceData
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiApeiUpdate (
+  VOID
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiPopulateBert (
+  VOID
+  );
+
+#endif /* ACPI_APEI_H_ */
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
new file mode 100644
index 000000000000..920579281dd5
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
@@ -0,0 +1,49 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_NFIT_H_
+#define ACPI_NFIT_H_
+
+#include <Platform/Ac01.h>
+
+#define NVDIMM_SK0          0
+#define NVDIMM_SK1          1
+#define NVDIMM_NUM_PER_SK   (PLATFORM_NVDIMM_MCU_MAX_PER_SK * PLATFORM_NVDIMM_NUM_MAX_PER_MCU)
+#define ONE_GB              (1024 * 1024 * 1024)
+
+enum NvdimmMode {
+  NVDIMM_DISABLED   = 0,
+  NVDIMM_NON_HASHED = 1,
+  NVDIMM_HASHED     = 2
+};
+
+typedef struct {
+  BOOLEAN Enabled;
+  UINT64  NvdSize;
+  UINT32  DeviceHandle;
+  UINT16  PhysId;
+  UINT8   InterleaveWays;
+  UINT64  RegionOffset;
+  UINT16  VendorId;
+  UINT16  DeviceId;
+  UINT16  RevisionId;
+  UINT16  SubVendorId;
+  UINT16  SubDeviceId;
+  UINT16  SubRevisionId;
+  UINT32  SerialNumber;
+} NVDIMM_INFO;
+
+typedef struct {
+  UINT8       NvdRegionNum;
+  UINT8       NvdRegionId[PLATFORM_NVDIMM_REGION_MAX_PER_SK];
+  UINT8       NvdMode;
+  UINT8       NvdNum;
+  NVDIMM_INFO NvdInfo[NVDIMM_NUM_PER_SK];
+} NVDIMM_DATA;
+
+#endif
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
new file mode 100644
index 000000000000..ce4d9b8440b8
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
@@ -0,0 +1,76 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_PLATFORM_H_
+#define ACPI_PLATFORM_H_
+
+#include <Uefi.h>
+
+#include <AcpiHeader.h>
+#include <Guid/EventGroup.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <IndustryStandard/Acpi63.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AcpiLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/AcpiTable.h>
+
+EFI_STATUS
+AcpiPatchDsdtTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallMadtTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallNfitTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiPcctInit (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallPcctTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallPpttTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallSlitTable (
+  VOID
+  );
+
+EFI_STATUS
+AcpiInstallSratTable (
+  VOID
+  );
+
+#endif /* ACPI_PLATFORM_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
new file mode 100644
index 000000000000..d604b712d8c8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
@@ -0,0 +1,37 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_HEADER_H_
+#define ACPI_HEADER_H_
+
+#include <IndustryStandard/Acpi.h>
+
+//
+// ACPI table information used to initialize tables.
+//
+#define EFI_ACPI_OEM_ID           {'A','m','p','e','r','e'}
+#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('A','l','t','r','a',' ',' ',' ')
+#define EFI_ACPI_OEM_REVISION     FixedPcdGet32 (PcdAcpiDefaultOemRevision)
+#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('A','M','P','.')
+#define EFI_ACPI_CREATOR_REVISION FixedPcdGet32 (PcdAcpiDefaultCreatorRevision)
+
+// A macro to initialise the common header part of EFI ACPI tables as defined by
+// EFI_ACPI_DESCRIPTION_HEADER structure.
+#define __ACPI_HEADER(Signature, Type, Revision) {                \
+    Signature,                /* UINT32  Signature */       \
+    sizeof (Type),            /* UINT32  Length */          \
+    Revision,                 /* UINT8   Revision */        \
+    0,                        /* UINT8   Checksum */        \
+    EFI_ACPI_OEM_ID,          /* UINT8   OemId[6] */        \
+    EFI_ACPI_OEM_TABLE_ID,    /* UINT64  OemTableId */      \
+    EFI_ACPI_OEM_REVISION,    /* UINT32  OemRevision */     \
+    EFI_ACPI_CREATOR_ID,      /* UINT32  CreatorId */       \
+    EFI_ACPI_CREATOR_REVISION /* UINT32  CreatorRevision */ \
+  }
+
+#endif /* ACPI_HEADER_H_ */
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
new file mode 100644
index 000000000000..fa188c7776db
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
@@ -0,0 +1,457 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/AcpiHelperLib.h>
+#include <Library/FlashLib.h>
+#include <Library/NVParamLib.h>
+#include <NVParamDef.h>
+
+#include "AcpiApei.h"
+
+UINT8 AMPERE_GUID[16] = {0x8d, 0x89, 0xed, 0xe8, 0x16, 0xdf, 0xcc, 0x43, 0x8e, 0xcc, 0x54, 0xf0, 0x60, 0xef, 0x15, 0x7f};
+CHAR8 DEFAULT_BERT_REBOOT_MSG[BERT_MSG_SIZE] = "Unknown reboot reason";
+
+STATIC VOID
+AcpiApeiUninstallTable (
+  UINT32 Signature
+  )
+{
+  EFI_STATUS              Status;
+  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+  EFI_ACPI_SDT_PROTOCOL   *AcpiTableSdtProtocol;
+  EFI_ACPI_SDT_HEADER     *Table;
+  EFI_ACPI_TABLE_VERSION  TableVersion;
+  UINTN                   TableKey;
+  UINTN                   Idx;
+
+  /*
+   * Get access to ACPI tables
+   */
+  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table protocol\n", __FUNCTION__, __LINE__));
+    return;
+  }
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table support protocol\n", __FUNCTION__, __LINE__));
+    return;
+  }
+
+  /*
+   * Search for ACPI Table Signature
+   */
+  for (Idx = 0; ; Idx++) {
+    Status = AcpiTableSdtProtocol->GetAcpiTable (Idx, &Table, &TableVersion, &TableKey);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d: Unable to get ACPI table index %d \n", __FUNCTION__, __LINE__, Idx));
+      return;
+    } else if (Table->Signature == Signature) {
+      break;
+    }
+  }
+
+  /*
+   * Uninstall ACPI Table
+   */
+  Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, TableKey);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to uninstall table\n", __FUNCTION__, __LINE__));
+  }
+}
+
+VOID
+AdjustBERTRegionLen (
+  UINT32 Len
+  )
+{
+  UINT32                                      Signature = EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE;
+  EFI_STATUS                                  Status;
+  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableSdtProtocol = NULL;
+  EFI_ACPI_TABLE_VERSION                      TableVersion;
+  UINTN                                       TableKey;
+  UINTN                                       Idx;
+  EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER *Table;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableSdtProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
+    return;
+  }
+
+  /*
+   * Search for ACPI Table Signature
+   */
+  for (Idx = 0; ; Idx++) {
+    Status = AcpiTableSdtProtocol->GetAcpiTable (
+                                     Idx,
+                                     (EFI_ACPI_SDT_HEADER **)&Table,
+                                     &TableVersion,
+                                     &TableKey
+                                     );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "APEI: Unable to get ACPI table index:%d\n", Idx));
+      return;
+    } else if (Table->Header.Signature == Signature) {
+      break;
+    }
+  }
+
+  /*
+   * Adjust Boot Error Region Length
+   */
+  Table->BootErrorRegionLength = Len;
+
+  AcpiTableChecksum ((UINT8 *)Table, Table->Header.Length);
+}
+
+/*
+ * Retrieve Bert data from SPI NOR
+ */
+VOID
+PullBertSpinorData (
+  APEI_CRASH_DUMP_DATA *BertErrorData
+  )
+{
+  UINTN Length;
+
+  Length = sizeof (*BertErrorData);
+
+  FlashReadCommand (
+    (UINT8 *)BERT_FLASH_OFFSET,
+    (UINT8 *)BertErrorData,
+    &Length
+    );
+}
+
+/*
+ * wrap raw bert error data
+ *
+ * @param  IN  BertErrorData     Bert Error record to be wrapped
+ * @param  OUT WrappedError      Generic error data for OS to consume.
+ */
+VOID
+WrapBertErrorData (
+  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
+  )
+{
+  UINT32 CrashSize;
+
+  CrashSize = PLAT_CRASH_ITERATOR_SIZE *
+              GetNumberOfSupportedSockets () *
+              GetMaximumNumberOfCores ();
+  CrashSize += 2 * (SMPRO_CRASH_SIZE + PMPRO_CRASH_SIZE);
+  CrashSize += sizeof (WrappedError->Bed.Vendor) + sizeof (WrappedError->Bed.BertRev);
+
+  WrappedError->Ges.BlockStatus.ErrorDataEntryCount = 1;
+  WrappedError->Ges.BlockStatus.UncorrectableErrorValid = 1;
+  WrappedError->Ged.ErrorSeverity = BERT_DEFAULT_ERROR_SEVERITY;
+  WrappedError->Ged.Revision = GENERIC_ERROR_DATA_REVISION;
+
+  if (WrappedError->Bed.Vendor.Type == RAS_2P_TYPE ||
+      (WrappedError->Bed.Vendor.Type == BERT_ERROR_TYPE &&
+       (WrappedError->Bed.Vendor.SubType == 0 ||
+        WrappedError->Bed.Vendor.SubType == BERT_UEFI_FAILURE)))
+  {
+    WrappedError->Ged.ErrorDataLength = sizeof (WrappedError->Bed.Vendor) +
+                                        sizeof (WrappedError->Bed.BertRev);
+    WrappedError->Ges.DataLength = sizeof (WrappedError->Bed.Vendor) +
+                                   sizeof (WrappedError->Bed.BertRev) +
+                                   sizeof (WrappedError->Ged);
+    AdjustBERTRegionLen (
+      sizeof (WrappedError->Bed.Vendor) +
+      sizeof (WrappedError->Bed.BertRev) +
+      sizeof (WrappedError->Ged) +
+      sizeof (WrappedError->Ges)
+      );
+  } else {
+    WrappedError->Ged.ErrorDataLength = CrashSize;
+    WrappedError->Ges.DataLength = CrashSize + sizeof (WrappedError->Ged);
+    AdjustBERTRegionLen (
+      CrashSize +
+      sizeof (WrappedError->Ged) +
+      sizeof (WrappedError->Ges)
+      );
+  }
+  CopyMem (
+    WrappedError->Ged.SectionType,
+    AMPERE_GUID,
+    sizeof (AMPERE_GUID)
+    );
+}
+
+
+/*
+ * create default bert error
+ * Msg: Unknown reboot reason
+ */
+VOID
+CreateDefaultBertData (
+  APEI_BERT_ERROR_DATA *Data
+  )
+{
+  Data->Type = BERT_ERROR_TYPE;
+  AsciiStrCpyS (
+    Data->Msg,
+    BERT_MSG_SIZE,
+    DEFAULT_BERT_REBOOT_MSG
+    );
+}
+
+/*
+ * Ensures BertErrorData In SPINOR matches
+ * the record produced by CreateDefaultBertData.
+ * @param  Bed    Crash dump Data
+ */
+VOID
+WriteSpinorDefaultBertTable (
+  APEI_CRASH_DUMP_DATA *Bed
+  )
+{
+  UINT8                BertRev;
+  UINTN                Length;
+  UINT64               Offset;
+  UINT32               MsgDiff;
+  APEI_BERT_ERROR_DATA DefaultData = {0};
+
+  CreateDefaultBertData (&DefaultData);
+  if ((Bed->Vendor.Type != DefaultData.Type)) {
+    Offset = BERT_FLASH_OFFSET +
+             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
+             OFFSET_OF (APEI_BERT_ERROR_DATA, Type);
+    Length = sizeof (DefaultData.Type);
+    FlashEraseCommand ((UINT8 *)Offset, Length);
+    FlashProgramCommand (
+      (UINT8 *)Offset,
+      (UINT8 *)&(DefaultData.Type),
+      &Length
+      );
+  }
+
+  if ((Bed->Vendor.SubType != DefaultData.SubType)) {
+    Offset = BERT_FLASH_OFFSET +
+             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
+             OFFSET_OF (APEI_BERT_ERROR_DATA, SubType);
+    Length = sizeof (DefaultData.SubType);
+    FlashEraseCommand ((UINT8 *)Offset, Length);
+    FlashProgramCommand (
+      (UINT8 *)Offset,
+      (UINT8 *)&(DefaultData.SubType),
+      &Length
+      );
+  }
+
+  if ((Bed->Vendor.Instance != DefaultData.Instance)) {
+    Offset = BERT_FLASH_OFFSET +
+             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
+             OFFSET_OF (APEI_BERT_ERROR_DATA, Instance);
+    Length = sizeof (DefaultData.Instance);
+    FlashEraseCommand ((UINT8 *)Offset, Length);
+    FlashProgramCommand (
+      (UINT8 *)Offset,
+      (UINT8 *)&(DefaultData.Instance),
+      &Length
+      );
+  }
+
+  MsgDiff = AsciiStrnCmp (Bed->Vendor.Msg, DefaultData.Msg, BERT_MSG_SIZE);
+  if (MsgDiff != 0) {
+    Offset = BERT_FLASH_OFFSET +
+             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
+             OFFSET_OF (APEI_BERT_ERROR_DATA, Msg);
+    Length = sizeof (DefaultData.Msg);
+    FlashEraseCommand ((UINT8 *)Offset, Length);
+    FlashProgramCommand (
+      (UINT8 *)Offset,
+      (UINT8 *)&(DefaultData.Msg),
+      &Length
+      );
+  }
+
+  if (Bed->BertRev != CURRENT_BERT_VERSION) {
+    Offset = BERT_FLASH_OFFSET + OFFSET_OF (APEI_CRASH_DUMP_DATA, BertRev);
+    Length = sizeof (Bed->BertRev);
+    BertRev = CURRENT_BERT_VERSION;
+    FlashEraseCommand ((UINT8 *)Offset, Length);
+    FlashProgramCommand ((UINT8 *)Offset, (UINT8 *)&BertRev, &Length);
+  }
+
+}
+
+/*
+ * Checks Status of NV_SI_RAS_BERT_ENABLED
+ * Returns TRUE if enabled and FALSE if disabled
+ */
+BOOLEAN
+IsBertEnabled (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  Status = NVParamGet (
+             NV_SI_RAS_BERT_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    // BERT is enabled by default
+    return TRUE;
+  }
+
+  return (Value != 0) ? TRUE : FALSE;
+}
+
+/*
+ * Write bert table to DDR
+ */
+VOID
+WriteDDRBertTable (
+  APEI_CRASH_DUMP_BERT_ERROR *Data
+  )
+{
+  VOID *Blk = (VOID *)BERT_DDR_OFFSET;
+
+  /*
+   * writing sizeof data to ddr produces alignment error
+   * this is a temporary workaround
+   */
+  CopyMem (Blk, Data, BERT_DDR_LENGTH);
+}
+
+/*
+ * Update Bert Table
+ */
+EFI_STATUS
+AcpiPopulateBert (
+  VOID
+  )
+{
+  APEI_CRASH_DUMP_BERT_ERROR *DDRError;
+
+  DDRError =
+    (APEI_CRASH_DUMP_BERT_ERROR *)
+    AllocateZeroPool (sizeof (APEI_CRASH_DUMP_BERT_ERROR));
+
+  if (DDRError == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  if (IsBertEnabled ()) {
+    PullBertSpinorData (&(DDRError->Bed));
+    if ((DDRError->Bed.BertRev == CURRENT_BERT_VERSION)) {
+      WrapBertErrorData (DDRError);
+      WriteDDRBertTable (DDRError);
+    }
+    WriteSpinorDefaultBertTable (&(DDRError->Bed));
+  }
+
+  FreePool (DDRError);
+  return EFI_SUCCESS;
+}
+
+/*
+ * Checks Status of NV_SI_RAS_SDEI_ENABLED
+ * Returns TRUE if enabled and FALSE if disabled or error occurred
+ */
+BOOLEAN
+IsSdeiEnabled (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  Status = NVParamGet (
+             NV_SI_RAS_SDEI_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    // SDEI is disabled by default
+    return FALSE;
+  }
+
+  return (Value != 0) ? TRUE : FALSE;
+}
+
+STATIC
+VOID
+AcpiApeiHestUpdateTable1P (
+  VOID
+  )
+{
+  EFI_STATUS                                      Status;
+  EFI_ACPI_SDT_PROTOCOL                           *AcpiTableSdtProtocol = NULL;
+  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *HestTablePointer;
+  EFI_ACPI_TABLE_VERSION                          TableVersion;
+  UINTN                                           TableKey;
+  UINTN                                           Idx;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
+    return;
+  }
+
+  /*
+   * Search for ACPI Table Signature
+   */
+  for (Idx = 0; ; Idx++) {
+    Status = AcpiTableSdtProtocol->GetAcpiTable (
+                                     Idx,
+                                     (EFI_ACPI_SDT_HEADER **)&HestTablePointer,
+                                     &TableVersion,
+                                     &TableKey
+                                     );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "APEI: Unable to get HEST table"));
+      return;
+    } else if (HestTablePointer->Header.Signature ==
+               EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE)
+    {
+      break;
+    }
+  }
+
+  HestTablePointer->ErrorSourceCount -= HEST_NUM_ENTRIES_PER_SOC;
+  HestTablePointer->Header.Length -=
+    (HEST_NUM_ENTRIES_PER_SOC *
+     sizeof (EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE));
+
+  AcpiTableChecksum ((UINT8 *)HestTablePointer, HestTablePointer->Header.Length);
+}
+
+/*
+ * Update APEI
+ *
+ */
+EFI_STATUS
+EFIAPI
+AcpiApeiUpdate (
+  VOID
+  )
+{
+  if (!IsSlaveSocketActive ()) {
+    AcpiApeiHestUpdateTable1P ();
+  }
+
+  if (!IsSdeiEnabled ()) {
+    AcpiApeiUninstallTable (EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE);
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
new file mode 100644
index 000000000000..7881044104e4
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
@@ -0,0 +1,445 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Protocol/PciRootBridgeIo.h>
+#include <Library/NVParamLib.h>
+#include <NVParamDef.h>
+
+#include "AcpiNfit.h"
+#include "AcpiPlatform.h"
+
+#define PCIE_DEVICE_CONTROL_OFFSET                      0x078
+#define PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN        0x08
+#define PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN         0x04
+#define PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN     0x02
+#define PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN          0x01
+
+#define PCIE_ROOT_ERR_CMD_OFFSET                        0x12C
+#define PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN        0x4
+#define PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN    0x2
+#define PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN         0x1
+
+#define PCIE_MAX_DEVICE_PER_ROOT_PORT 8
+
+STATIC VOID
+AcpiPatchCmn600 (
+  VOID
+  )
+{
+  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
+  UINTN Index;
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.CMN%1X._STA", Index);
+    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+    } else {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    }
+  }
+}
+
+STATIC VOID
+AcpiPatchDmc620 (
+  VOID
+  )
+{
+  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
+  UINTN              Index, Index1;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  UINT32             McuMask;
+  VOID               *Hob;
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    McuMask = PlatformHob->DramInfo.McuMask[Index];
+    for (Index1 = 0; Index1 < sizeof (McuMask) * 8; Index1++) {
+      AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.MC%1X%1X._STA", Index, Index1);
+      if (McuMask & (0x1 << Index1)) {
+        AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+      } else {
+        AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+      }
+    }
+  }
+}
+
+STATIC VOID
+AcpiPatchNvdimm (
+  VOID
+  )
+{
+  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
+  UINTN              NvdRegionNumSK0, NvdRegionNumSK1, NvdRegionNum, Count;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  VOID               *Hob;
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  NvdRegionNumSK0 = 0;
+  NvdRegionNumSK1 = 0;
+  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+    if (PlatformHob->DramInfo.NvdRegion[Count] > 0) {
+      if (PlatformHob->DramInfo.Socket[Count] == 0) {
+        NvdRegionNumSK0++;
+      } else {
+        NvdRegionNumSK1++;
+      }
+    }
+  }
+  NvdRegionNum = NvdRegionNumSK0 + NvdRegionNumSK1;
+
+  /* Disable NVDIMM Root Device */
+  if (NvdRegionNum == 0) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR._STA");
+    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+  }
+  /* Update NVDIMM Device _STA for SK0 */
+  if (NvdRegionNumSK0 == 0) {
+    /* Disable NVD1/2 */
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
+    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
+    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+  } else if (NvdRegionNumSK0 == 1) {
+    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK0] == NVDIMM_NON_HASHED) {
+      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
+            PlatformHob->DramInfo.Socket[Count] == 0)
+        {
+          if (PlatformHob->DramInfo.Base[Count] ==
+              PLATFORM_NVDIMM_SK0_NHASHED_REGION0)
+          {
+            /* Disable NVD2 */
+            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
+            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+          } else if (PlatformHob->DramInfo.Base[Count] ==
+                     PLATFORM_NVDIMM_SK0_NHASHED_REGION1)
+          {
+            /* Disable NVD1 */
+            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
+            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+          }
+        }
+      }
+    }
+  }
+  /* Update NVDIMM Device _STA for SK1 */
+  if (NvdRegionNumSK1 == 0) {
+    /* Disable NVD3/4 */
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
+    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
+    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+  } else if (NvdRegionNumSK1 == 1) {
+    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK1] == NVDIMM_NON_HASHED) {
+      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
+            PlatformHob->DramInfo.Socket[Count] == 1)
+        {
+          if (PlatformHob->DramInfo.Base[Count] ==
+              PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
+          {
+            /* Disable NVD4 */
+            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
+            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+          } else if (PlatformHob->DramInfo.Base[Count] ==
+                     PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
+          {
+            /* Disable NVD3 */
+            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
+            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+          }
+        }
+      }
+    }
+  }
+}
+
+STATIC VOID
+AcpiPatchHwmon (
+  VOID
+  )
+{
+  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
+  UINT8 Index;
+
+  // PCC Hardware Monitor Devices
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index);
+    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+    } else {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    }
+  }
+
+  // Ampere Altra SoC Hardware Monitor Devices
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index + 2);
+    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+    } else {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    }
+  }
+}
+
+STATIC VOID
+AcpiPatchDsu (
+  VOID
+  )
+{
+  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
+  UINTN Index;
+
+  for (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index += PLATFORM_CPU_NUM_CORES_PER_CPM) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.DU%2X._STA", Index / PLATFORM_CPU_NUM_CORES_PER_CPM);
+    if (IsCpuEnabled (Index)) {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+    } else {
+      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+    }
+  }
+}
+
+VOID
+AcpiPatchPcieNuma (
+  VOID
+  )
+{
+  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
+  UINTN Index;
+  UINTN NumaIdx;
+  UINTN NumPciePort;
+  UINTN NumaAssignment[3][16] = {
+    { 0, 0, 0, 0, 0, 0, 0, 0,   // Monolithic Node 0 (S0)
+      1, 1, 1, 1, 1, 1, 1, 1 }, // Monolithic Node 1 (S1)
+    { 0, 1, 0, 1, 0, 0, 1, 1,   // Hemisphere Node 0, 1 (S0)
+      2, 3, 2, 3, 2, 2, 3, 3 }, // Hemisphere Node 2, 3 (S1)
+    { 0, 2, 1, 3, 1, 1, 3, 3,   // Quadrant Node 0, 1, 2, 3 (S0)
+      4, 6, 5, 7, 5, 5, 7, 7 }, // Quadrant Node 4, 5, 6, 7 (S1)
+  };
+
+  switch (CpuGetSubNumaMode ()) {
+  case SUBNUMA_MODE_MONOLITHIC:
+    NumaIdx = 0;
+    break;
+
+  case SUBNUMA_MODE_HEMISPHERE:
+    NumaIdx = 1;
+    break;
+
+  case SUBNUMA_MODE_QUADRANT:
+    NumaIdx = 2;
+    break;
+
+  default:
+    NumaIdx = 0;
+    break;
+  }
+
+  if (IsSlaveSocketActive ()) {
+    NumPciePort = 16; // 16 ports total (8 per socket)
+  } else {
+    NumPciePort = 8;  // 8 ports total
+  }
+
+  for (Index = 0; Index < NumPciePort; Index++) {
+    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._PXM", Index);
+    AcpiDSDTSetNodeStatusValue (NodePath, NumaAssignment[NumaIdx][Index]);
+  }
+}
+
+EFI_STATUS
+AcpiPatchPcieAerFwFirst (
+  VOID
+  )
+{
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS Address;
+  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableProtocol;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL             *PciRootBridgeIo;
+  EFI_HANDLE                                  *HandleBuffer;
+  UINTN                                       HandleCount;
+  EFI_ACPI_HANDLE                             TableHandle;
+  EFI_ACPI_HANDLE                             ChildHandle;
+  EFI_ACPI_DATA_TYPE                          DataType;
+  UINTN                                       DataSize;
+  CHAR8                                       ObjectPath[8];
+  EFI_STATUS                                  Status;
+  UINT32                                      AerFwFirstConfigValue;
+  UINT32                                      RegData;
+  UINT16                                      Device;
+  UINT32                                      Index;
+  UINT8                                       *Data;
+
+  //
+  // Check if PCIe AER Firmware First should be enabled
+  //
+  Status = NVParamGet (
+             NV_SI_RAS_PCIE_AER_FW_FIRST,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &AerFwFirstConfigValue
+             );
+  if (EFI_ERROR (Status)) {
+    Status = NVParamGet (
+               NV_SI_RO_BOARD_PCIE_AER_FW_FIRST,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               &AerFwFirstConfigValue
+               );
+    if (EFI_ERROR (Status)) {
+      AerFwFirstConfigValue = 0;
+    }
+  }
+
+  if (AerFwFirstConfigValue == 0) {
+    //
+    // By default, the PCIe AER FW-First (ACPI Object "AERF") is set to 0
+    // in the DSDT table.
+    //
+    return EFI_SUCCESS;
+  }
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
+    return Status;
+  }
+
+  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
+  if (EFI_ERROR (Status)) {
+    AcpiTableProtocol->Close (TableHandle);
+    return Status;
+  }
+
+  //
+  // Update Name Object "AERF" (PCIe AER Firmware-First) if it is enabled.
+  //
+  AsciiSPrint (ObjectPath, sizeof (ObjectPath), "\\AERF");
+  Status = AcpiTableProtocol->FindPath (TableHandle, ObjectPath, &ChildHandle);
+  ASSERT_EFI_ERROR (Status);
+  if (!EFI_ERROR (Status)) {
+    Status = AcpiTableProtocol->GetOption (
+                                  ChildHandle,
+                                  0,
+                                  &DataType,
+                                  (VOID *)&Data,
+                                  &DataSize
+                                  );
+    ASSERT_EFI_ERROR (Status);
+    if (!EFI_ERROR (Status)
+        && Data[0] == AML_NAME_OP
+        && (Data[5] == AML_ZERO_OP || Data[5] == AML_ONE_OP))
+    {
+      Data[5] = 1; // Enable PCIe AER Firmware-First
+    }
+  }
+
+  AcpiTableProtocol->Close (TableHandle);
+  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
+
+  //
+  // For PCIe AER Firmware First, PCIe capability registers need
+  // to be updated to allow Firmware to detect AER errors.
+  //
+
+  HandleCount = 0;
+  HandleBuffer = NULL;
+  PciRootBridgeIo = NULL;
+
+  Status = gBS->LocateHandleBuffer (
+                  ByProtocol,
+                  &gEfiPciRootBridgeIoProtocolGuid,
+                  NULL,
+                  &HandleCount,
+                  &HandleBuffer
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Loop through each root complex
+  //
+  for (Index = 0; Index < HandleCount; Index++) {
+    Status = gBS->HandleProtocol (
+                    HandleBuffer[Index],
+                    &gEfiPciRootBridgeIoProtocolGuid,
+                    (VOID **)&PciRootBridgeIo
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    //
+    // Loop through each root port
+    //
+    for (Device = 1; Device <= PCIE_MAX_DEVICE_PER_ROOT_PORT; Device++) {
+      Address.Bus = 0;
+      Address.Device = Device;
+      Address.Function = 0;
+      Address.Register = 0;
+
+      Address.ExtendedRegister = PCIE_DEVICE_CONTROL_OFFSET;
+      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
+
+      if (RegData == 0xFFFFFFFF) {
+        continue;
+      }
+
+      RegData |= PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN
+                 | PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN
+                 | PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN
+                 | PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN;
+
+      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
+
+      RegData = 0;
+      Address.ExtendedRegister = PCIE_ROOT_ERR_CMD_OFFSET;
+      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
+
+      RegData |= PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN
+                 | PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN
+                 | PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN;
+
+      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+AcpiPatchDsdtTable (
+  VOID
+  )
+{
+  AcpiPatchCmn600 ();
+  AcpiPatchDmc620 ();
+  AcpiPatchDsu ();
+  AcpiPatchHwmon ();
+  AcpiPatchNvdimm ();
+  AcpiPatchPcieNuma ();
+  AcpiPatchPcieAerFwFirst ();
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
new file mode 100644
index 000000000000..1d1643abd299
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
@@ -0,0 +1,351 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiPlatform.h"
+
+EFI_ACPI_6_3_GIC_ITS_STRUCTURE GicItsTemplate = {
+  EFI_ACPI_6_3_GIC_ITS,
+  sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE),
+  EFI_ACPI_RESERVED_WORD,
+  0, /* GicItsId */
+  0, /* PhysicalBaseAddress */
+  0, /* Reserved2 */
+};
+
+EFI_ACPI_6_3_GICR_STRUCTURE GicRTemplate = {
+  EFI_ACPI_6_3_GICR,
+  sizeof (EFI_ACPI_6_3_GICR_STRUCTURE),
+  EFI_ACPI_RESERVED_WORD,
+  GICR_MASTER_BASE_REG, /* DiscoveryRangeBaseAddress */
+  0x1000000,            /* DiscoveryRangeLength */
+};
+
+EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDTemplate = {
+  EFI_ACPI_6_3_GICD,
+  sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE),
+  EFI_ACPI_RESERVED_WORD,
+  0,             /* GicDistHwId */
+  GICD_BASE_REG, /* GicDistBase */
+  0,             /* GicDistVector */
+  0x3,           /* GicVersion */
+  {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}
+};
+
+EFI_ACPI_6_3_GIC_STRUCTURE GiccTemplate = {
+  EFI_ACPI_6_3_GIC,
+  sizeof (EFI_ACPI_6_3_GIC_STRUCTURE),
+  EFI_ACPI_RESERVED_WORD,
+  0, /* GicId */
+  0, /* AcpiCpuUid */
+  0, /* Flags */
+  0,
+  23, /* PmuIrq */
+  0,
+  0,
+  0,
+  0,
+  25, /* GsivId */
+  0,  /* GicRBase */
+  0,  /* Mpidr */
+  0,  /* ProcessorPowerEfficiencyClass */
+  0,  /* Reserved2 */
+  21, /* SPE irq */
+};
+
+EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MADTTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
+    0, /* need fill in */
+    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
+    ),
+};
+
+UINT32 Ac01CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
+  36, 52, 40, 56, 32, 48, 44, 60,
+  20, 68, 24, 72, 16, 64, 28, 76,
+  4, 8, 0, 12, 38, 54, 42, 58,
+  34, 50, 46, 62, 22, 70, 26, 74,
+  18, 66, 30, 78, 6, 10, 2, 14,
+  37, 53, 41, 57, 33, 49, 45, 61,
+  21, 69, 25, 73, 17, 65, 29, 77,
+  5, 9, 1, 13, 39, 55, 43, 59,
+  35, 51, 47, 63, 23, 71, 27, 75,
+  19, 67, 31, 79, 7, 11, 3, 15,
+};
+
+UINT32 Ac01CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
+  32, 48, 16, 64, 36, 52, 0, 20,
+  68, 4, 34, 50, 18, 66, 38, 54,
+  2, 22, 70, 6, 33, 49, 17, 65,
+  37, 53, 1, 21, 69, 5, 35, 51,
+  19, 67, 39, 55, 3, 23, 71, 7,
+  44, 60, 28, 76, 40, 56, 12, 24,
+  72, 8, 46, 62, 30, 78, 42, 58,
+  14, 26, 74, 10, 45, 61, 29, 77,
+  41, 57, 13, 25, 73, 9, 47, 63,
+  31, 79, 43, 59, 15, 27, 75, 11,
+};
+
+UINT32 Ac01CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
+  16, 32, 0, 20, 4, 18, 34, 2,
+  22, 6, 17, 33, 1, 21, 5, 19,
+  35, 3, 23, 7, 48, 64, 52, 68,
+  36, 50, 66, 54, 70, 38, 49, 65,
+  53, 69, 37, 51, 67, 55, 71, 39,
+  28, 44, 12, 24, 8, 30, 46, 14,
+  26, 10, 29, 45, 13, 25, 9, 31,
+  47, 15, 27, 11, 60, 76, 56, 72,
+  40, 62, 78, 58, 74, 42, 61, 77,
+  57, 73, 41, 63, 79, 59, 75, 43,
+};
+
+EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTablePointer;
+
+UINT32 *
+CpuGetCoreOrder (
+  VOID
+  )
+{
+  UINT8              SubNumaMode;
+
+  SubNumaMode = CpuGetSubNumaMode ();
+  switch (SubNumaMode) {
+  case SUBNUMA_MODE_MONOLITHIC:
+    return (UINT32 *)&Ac01CoreOrderMonolithic;
+
+  case SUBNUMA_MODE_HEMISPHERE:
+    return (UINT32 *)&Ac01CoreOrderHemisphere;
+
+  case SUBNUMA_MODE_QUADRANT:
+    return (UINT32 *)&Ac01CoreOrderQuadrant;
+
+  default:
+    // Should never reach here
+    ASSERT (FALSE);
+    return NULL;
+  }
+
+  return NULL;
+}
+
+UINT32
+AcpiInstallMadtProcessorNode (
+  VOID   *EntryPointer,
+  UINT32 CpuId
+  )
+{
+  EFI_ACPI_6_3_GIC_STRUCTURE *MadtProcessorEntryPointer = EntryPointer;
+  UINT32                     SocketId;
+  UINT32                     ClusterId;
+  UINTN                      Size;
+
+  Size = sizeof (GiccTemplate);
+  CopyMem (MadtProcessorEntryPointer, &GiccTemplate, Size);
+
+  SocketId = SOCKET_ID (CpuId);
+  ClusterId = CLUSTER_ID (CpuId);
+
+  //
+  // GICv2 compatibility mode is not supported.
+  // Hence, set GIC's CPU Interface Number to 0.
+  //
+  MadtProcessorEntryPointer->CPUInterfaceNumber = 0;
+  MadtProcessorEntryPointer->AcpiProcessorUid =
+    (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
+    (ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM);
+  MadtProcessorEntryPointer->Flags = 1;
+  MadtProcessorEntryPointer->MPIDR =
+    (((ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM)) << 8);
+  MadtProcessorEntryPointer->MPIDR += (((UINT64)SocketId) << 32);
+
+  return Size;
+}
+
+UINT32
+AcpiInstallMadtGicD (
+  VOID *EntryPointer
+  )
+{
+  EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GicDEntryPointer = EntryPointer;
+  UINTN                                  Size;
+
+  Size = sizeof (GicDTemplate);
+  CopyMem (GicDEntryPointer, &GicDTemplate, Size);
+
+  return Size;
+}
+
+UINT32
+AcpiInstallMadtGicR (
+  VOID   *EntryPointer,
+  UINT32 SocketId
+  )
+{
+  EFI_ACPI_6_3_GICR_STRUCTURE *GicREntryPointer = EntryPointer;
+  UINTN                       Size;
+
+  /*
+   * If the Slave socket is not present, discard the Slave socket
+   * GIC redistributor region
+   */
+  if (SocketId == 1 && !IsSlaveSocketActive ()) {
+    return 0;
+  }
+
+  Size = sizeof (GicRTemplate);
+  CopyMem (GicREntryPointer, &GicRTemplate, Size);
+
+  if (SocketId == 1) {
+    GicREntryPointer->DiscoveryRangeBaseAddress = GICR_SLAVE_BASE_REG;
+  }
+
+  return Size;
+}
+
+UINT32
+AcpiInstallMadtGicIts (
+  VOID   *EntryPointer,
+  UINT32 Index
+  )
+{
+  EFI_ACPI_6_3_GIC_ITS_STRUCTURE *GicItsEntryPointer = EntryPointer;
+  UINTN                          Size, Offset;
+  UINT64                         GicBase = GICD_BASE_REG;
+  UINT32                         ItsId = Index;
+
+  if (Index > SOCKET0_LAST_RC) { /* Socket 1, Index: 8-15 */
+    GicBase = GICD_SLAVE_BASE_REG;
+    Index -= (SOCKET0_LAST_RC + 1); /* Socket 1, Index:8 -> RCA0 */
+  }
+  Size = sizeof (GicItsTemplate);
+  CopyMem (GicItsEntryPointer, &GicItsTemplate, Size);
+  Offset = 0x40000 + Index * 0x20000;
+  GicItsEntryPointer->GicItsId = ItsId;
+  GicItsEntryPointer->PhysicalBaseAddress = Offset + GicBase;
+
+  return Size;
+}
+
+/*
+ *  Install MADT table.
+ */
+EFI_STATUS
+AcpiInstallMadtTable (
+  VOID
+  )
+{
+  EFI_ACPI_6_3_GIC_STRUCTURE *GiccEntryPointer = NULL;
+  EFI_ACPI_TABLE_PROTOCOL    *AcpiTableProtocol;
+  UINTN                      MadtTableKey  = 0;
+  INTN                       Index;
+  EFI_STATUS                 Status;
+  UINTN                      Size;
+  UINT32                     *CoreOrder;
+  UINT32                     SktMaxCoreNum;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = sizeof (MADTTableHeaderTemplate) +
+          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (GiccTemplate)) +
+          sizeof (GicDTemplate) +
+          (PLATFORM_CPU_MAX_SOCKET * sizeof (GicRTemplate)) +
+          ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsTemplate));
+  if (IsSlaveSocketActive ()) {
+    Size += ((SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsTemplate));
+  } else if (!IsSlaveSocketPresent ()) {
+    Size += 2 * sizeof (GicItsTemplate); /* RCA0/1 */
+  }
+
+  MadtTablePointer =
+    (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (Size);
+  if (MadtTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  GiccEntryPointer =
+    (EFI_ACPI_6_3_GIC_STRUCTURE *)((UINT64)MadtTablePointer +
+                                    sizeof (MADTTableHeaderTemplate));
+
+  /* Install Gic interface for each processor */
+  Size = 0;
+  CoreOrder = CpuGetCoreOrder ();
+  ASSERT (CoreOrder != NULL);
+  SktMaxCoreNum = PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM;
+  for (Index = 0; Index < SktMaxCoreNum; Index++) {
+    if (IsCpuEnabled (CoreOrder[Index])) {
+      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index]);
+    }
+  }
+
+  for (Index = 0; Index < SktMaxCoreNum; Index++) {
+    if (IsCpuEnabled (CoreOrder[Index] + SktMaxCoreNum)) {
+      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index] + SktMaxCoreNum);
+    }
+  }
+
+  /* Install Gic Distributor */
+  Size += AcpiInstallMadtGicD ((VOID *)((UINT64)GiccEntryPointer + Size));
+
+  /* Install Gic Redistributor */
+  for (Index = 0; Index < PLATFORM_CPU_MAX_SOCKET; Index++) {
+    Size += AcpiInstallMadtGicR ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
+  }
+
+  /* Install Gic ITS */
+  if (!IsSlaveSocketPresent ()) {
+    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
+      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
+    }
+  }
+  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
+    Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
+  }
+  if (IsSlaveSocketActive ()) {
+    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
+      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
+    }
+  }
+  CopyMem (
+    MadtTablePointer,
+    &MADTTableHeaderTemplate,
+    sizeof (MADTTableHeaderTemplate)
+    );
+
+  Size += sizeof (MADTTableHeaderTemplate);
+  MadtTablePointer->Header.Length = Size;
+  CopyMem (
+    MadtTablePointer->Header.OemId,
+    PcdGetPtr (PcdAcpiDefaultOemId),
+    sizeof (MadtTablePointer->Header.OemId)
+    );
+
+  AcpiTableChecksum (
+    (UINT8 *)MadtTablePointer,
+    MadtTablePointer->Header.Length
+    );
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)MadtTablePointer,
+                                MadtTablePointer->Header.Length,
+                                &MadtTableKey
+                                );
+  FreePool ((VOID *)MadtTablePointer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
new file mode 100644
index 000000000000..d13ac3514e11
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
@@ -0,0 +1,599 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiNfit.h"
+#include "AcpiPlatform.h"
+
+EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE NfitSPATemplate = {
+  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE,
+  sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE),
+  0,                                                                // The uniue index - need to be filled.
+  0,                                                                // The flags - need to be filled.
+  0,                                                                // Reserved.
+  0,                                                                // Proximity domain - need to be filled.
+  EFI_ACPI_6_3_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION, // PM range type.
+  0,                                                                // Start address - need to be filled.
+  0,                                                                // Size - need to be filled.
+  EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB |
+  EFI_MEMORY_WP | EFI_MEMORY_UCE, // attribute - need to be filled.
+};
+
+EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE NvdimmControlRegionTemplate = {
+  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE,
+  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE),
+  0,   // The unique index - need to be filled.
+  0,   // The vendor id - need to be filled.
+  0,   // The device id - need to be filled.
+  0,   // The revision - need to be filled.
+  0,   // The subsystem nvdimm id - need to be filled.
+  0,   // The subsystem nvdimm device id - need to be filled.
+  0,   // The subsystem revision - need to be filled.
+  0,   // The valid field.
+  0,   // The manufacturing location - not valid.
+  0,   // The manufacturing date - not valid.
+  {0}, // Reserved.
+  0,   // The serial number - need to be filled.
+  0,   // The region format interface code - dummy value.
+  0,   // The number of block control windows.
+  0,   // The size of block control windows.
+  0,   // The Command Register Offset in Block Control Window.
+  0,   // The Size of Command Register in Block Control Windows.
+  0,   // The Status Register Offset in Block Control Window.
+  0,   // Size of Status Register in Block Control Windows.
+  0,   // The NVDIMM Control Region Flag.
+  {0}, // Reserved.
+};
+
+EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE NvdimmRegionMappingTemplate = {
+  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE,
+  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE),
+  {0}, // _ADR of the NVDIMM device - need to be filled.
+  0,   // Dimm smbios handle index - need to be filled.
+  0,   // The unique region index - need to be filled.
+  0,   // The SPA range index - need to be filled.
+  0,   // The control region index - need to be filled.
+  0,   // The region size - need to be filled.
+  0,   // The region offset - need to be filled.
+  0,   // The region base - need to be filled.
+  0,   // The interleave structure index - need to be filled.
+  0,   // The interleave ways - need to be filled.
+  0,   // NVDIMM flags - need to be filled.
+  0,   // Reserved.
+};
+
+EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE NFITTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE,
+    0, /* need fill in */
+    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION
+    ),
+  0x00000000, // Reserved
+};
+
+NVDIMM_DATA NvdData[PLATFORM_CPU_MAX_SOCKET] = { 0 };
+
+EFI_STATUS
+AcpiNvdInfoInit (
+  IN OUT NVDIMM_INFO *NvdInfoPtr,
+  IN     UINTN       NvdId
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  VOID               *Hob;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL || NvdInfoPtr == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  NvdInfoPtr->Enabled = TRUE;
+  NvdInfoPtr->PhysId = NvdId;
+  NvdInfoPtr->NvdSize = PlatformHob->DimmList.Dimm[NvdId].Info.DimmSize * ONE_GB;
+  NvdInfoPtr->VendorId =
+    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[320]);
+  NvdInfoPtr->DeviceId =
+    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[192]);
+  NvdInfoPtr->RevisionId =
+    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[349];
+  NvdInfoPtr->SubVendorId =
+    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[194]);
+  NvdInfoPtr->SubDeviceId =
+    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[196]);
+  NvdInfoPtr->SubRevisionId =
+    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[198];
+  NvdInfoPtr->SerialNumber =
+    *((UINT32 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[325]);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AcpiNvdDataInit (
+  IN UINTN Socket
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  NVDIMM_INFO        *NvdInfo;
+  UINTN              Count;
+  VOID               *Hob;
+  UINTN              NvdRegionNum, RegionId;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  NvdRegionNum = 0;
+  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+    if (PlatformHob->DramInfo.NvdRegion[Count] != 0
+        && (PlatformHob->DramInfo.Socket[Count] == Socket))
+    {
+      NvdData[Socket].NvdRegionId[NvdRegionNum] = Count;
+      NvdRegionNum++;
+    }
+  }
+  if (NvdRegionNum == 0) {
+    return EFI_SUCCESS;
+  }
+
+  NvdData[Socket].NvdRegionNum = NvdRegionNum;
+  NvdData[Socket].NvdMode = PlatformHob->DramInfo.NvdimmMode[Socket];
+  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
+    NvdInfo = &NvdData[Socket].NvdInfo[NVDIMM_SK0];
+    NvdInfo->DeviceHandle   =
+      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
+      PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
+    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
+    NvdInfo->RegionOffset   = 0;
+    AcpiNvdInfoInit (
+      NvdInfo,
+      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
+      PLATFORM_NVDIMM_NVD3_DIMM_ID
+      );
+
+    NvdInfo = &NvdData[Socket].NvdInfo[1];
+    NvdInfo->DeviceHandle   =
+      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
+      PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
+    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
+    NvdInfo->RegionOffset   = PLATFORM_NVDIMM_HASHED_REGION_OFFSET;
+    AcpiNvdInfoInit (
+      NvdInfo,
+      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
+      PLATFORM_NVDIMM_NVD4_DIMM_ID
+      );
+
+    /* Update NvdNum */
+    NvdData[Socket].NvdNum = 0;
+    for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
+      if (NvdData[Socket].NvdInfo[Count].Enabled) {
+        NvdData[Socket].NvdNum++;
+      }
+    }
+    return EFI_SUCCESS;
+  }
+  /* NVDIMM_NON_HASHED */
+  NvdData[Socket].NvdNum = 0;
+  for (Count = 0; Count < NvdData[Socket].NvdRegionNum; Count++) {
+    RegionId = NvdData[Socket].NvdRegionId[Count];
+    if (PlatformHob->DramInfo.Base[RegionId] ==
+        PLATFORM_NVDIMM_SK0_NHASHED_REGION0 ||
+        PlatformHob->DramInfo.Base[RegionId] ==
+        PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
+    {
+      NvdInfo = &NvdData[Socket].NvdInfo[0];
+      NvdInfo->DeviceHandle   =
+        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
+        PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
+      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
+      NvdInfo->RegionOffset   = 0;
+      AcpiNvdInfoInit (
+        NvdInfo,
+        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
+        PLATFORM_NVDIMM_NVD3_DIMM_ID
+        );
+
+    } else if (PlatformHob->DramInfo.Base[RegionId] ==
+               PLATFORM_NVDIMM_SK0_NHASHED_REGION1 ||
+               PlatformHob->DramInfo.Base[RegionId] ==
+               PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
+    {
+      NvdInfo = &NvdData[Socket].NvdInfo[1];
+      NvdInfo->DeviceHandle   =
+        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
+        PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
+      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
+      NvdInfo->RegionOffset   = 0;
+      AcpiNvdInfoInit (
+        NvdInfo,
+        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
+        PLATFORM_NVDIMM_NVD4_DIMM_ID
+        );
+    }
+  }
+  /* Update NvdNum */
+  NvdData[Socket].NvdNum = 0;
+  for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
+    if (NvdData[Socket].NvdInfo[Count].Enabled) {
+      NvdData[Socket].NvdNum++;
+    }
+  }
+  return EFI_SUCCESS;
+}
+
+/*
+ * Fill in SPA structure
+ */
+VOID
+AcpiNfitFillSPA (
+  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
+  IN     UINTN                                                     NvdRegionIndex,
+  IN     UINT64                                                    NvdRegionBase,
+  IN     UINT64                                                    NvdRegionSize
+  )
+{
+  ASSERT (NfitSpaPointer != NULL);
+
+  NfitSpaPointer->Flags                            = 0;
+  NfitSpaPointer->SPARangeStructureIndex           = NvdRegionIndex;
+  NfitSpaPointer->SystemPhysicalAddressRangeBase   = NvdRegionBase;
+  NfitSpaPointer->SystemPhysicalAddressRangeLength = NvdRegionSize;
+}
+
+VOID
+NfitFillControlRegion (
+  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControlRegionPointer,
+  IN     NVDIMM_INFO                                       *NvdInfo,
+  IN     UINTN                                             NvdControlRegionIndex
+  )
+{
+  ASSERT (
+    NfitControlRegionPointer != NULL
+    && NvdInfo != NULL
+    );
+
+  NfitControlRegionPointer->NVDIMMControlRegionStructureIndex =
+    NvdControlRegionIndex;
+  NfitControlRegionPointer->VendorID = NvdInfo->VendorId;
+  NfitControlRegionPointer->DeviceID = NvdInfo->DeviceId;
+  NfitControlRegionPointer->RevisionID = NvdInfo->RevisionId;
+  NfitControlRegionPointer->SubsystemVendorID = NvdInfo->SubVendorId;
+  NfitControlRegionPointer->SubsystemDeviceID = NvdInfo->SubDeviceId;
+  NfitControlRegionPointer->SubsystemRevisionID = NvdInfo->SubRevisionId;
+  NfitControlRegionPointer->SerialNumber = NvdInfo->SerialNumber;
+}
+
+VOID
+NfitFillRegionMapping (
+  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer,
+  IN     EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer,
+  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
+  IN     NVDIMM_INFO                                               *NvdInfo,
+  IN     UINTN                                                     NvdRegionID
+  )
+{
+  ASSERT (
+    NfitRegionMappingPointer != NULL
+    && NfitRegionMappingPointer != NULL
+    && NfitRegionMappingPointer != NULL
+    && NfitRegionMappingPointer != NULL
+    && NvdInfo != NULL
+    );
+
+  NfitRegionMappingPointer->NVDIMMRegionID = NvdRegionID;
+  NfitRegionMappingPointer->NVDIMMPhysicalID = NvdInfo->PhysId;
+  NfitRegionMappingPointer->InterleaveWays = NvdInfo->InterleaveWays;
+  NfitRegionMappingPointer->RegionOffset = NvdInfo->RegionOffset;
+  NfitRegionMappingPointer->NVDIMMRegionSize = NvdInfo->NvdSize;
+  NfitRegionMappingPointer->NFITDeviceHandle.DIMMNumber =
+    NvdInfo->DeviceHandle & 0x0F;
+  NfitRegionMappingPointer->NFITDeviceHandle.MemoryChannelNumber =
+    (NvdInfo->DeviceHandle >> 4) & 0x0F;
+  NfitRegionMappingPointer->NFITDeviceHandle.MemoryControllerID =
+    (NvdInfo->DeviceHandle >> 8) & 0x0F;
+  NfitRegionMappingPointer->NFITDeviceHandle.SocketID =
+    (NvdInfo->DeviceHandle >> 12) & 0x0F;
+  NfitRegionMappingPointer->SPARangeStructureIndex =
+    NfitSpaPointer->SPARangeStructureIndex;
+  NfitRegionMappingPointer->NVDIMMPhysicalAddressRegionBase =
+    NfitSpaPointer->SystemPhysicalAddressRangeBase;
+  NfitRegionMappingPointer->NVDIMMControlRegionStructureIndex =
+    NfitControlRegionPointer->NVDIMMControlRegionStructureIndex;
+}
+
+EFI_STATUS
+AcpiNfitFillTableBySK (
+  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerStart,
+  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE **NfitSpaPointerNext,
+  IN     UINTN                                                     Socket
+  )
+{
+  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer;
+  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer;
+  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer;
+  PLATFORM_INFO_HOB                                         *PlatformHob;
+  VOID                                                      *Hob;
+  UINT64                                                    NvdRegionBase,
+                                                            NvdRegionSize;
+  UINTN NvdCount, MaxNvdCount, RegionCount;
+  UINTN RegionId, NvdRegionIndex, NvdIndex;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL
+      || NfitSpaPointerStart == NULL
+      || NfitSpaPointerNext == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformHob    = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+  NvdRegionIndex = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdRegionNum;
+  NvdIndex       = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdNum;
+  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
+    /* Table Type 0: SPA Range Structure */
+    NfitSpaPointer = NfitSpaPointerStart;
+    CopyMem (
+      (VOID *)NfitSpaPointer,
+      (VOID *)&NfitSPATemplate,
+      sizeof (NfitSPATemplate)
+      );
+    RegionId      = NvdData[Socket].NvdRegionId[0];
+    NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
+    NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
+    NvdRegionIndex++;
+    AcpiNfitFillSPA (
+      NfitSpaPointer,
+      NvdRegionIndex,
+      NvdRegionBase,
+      NvdRegionSize
+      );
+
+    NfitControlRegionPointer =
+      (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
+      (NfitSpaPointer + 1);
+    for (NvdCount = 0; NvdCount < NVDIMM_NUM_PER_SK; NvdCount++) {
+      if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
+        continue;
+      }
+      NvdIndex++;
+      /* Table Type 4: NVDIMM Control Region Structure Mark */
+      CopyMem (
+        (VOID *)NfitControlRegionPointer,
+        (VOID *)&NvdimmControlRegionTemplate,
+        sizeof (NvdimmControlRegionTemplate)
+        );
+      NfitFillControlRegion (
+        NfitControlRegionPointer,
+        &NvdData[Socket].NvdInfo[NvdCount],
+        NvdIndex
+        );
+
+      NfitRegionMappingPointer =
+        (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
+        (NfitControlRegionPointer + 1);
+
+      /* Table Type 1: NVDIMM Region Mapping Structure */
+      CopyMem (
+        (VOID *)NfitRegionMappingPointer,
+        (VOID *)&NvdimmRegionMappingTemplate,
+        sizeof (NvdimmRegionMappingTemplate)
+        );
+      NfitFillRegionMapping (
+        NfitRegionMappingPointer,
+        NfitControlRegionPointer,
+        NfitSpaPointer,
+        &NvdData[Socket].NvdInfo[NvdCount],
+        NvdIndex - 1
+        );
+
+      NfitControlRegionPointer =
+        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
+        (NfitRegionMappingPointer + 1);
+    }
+    NfitSpaPointer =
+      (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
+      NfitControlRegionPointer;
+  } else { /* NVDIMM_NON_HASHED */
+    NfitSpaPointer = NfitSpaPointerStart;
+    for (RegionCount = 0; RegionCount < NvdData[Socket].NvdRegionNum;
+         RegionCount++)
+    {
+      /* Table Type 0: SPA Range Structure */
+      CopyMem (
+        (VOID *)NfitSpaPointer,
+        (VOID *)&NfitSPATemplate,
+        sizeof (NfitSPATemplate)
+        );
+      RegionId      = NvdData[Socket].NvdRegionId[RegionCount];
+      NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
+      NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
+      NvdRegionIndex++;
+      AcpiNfitFillSPA (
+        NfitSpaPointer,
+        NvdRegionIndex,
+        NvdRegionBase,
+        NvdRegionSize
+        );
+
+      NfitControlRegionPointer =
+        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
+        (NfitSpaPointer + 1);
+      NvdCount = ((NvdRegionBase == PLATFORM_NVDIMM_SK0_NHASHED_REGION0) ||
+                  (NvdRegionBase == PLATFORM_NVDIMM_SK1_NHASHED_REGION0)) ?
+                 0 : PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
+      MaxNvdCount = NvdCount + PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
+      for (; NvdCount < MaxNvdCount; NvdCount++) {
+        if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
+          continue;
+        }
+        NvdIndex++;
+
+        /* Table Type 4: NVDIMM Control Region Structure Mark */
+        CopyMem (
+          (VOID *)NfitControlRegionPointer,
+          (VOID *)&NvdimmControlRegionTemplate,
+          sizeof (NvdimmControlRegionTemplate)
+          );
+        NfitFillControlRegion (
+          NfitControlRegionPointer,
+          &NvdData[Socket].NvdInfo[NvdCount],
+          NvdIndex
+          );
+
+        NfitRegionMappingPointer =
+          (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
+          (NfitControlRegionPointer + 1);
+
+        /* Table Type 1: NVDIMM Region Mapping Structure */
+        CopyMem (
+          (VOID *)NfitRegionMappingPointer,
+          (VOID *)&NvdimmRegionMappingTemplate,
+          sizeof (NvdimmRegionMappingTemplate)
+          );
+        NfitFillRegionMapping (
+          NfitRegionMappingPointer,
+          NfitControlRegionPointer,
+          NfitSpaPointer,
+          &NvdData[Socket].NvdInfo[NvdCount],
+          NvdIndex - 1
+          );
+
+        NfitControlRegionPointer =
+          (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
+          (NfitRegionMappingPointer + 1);
+      }
+      NfitSpaPointer =
+        (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
+        NfitControlRegionPointer;
+    }
+  }
+  /* Update NfitSpaPointerNext */
+  *NfitSpaPointerNext = NfitSpaPointer;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AcpiNfitFillTable (
+  IN EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer
+  )
+{
+  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerNext;
+
+  if (NfitTablePointer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  NfitSpaPointerNext = (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
+                       (NfitTablePointer + 1);
+
+  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
+    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK0);
+  }
+
+  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
+    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK1);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/*
+ * Install NFIT table.
+ */
+EFI_STATUS
+AcpiInstallNfitTable (
+  VOID
+  )
+{
+  EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer;
+  EFI_ACPI_TABLE_PROTOCOL                      *AcpiTableProtocol;
+  UINTN                                        NfitTableKey  = 0;
+  EFI_STATUS                                   Status;
+  UINTN                                        Size;
+  UINTN                                        NvdRegionNum;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = AcpiNvdDataInit (NVDIMM_SK0);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Status = AcpiNvdDataInit (NVDIMM_SK1);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  NvdRegionNum = NvdData[NVDIMM_SK0].NvdRegionNum +
+                 NvdData[NVDIMM_SK1].NvdRegionNum;
+  if (NvdRegionNum == 0) {
+    return EFI_INVALID_PARAMETER; /* No NVDIMM Region */
+  }
+  Size = sizeof (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE);
+  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
+    Size +=
+      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
+       NvdData[NVDIMM_SK0].NvdRegionNum) +
+      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
+       NvdData[NVDIMM_SK0].NvdNum) +
+      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
+       NvdData[NVDIMM_SK0].NvdNum);
+  }
+  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
+    Size +=
+      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
+       NvdData[NVDIMM_SK1].NvdRegionNum) +
+      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
+       NvdData[NVDIMM_SK1].NvdNum) +
+      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
+       NvdData[NVDIMM_SK1].NvdNum);
+  }
+  NfitTablePointer =
+    (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *)AllocateZeroPool (Size);
+  if (NfitTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem (
+    (VOID *)NfitTablePointer,
+    (VOID *)&NFITTableHeaderTemplate,
+    sizeof (NFITTableHeaderTemplate)
+    );
+
+  NfitTablePointer->Header.Length = Size;
+
+  Status = AcpiNfitFillTable (NfitTablePointer);
+  if (EFI_ERROR (Status)) {
+    FreePool ((VOID *)NfitTablePointer);
+    return Status;
+  }
+  AcpiTableChecksum (
+    (UINT8 *)NfitTablePointer,
+    NfitTablePointer->Header.Length
+    );
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)NfitTablePointer,
+                                NfitTablePointer->Header.Length,
+                                &NfitTableKey
+                                );
+  if (EFI_ERROR (Status)) {
+    FreePool ((VOID *)NfitTablePointer);
+  }
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
new file mode 100644
index 000000000000..296ae57aada0
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
@@ -0,0 +1,196 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/AcpiPccLib.h>
+#include "AcpiPlatform.h"
+
+EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS PcctSubspaceTemplate = {
+  EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS,
+  sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS),
+  0,                        // PlatformInterrupt
+  0,                        // PlatformInterruptFlags
+  0,                        // Reserved
+  0,                        // BaseAddress
+  0x100,                    // AddressLength
+  { 0, 0x20, 0, 0x3, 0x0 }, // DoorbellRegister
+  0,                        // DoorbellPreserve
+  0x53000040,               // DoorbellWrite
+  1,                        // NominalLatency
+  1,                        // MaximumPeriodicAccessRate
+  1,                        // MinimumRequestTurnaroundTime
+  { 0, 0x20, 0, 0x3, 0x0 }, // PlatformInterruptAckRegister
+  0,                        // PlatformInterruptAckPreserve
+  0x10001,                  // PlatformInterruptAckWrite
+};
+
+EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER PcctTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
+    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER,
+    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION
+    ),
+  EFI_ACPI_6_3_PCCT_FLAGS_PLATFORM_INTERRUPT,
+};
+
+EFI_STATUS
+AcpiPcctInit (
+  VOID
+  )
+{
+  UINT8  NumberOfSockets;
+  UINT8  Socket;
+  UINT16 Doorbell;
+  UINT16 Subspace;
+
+  NumberOfSockets = GetNumberOfActiveSockets ();
+  Subspace = 0;
+
+  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
+    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
+      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
+        continue;
+      }
+      AcpiPccInitSharedMemory (Socket, Doorbell, Subspace);
+      AcpiPccUnmaskDoorbellInterrupt (Socket, Doorbell);
+
+      Subspace++;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Install PCCT table.
+
+  Each socket has 16 PCC subspaces corresponding to 16 Mailbox/Doorbell channels
+    0 - 7  : PMpro subspaces
+    8 - 15 : SMpro subspaces
+
+  Please note that some SMpro/PMpro Doorbell are reserved for private use.
+  The reserved Doorbells are filtered by using the ACPI_PCC_AVAILABLE_DOORBELL_MASK
+  and ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS macro.
+
+**/
+EFI_STATUS
+AcpiInstallPcctTable (
+  VOID
+  )
+{
+  EFI_STATUS                                               Status;
+  EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *PcctTablePointer;
+  EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS   *PcctEntryPointer;
+  EFI_PHYSICAL_ADDRESS                                     PccSharedMemPointer;
+  EFI_ACPI_TABLE_PROTOCOL                                  *AcpiTableProtocol;
+  UINTN                                                    PcctTableKey;
+  UINT8                                                    NumberOfSockets;
+  UINT8                                                    Socket;
+  UINT16                                                   Doorbell;
+  UINT16                                                   Subspace;
+  UINT16                                                   NumberOfSubspaces;
+  UINTN                                                    Size;
+  UINTN                                                    DoorbellAddress;
+
+  Subspace = 0;
+  NumberOfSockets = GetNumberOfActiveSockets ();
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  NumberOfSubspaces = ACPI_PCC_MAX_SUBPACE_PER_SOCKET * NumberOfSockets;
+
+  AcpiPccAllocateSharedMemory (&PccSharedMemPointer, NumberOfSubspaces);
+  if (PccSharedMemPointer == 0) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
+          NumberOfSubspaces * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
+
+  PcctTablePointer = (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)AllocateZeroPool (Size);
+  if (PcctTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  PcctEntryPointer = (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)
+                      ((UINT64)PcctTablePointer + sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER));
+
+  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
+    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
+      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
+        continue;
+      }
+
+      CopyMem (
+        &PcctEntryPointer[Subspace],
+        &PcctSubspaceTemplate,
+        sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS)
+        );
+
+      PcctEntryPointer[Subspace].BaseAddress = (UINT64)PccSharedMemPointer + ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace;
+      PcctEntryPointer[Subspace].AddressLength = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE;
+
+      DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
+
+      PcctEntryPointer[Subspace].DoorbellRegister.Address = DoorbellAddress + DB_OUT_REG_OFST;
+      PcctEntryPointer[Subspace].PlatformInterrupt = MailboxGetDoorbellInterruptNumber (Socket, Doorbell);
+      PcctEntryPointer[Subspace].PlatformInterruptAckRegister.Address = DoorbellAddress + DB_STATUS_REG_OFST;
+
+      if (Doorbell == ACPI_PCC_CPPC_DOORBELL_ID) {
+        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_URGENT_CPPC_MESSAGE;
+        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_CPPC_NOMINAL_LATENCY_US;
+        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US;
+      } else {
+        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_TYPICAL_PCC_MESSAGE;
+        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_NOMINAL_LATENCY_US;
+        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US;
+      }
+      PcctEntryPointer[Subspace].MaximumPeriodicAccessRate = ACPI_PCC_MAX_PERIODIC_ACCESS_RATE;
+
+      Subspace++;
+    }
+  }
+
+  CopyMem (
+    PcctTablePointer,
+    &PcctTableHeaderTemplate,
+    sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER)
+    );
+
+  //
+  // Recalculate the size
+  //
+  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
+          Subspace * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
+
+  PcctTablePointer->Header.Length = Size;
+  AcpiTableChecksum (
+    (UINT8 *)PcctTablePointer,
+    PcctTablePointer->Header.Length
+    );
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)PcctTablePointer,
+                                PcctTablePointer->Header.Length,
+                                &PcctTableKey
+                                );
+  if (EFI_ERROR (Status)) {
+    AcpiPccFreeSharedMemory ();
+    FreePool ((VOID *)PcctTablePointer);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
new file mode 100644
index 000000000000..3ed3e98d00d2
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
@@ -0,0 +1,178 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiApei.h"
+#include "AcpiPlatform.h"
+
+STATIC EFI_EVENT mAcpiRegistration = NULL;
+
+/*
+ * This GUID must match the FILE_GUID in AcpiTables.inf of each boards
+ */
+STATIC CONST EFI_GUID mAcpiCommonTableFile = { 0xCEFA2AEB, 0x357E, 0x4F48, { 0x80, 0x66, 0xEA, 0x95, 0x08, 0x53, 0x05, 0x6E } } ;
+STATIC CONST EFI_GUID mJadeAcpiTableFile = { 0x5addbc13, 0x8634, 0x480c, { 0x9b, 0x94, 0x67, 0x1b, 0x78, 0x55, 0xcd, 0xb8 } };
+/**
+ * Callback called when ACPI Protocol is installed
+ */
+STATIC VOID
+AcpiNotificationEvent (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS                                   Status;
+  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
+
+  Status = LocateAndInstallAcpiFromFv (&mAcpiCommonTableFile);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = LocateAndInstallAcpiFromFv (&mJadeAcpiTableFile);
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Find ACPI table RSD_PTR from the system table.
+  //
+  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);
+  if (EFI_ERROR (Status)) {
+    Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);
+  }
+
+  if (!EFI_ERROR (Status) &&
+      Rsdp != NULL &&
+      Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION &&
+      Rsdp->RsdtAddress != 0)
+  {
+    // ARM Platforms must set the RSDT address to NULL
+    Rsdp->RsdtAddress = 0;
+  }
+
+  DEBUG ((DEBUG_INFO, "[%a:%d]-\n", __FUNCTION__, __LINE__));
+}
+
+VOID
+EFIAPI
+InstallAcpiOnReadyToBoot (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS Status;
+
+  Status = AcpiInstallMadtTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Installed MADT table\n"));
+  }
+
+  Status = AcpiInstallPpttTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Installed PPTT table\n"));
+  }
+
+  Status = AcpiInstallSlitTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Installed SLIT table\n"));
+  }
+
+  Status = AcpiInstallSratTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Installed SRAT table\n"));
+  }
+
+  Status = AcpiInstallPcctTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Installed PCCT table\n"));
+  }
+
+  Status = AcpiInstallNfitTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Installed NFIT table\n"));
+  }
+
+  Status = AcpiPopulateBert ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "Populate BERT record\n"));
+  }
+
+  //
+  // Close the event, so it will not be signalled again.
+  //
+  gBS->CloseEvent (Event);
+}
+
+VOID
+EFIAPI
+UpdateAcpiOnExitBootServices (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS Status;
+
+  Status = AcpiPatchDsdtTable ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "DSDT Table updated!\n"));
+  }
+
+  // Configure ACPI Platform Error Interfaces
+  Status = AcpiApeiUpdate ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "APEI Table updated!\n"));
+  }
+
+  // Configure PCC mailbox base address and unmask interrupt
+  Status = AcpiPcctInit ();
+  if (!EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_INFO, "PCCT Table updated!\n"));
+  }
+
+  //
+  // Close the event, so it will not be signalled again.
+  //
+  gBS->CloseEvent (Event);
+}
+
+EFI_STATUS
+EFIAPI
+AcpiPlatformDxeInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_EVENT  ReadyToBootEvent;
+  EFI_EVENT  ExitBootServicesEvent;
+  EFI_STATUS Status;
+
+  EfiCreateProtocolNotifyEvent (
+    &gEfiAcpiTableProtocolGuid,
+    TPL_CALLBACK,
+    AcpiNotificationEvent,
+    NULL,
+    &mAcpiRegistration
+    );
+
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
+                  TPL_CALLBACK,
+                  UpdateAcpiOnExitBootServices,
+                  NULL,
+                  &ExitBootServicesEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  InstallAcpiOnReadyToBoot,
+                  NULL,
+                  &gEfiEventReadyToBootGuid,
+                  &ReadyToBootEvent
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
new file mode 100644
index 000000000000..97adb66beed3
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
@@ -0,0 +1,378 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiPlatform.h"
+
+EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR PPTTProcessorTemplate = {
+  EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR,
+  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR),
+  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
+  {0}, /* Flags */
+  0,   /* Parent */
+  0,   /* AcpiProcessorId */
+  0    /* NumberOfPrivateResources */
+};
+
+EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE PPTTCacheTemplate = {
+  EFI_ACPI_6_3_PPTT_TYPE_CACHE,
+  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE),
+  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
+  {0}, /* Flags */
+  0,   /* NextLevelOfCache */
+  0,   /* Size */
+  0,   /* NumberOfSets */
+  0,   /* Associativity */
+  {0}, /* Attributes */
+  0
+};
+
+EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER PPTTTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
+    0, /* need fill in */
+    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
+    ),
+};
+
+STATIC EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *PpttTablePointer;
+STATIC UINT32                                                  PpttClusterOffset[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET];
+STATIC UINT32                                                  PpttSocketOffset[PLATFORM_CPU_MAX_SOCKET];
+STATIC UINT32                                                  PpttRootOffset;
+STATIC UINT32                                                  PpttL1DataCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
+STATIC UINT32                                                  PpttL1InstructionCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
+STATIC UINT32                                                  PpttL2CacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
+STATIC UINT32                                                  PpttSLCCacheOffset[PLATFORM_CPU_MAX_SOCKET];
+
+UINT32
+AcpiPpttProcessorCoreNode (
+  VOID   *EntryPointer,
+  UINT32 CpuId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
+  UINT32                                *ResPointer;
+  UINTN                                 ClusterIdPerSocket, CoreIdPerCpm, SocketId;
+
+  CopyMem (
+    PpttProcessorEntryPointer,
+    &PPTTProcessorTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
+    );
+
+  ClusterIdPerSocket = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM;
+  SocketId = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) / PLATFORM_CPU_MAX_CPM;
+  CoreIdPerCpm = CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM;
+  PpttProcessorEntryPointer->Flags.AcpiProcessorIdValid = 1;
+  PpttProcessorEntryPointer->Flags.NodeIsALeaf = 1;
+  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
+  PpttProcessorEntryPointer->AcpiProcessorId = (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) | (ClusterIdPerSocket << 8) | CoreIdPerCpm;
+  PpttProcessorEntryPointer->Parent = (UINT32)PpttClusterOffset[CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM];
+  PpttProcessorEntryPointer->NumberOfPrivateResources = 2; /* L1I + L1D */
+
+  ResPointer = (UINT32 *)((UINT64)EntryPointer +
+                          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
+  ResPointer[0] = PpttL1InstructionCacheOffset[CpuId];
+  ResPointer[1] = PpttL1DataCacheOffset[CpuId];
+
+  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32);
+
+  return PpttProcessorEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttClusterNode (
+  VOID   *EntryPointer,
+  UINT32 ClusterId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
+
+  PpttClusterOffset[ClusterId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+
+  CopyMem (
+    PpttProcessorEntryPointer,
+    &PPTTProcessorTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
+    );
+
+  PpttProcessorEntryPointer->Parent = (UINT32)PpttSocketOffset[ClusterId / PLATFORM_CPU_MAX_CPM];
+  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
+
+  return PpttProcessorEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttSocketNode (
+  VOID   *EntryPointer,
+  UINT32 SocketId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
+  UINT32                                *ResPointer;
+
+  PpttSocketOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+
+  CopyMem (
+    PpttProcessorEntryPointer,
+    &PPTTProcessorTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
+    );
+
+  PpttProcessorEntryPointer->Flags.PhysicalPackage = 1;
+  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
+  PpttProcessorEntryPointer->Parent = (UINT32)PpttRootOffset;
+
+  PpttProcessorEntryPointer->NumberOfPrivateResources = 1;
+  ResPointer = (UINT32 *)((UINT64)EntryPointer + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
+  ResPointer[0] = PpttSLCCacheOffset[SocketId];
+
+  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32);
+
+  return PpttProcessorEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttRootNode (
+  VOID *EntryPointer
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
+
+  PpttRootOffset = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+
+  CopyMem (
+    PpttProcessorEntryPointer,
+    &PPTTProcessorTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
+    );
+
+  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
+
+  return PpttProcessorEntryPointer->Length;
+}
+
+STATIC VOID
+AcpiPpttFillCacheSizeInfo (
+  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *Node,
+  UINT32                            Level
+  )
+{
+  UINT64 CacheCCSIDR;
+  UINT32 CacheLineSize;
+  UINT32 Count;
+
+  CacheCCSIDR = ReadCCSIDR (Level);
+
+  CacheLineSize = 1;
+  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
+  while (Count-- > 0) {
+    CacheLineSize *= 2;
+  }
+
+  Node->Flags.LineSizeValid = 1;
+  Node->Flags.NumberOfSetsValid = 1;
+  Node->Flags.AssociativityValid = 1;
+  Node->Flags.SizePropertyValid = 1;
+  Node->Flags.CacheTypeValid = 1;
+  Node->NumberOfSets = CCSIDR_NUMSETS (CacheCCSIDR) + 1;
+  Node->Associativity = CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1;
+  Node->LineSize = CacheLineSize;
+  Node->Size = Node->NumberOfSets *
+               Node->Associativity *
+               Node->LineSize;
+}
+
+STATIC UINT32
+AcpiPpttL1DataCacheNode (
+  VOID   *EntryPointer,
+  UINT32 CpuId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
+
+  PpttL1DataCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+  CopyMem (
+    PpttCacheEntryPointer,
+    &PPTTCacheTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
+    );
+
+  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
+  PpttCacheEntryPointer->Attributes.CacheType = 0x0; /* Data Cache */
+  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
+
+  return PpttCacheEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttL1InstructionCacheNode (
+  VOID   *EntryPointer,
+  UINT32 CpuId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
+
+  PpttL1InstructionCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+  CopyMem (
+    PpttCacheEntryPointer,
+    &PPTTCacheTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
+    );
+
+  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
+  PpttCacheEntryPointer->Attributes.CacheType = 0x1; /* Instruction Cache */
+  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
+
+  return PpttCacheEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttL2CacheNode (
+  VOID   *EntryPointer,
+  UINT32 CpuId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
+
+  PpttL2CacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+  CopyMem (
+    PpttCacheEntryPointer,
+    &PPTTCacheTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
+    );
+
+  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 2);
+  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
+  PpttCacheEntryPointer->NextLevelOfCache = 0;
+
+  return PpttCacheEntryPointer->Length;
+}
+
+STATIC UINT32
+AcpiPpttSLCCacheNode (
+  VOID   *EntryPointer,
+  UINT32 SocketId
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
+
+  PpttSLCCacheOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
+  CopyMem (
+    PpttCacheEntryPointer,
+    &PPTTCacheTemplate,
+    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
+    );
+
+  PpttCacheEntryPointer->Flags.LineSizeValid = 1;
+  PpttCacheEntryPointer->Flags.NumberOfSetsValid = 1;
+  PpttCacheEntryPointer->Flags.AssociativityValid = 1;
+  PpttCacheEntryPointer->Flags.SizePropertyValid = 1;
+  PpttCacheEntryPointer->Flags.CacheTypeValid = 1;
+
+  PpttCacheEntryPointer->Size = 0x2000000; /* 32 MB */
+  PpttCacheEntryPointer->NumberOfSets = 0x400; /* 1024 sets per 1MB HN-F */
+
+  PpttCacheEntryPointer->Associativity = 0x10; /* 16-way set-associative */
+  PpttCacheEntryPointer->LineSize = 0x40; /* 64 bytes */
+  PpttCacheEntryPointer->NextLevelOfCache = 0;
+
+  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
+
+  return PpttCacheEntryPointer->Length;
+}
+
+/*
+ *  Install PPTT table.
+ */
+EFI_STATUS
+AcpiInstallPpttTable (
+  VOID
+  )
+{
+  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = NULL;
+  EFI_ACPI_TABLE_PROTOCOL               *AcpiTableProtocol;
+  UINTN                                 PpttTableKey  = 0;
+  UINTN                                 Count;
+  EFI_STATUS                            Status;
+  UINTN                                 Size;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER) +
+          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) +                                                        /* Root node */
+          (PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                                /* SLC node */
+          (PLATFORM_CPU_MAX_SOCKET * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32))) +        /* Socket node */
+          (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)) +     /* Cluster node */
+          (PLATFORM_CPU_MAX_NUM_CORES * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32))) + /* Core node */
+          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1I node */
+          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1D node */
+          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE));                              /* L2 node */
+
+  PpttTablePointer =
+    (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *)AllocateZeroPool (Size);
+  if (PpttTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  PpttProcessorEntryPointer =
+    (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *)((UINT64)PpttTablePointer +
+                                              sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER));
+
+  Size = 0;
+  Size += AcpiPpttRootNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size));
+
+  for (Count = 0; Count < PLATFORM_CPU_MAX_SOCKET; Count++) {
+    Size += AcpiPpttSLCCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+    Size += AcpiPpttSocketNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+  }
+
+  for (Count = 0; Count < PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET; Count++) {
+    Size += AcpiPpttClusterNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+  }
+
+  for (Count = 0; Count < PLATFORM_CPU_MAX_NUM_CORES; Count++) {
+    Size += AcpiPpttL2CacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+    Size += AcpiPpttL1InstructionCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+    Size += AcpiPpttL1DataCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+    Size += AcpiPpttProcessorCoreNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
+  }
+
+  CopyMem (
+    PpttTablePointer,
+    &PPTTTableHeaderTemplate,
+    sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER)
+    );
+
+  Size += sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER);
+  PpttTablePointer->Header.Length = Size;
+
+  AcpiTableChecksum (
+    (UINT8 *)PpttTablePointer,
+    PpttTablePointer->Header.Length
+    );
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)PpttTablePointer,
+                                PpttTablePointer->Header.Length,
+                                &PpttTableKey
+                                );
+  FreePool ((VOID *)PpttTablePointer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
new file mode 100644
index 000000000000..60acdb9dd5db
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
@@ -0,0 +1,190 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiPlatform.h"
+
+#define MAX_NODES_PER_SOCKET          4
+#define SELF_DISTANCE                 10
+#define REMOTE_DISTANCE               20
+
+EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER SLITTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,
+    0, /* need fill in */
+    EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION
+    ),
+  0,
+};
+
+VOID
+ComputeCoordinatesForNode (
+  UINTN Node,
+  UINTN *X,
+  UINTN *Y
+  )
+{
+  switch (Node) {
+  case 0:
+    *X = 0;
+    *Y = 0;
+    break;
+  case 1:
+    *X = 1;
+    *Y = 0;
+    break;
+  case 2:
+    *X = 0;
+    *Y = 1;
+    break;
+  case 3:
+    *X = 1;
+    *Y = 1;
+    break;
+  default:
+    *X = 0;
+    *Y = 0;
+    break;
+  }
+}
+
+/**
+  Compute the distance between between two nodes on socket.
+**/
+UINT8
+ComputeSlitDistanceOnSocket (
+  UINTN Node1,
+  UINTN Node2
+  )
+{
+  UINTN X1, Y1, X2, Y2;
+  UINTN XDistance, YDistance;
+
+  ComputeCoordinatesForNode (Node1, &X1, &Y1);
+  ComputeCoordinatesForNode (Node2, &X2, &Y2);
+
+  XDistance = ABS ((INTN)(X1 - X2));
+  YDistance = ABS ((INTN)(Y1 - Y2));
+
+  return (UINT8)(XDistance + YDistance + SELF_DISTANCE);
+}
+
+/**
+  Compute the distance between between two nodes on
+  different sockets.
+  Node1 - local socket node number
+  Node2 - remote socket node number
+**/
+UINT8
+ComputeSlitDistanceOnRemoteSocket (
+  UINTN LocalNode,
+  UINTN RemoteNode
+  )
+{
+  UINTN LocalDistance, RemoteDistance;
+
+  //
+  // Mesh forwards traffic between sockets over both CCIX links when going from
+  // one quadrant to another. For example, memory access from Node 0 to Node 4
+  // results in traffic being split between RCA0 and 1. Hence distance is
+  // different only between upper half and lower half of sockets and not
+  // between quadrants. Hemisphere configuration is not impacted as there
+  // is no upper-half.
+  //
+  LocalDistance = 0;
+  RemoteDistance = 0;
+  if (LocalNode >= (MAX_NODES_PER_SOCKET / 2)) {
+    LocalDistance = 1;
+  }
+  if (RemoteNode >= (MAX_NODES_PER_SOCKET / 2)) {
+    RemoteDistance = 1;
+  }
+
+  return (UINT8)(LocalDistance + RemoteDistance + REMOTE_DISTANCE);
+}
+
+UINT8
+ComputeSlitDistance (
+  UINTN Node1,
+  UINTN Node2,
+  UINTN DomainsPerSocket
+  )
+{
+  UINT8 Distance;
+
+  Distance = 0;
+  if ((Node1 / DomainsPerSocket) == (Node2 / DomainsPerSocket)) {
+    Distance = ComputeSlitDistanceOnSocket (
+                 Node1 % DomainsPerSocket,
+                 Node2 % DomainsPerSocket
+                 );
+  } else {
+    Distance = ComputeSlitDistanceOnRemoteSocket (
+                 Node1 % DomainsPerSocket,
+                 Node2 % DomainsPerSocket
+                 );
+  }
+
+  return Distance;
+}
+
+EFI_STATUS
+AcpiInstallSlitTable (
+  VOID
+  )
+{
+  EFI_ACPI_TABLE_PROTOCOL                                        *AcpiTableProtocol;
+  EFI_STATUS                                                     Status;
+  UINTN                                                          NumDomain, Count, Count1;
+  EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *SlitTablePointer;
+  UINT8                                                          *TmpPtr;
+  UINTN                                                          SlitTableKey;
+  UINTN                                                          NumDomainPerSocket;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  NumDomainPerSocket = CpuGetNumberOfSubNumaRegion ();
+  NumDomain = NumDomainPerSocket * GetNumberOfActiveSockets ();
+
+  SlitTablePointer = (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *)
+                     AllocateZeroPool (sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain);
+  if (SlitTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem ((VOID *)SlitTablePointer, (VOID *)&SLITTableHeaderTemplate, sizeof (SLITTableHeaderTemplate));
+  SlitTablePointer->NumberOfSystemLocalities = NumDomain;
+  TmpPtr = (UINT8 *)SlitTablePointer + sizeof (SLITTableHeaderTemplate);
+  for (Count = 0; Count < NumDomain; Count++) {
+    for (Count1 = 0; Count1 < NumDomain; Count1++, TmpPtr++) {
+      *TmpPtr = ComputeSlitDistance (Count, Count1, NumDomainPerSocket);
+    }
+  }
+
+  SlitTablePointer->Header.Length = sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain;
+
+  AcpiTableChecksum (
+    (UINT8 *)SlitTablePointer,
+    SlitTablePointer->Header.Length
+    );
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)SlitTablePointer,
+                                SlitTablePointer->Header.Length,
+                                &SlitTableKey
+                                );
+  FreePool ((VOID *)SlitTablePointer);
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
new file mode 100644
index 000000000000..5f3b7007623a
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
@@ -0,0 +1,274 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/ArmMpCoreInfo.h>
+#include "AcpiPlatform.h"
+
+EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER SRATTableHeaderTemplate = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
+    0, /* need fill in */
+    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION
+    ),
+  0x00000001,
+  0x0000000000000000,
+};
+
+EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE GicItsAffinityTemplate = {
+  .Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY,
+  sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE),
+  .ProximityDomain = 0, /* ProximityDomain */
+  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
+  .ItsId = 0,
+};
+
+STATIC
+UINTN
+SratCalculateNumMemoryRegion (
+  VOID
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  UINTN              Count;
+  UINT64             TmpVal;
+  VOID               *Hob;
+  UINTN              Result;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return 0;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  Result = 0;
+  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+    TmpVal = PlatformHob->DramInfo.Size[Count];
+    if (TmpVal > 0) {
+      Result++;
+    }
+  }
+
+  return Result;
+}
+
+STATIC
+EFI_STATUS
+SratAddMemAffinity (
+  EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *SratMemAffinity
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  UINTN              Count, NumRegion;
+  UINT64             RegionSize, RegionBase;
+  VOID               *Hob;
+  UINTN              ProximityDomain;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  NumRegion = 0;
+
+  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
+    RegionSize = PlatformHob->DramInfo.Size[Count];
+    RegionBase = PlatformHob->DramInfo.Base[Count];
+    ProximityDomain = PlatformHob->DramInfo.Node[Count];
+    if (RegionSize > 0) {
+      ZeroMem ((VOID *)&SratMemAffinity[NumRegion], sizeof (SratMemAffinity[NumRegion]));
+      SratMemAffinity[NumRegion].Flags = EFI_ACPI_6_3_MEMORY_ENABLED;
+      if (PlatformHob->DramInfo.NvdRegion[Count] != 0) {
+        /* Mark NVDIMM-N region as HOT_PLUGGABLE and NON-VOLATILE */
+        SratMemAffinity[NumRegion].Flags |= EFI_ACPI_6_3_MEMORY_HOT_PLUGGABLE |
+                                            EFI_ACPI_6_3_MEMORY_NONVOLATILE;
+      }
+      SratMemAffinity[NumRegion].LengthLow =
+        (UINT32)(RegionSize & 0xFFFFFFFF);
+      SratMemAffinity[NumRegion].LengthHigh =
+        (UINT32)((RegionSize & 0xFFFFFFFF00000000ULL) >> 32);
+      SratMemAffinity[NumRegion].AddressBaseLow =
+        (UINT32)(RegionBase & 0xFFFFFFFF);
+      SratMemAffinity[NumRegion].AddressBaseHigh =
+        (UINT32)((RegionBase & 0xFFFFFFFF00000000ULL) >> 32);
+      SratMemAffinity[NumRegion].ProximityDomain = (UINT32)(ProximityDomain);
+      SratMemAffinity[NumRegion].Type = EFI_ACPI_6_3_MEMORY_AFFINITY;
+      SratMemAffinity[NumRegion].Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
+      NumRegion++;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SratAddGiccAffinity (
+  EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *SratGiccAffinity
+  )
+{
+  ARM_PROCESSOR_TABLE *ArmProcessorTable;
+  ARM_CORE_INFO       *ArmCoreInfoTable;
+  UINTN               Count, NumNode, Idx;
+  UINT32              AcpiProcessorUid;
+  UINT8               Socket;
+  UINT8               Cpm;
+
+  for (Idx = 0; Idx < gST->NumberOfTableEntries; Idx++) {
+    if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Idx].VendorGuid))) {
+      ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Idx].VendorTable;
+      ArmCoreInfoTable = ArmProcessorTable->ArmCpus;
+      break;
+    }
+  }
+
+  if (Idx == gST->NumberOfTableEntries) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Count = 0;
+  NumNode = 0;
+  while (Count != ArmProcessorTable->NumberOfEntries) {
+    for (Idx = 0; Idx < ArmProcessorTable->NumberOfEntries; Idx++ ) {
+      Socket = ArmCoreInfoTable[Idx].ClusterId;
+      Cpm = (ArmCoreInfoTable[Idx].CoreId >> PLATFORM_CPM_UID_BIT_OFFSET);
+      if (CpuGetSubNumNode (Socket, Cpm) != NumNode) {
+        /* We add nodes based on ProximityDomain order */
+        continue;
+      }
+      AcpiProcessorUid = (ArmCoreInfoTable[Idx].ClusterId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
+                         ArmCoreInfoTable[Idx].CoreId;
+      ZeroMem ((VOID *)&SratGiccAffinity[Count], sizeof (SratGiccAffinity[Count]));
+      SratGiccAffinity[Count].AcpiProcessorUid = AcpiProcessorUid;
+      SratGiccAffinity[Count].Flags = 1;
+      SratGiccAffinity[Count].Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
+      SratGiccAffinity[Count].Type = EFI_ACPI_6_3_GICC_AFFINITY;
+      SratGiccAffinity[Count].ProximityDomain = CpuGetSubNumNode (Socket, Cpm);
+      Count++;
+    }
+    NumNode++;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC UINT32
+InstallGicItsAffinity (
+  VOID   *EntryPointer,
+  UINT32 Index
+  )
+{
+  EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *ItsAffinityEntryPointer = EntryPointer;
+  UINTN                                   Size;
+
+  Size = sizeof (GicItsAffinityTemplate);
+  CopyMem (ItsAffinityEntryPointer, &GicItsAffinityTemplate, Size);
+  return Size;
+}
+
+STATIC
+EFI_STATUS
+SratAddGicItsAffinity (
+  VOID *TmpPtr
+  )
+{
+  UINTN Size = 0;
+  UINTN Index;
+
+  /* Install Gic ITSAffinity */
+  if (!IsSlaveSocketPresent ()) {
+    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
+      GicItsAffinityTemplate.ItsId = Index;
+      GicItsAffinityTemplate.ProximityDomain = 0;
+      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
+    }
+  }
+
+  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
+    GicItsAffinityTemplate.ItsId = Index;
+    GicItsAffinityTemplate.ProximityDomain = 0;
+    Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
+  }
+
+  if (IsSlaveSocketActive ()) {
+    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
+      GicItsAffinityTemplate.ItsId = Index;
+      GicItsAffinityTemplate.ProximityDomain = 1;
+      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+AcpiInstallSratTable (
+  VOID
+  )
+{
+  EFI_ACPI_TABLE_PROTOCOL                            *AcpiTableProtocol;
+  EFI_STATUS                                         Status;
+  EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratTablePointer;
+  UINT8                                              *TmpPtr;
+  UINTN                                              SratTableKey;
+  UINTN                                              Size;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Size = sizeof (SRATTableHeaderTemplate) +
+         SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) +
+         GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) +
+         ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate));
+  if (IsSlaveSocketActive ()) {
+    Size += (SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate);
+  } else if (!IsSlaveSocketPresent ()) {
+    Size += 2 * sizeof (GicItsAffinityTemplate); /* RCA0/1 */
+  }
+
+  SratTablePointer = (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)AllocateZeroPool (Size);
+  if (SratTablePointer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  CopyMem ((VOID *)SratTablePointer, (VOID *)&SRATTableHeaderTemplate, sizeof (SRATTableHeaderTemplate));
+
+  TmpPtr = (UINT8 *)SratTablePointer + sizeof (SRATTableHeaderTemplate);
+  Status = SratAddMemAffinity ((EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)TmpPtr);
+  ASSERT_EFI_ERROR (Status);
+
+  TmpPtr += SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
+  Status = SratAddGiccAffinity ((EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)TmpPtr);
+  ASSERT_EFI_ERROR (Status);
+
+  TmpPtr += GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
+  SratAddGicItsAffinity ((VOID *)(UINT64)TmpPtr);
+  SratTablePointer->Header.Length = Size;
+
+  AcpiTableChecksum (
+    (UINT8 *)SratTablePointer,
+    SratTablePointer->Header.Length
+    );
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                (VOID *)SratTablePointer,
+                                SratTablePointer->Header.Length,
+                                &SratTableKey
+                                );
+  FreePool ((VOID *)SratTablePointer);
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
new file mode 100755
index 000000000000..023509412f04
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
@@ -0,0 +1,5639 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(C000) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x0)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 0, 0xFD, 2}
+  }) // Domain 0
+}
+
+Device(C001) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 1, 0xFD, 2}
+  }) // Domain 1
+}
+
+Device(C002) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 2, 0xFD, 2}
+  }) // Domain 2
+}
+
+Device(C003) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 3, 0xFD, 2}
+  }) // Domain 3
+}
+
+Device(C004) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 4, 0xFD, 2}
+  }) // Domain 4
+}
+
+Device(C005) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 5, 0xFD, 2}
+  }) // Domain 5
+}
+
+Device(C006) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 6, 0xFD, 2}
+  }) // Domain 6
+}
+
+Device(C007) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 7, 0xFD, 2}
+  }) // Domain 7
+}
+
+Device(C008) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 8, 0xFD, 2}
+  }) // Domain 8
+}
+
+Device(C009) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 9, 0xFD, 2}
+  }) // Domain 9
+}
+
+Device(C010) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 10, 0xFD, 2}
+  }) // Domain 10
+}
+
+Device(C011) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 11, 0xFD, 2}
+  }) // Domain 11
+}
+
+Device(C012) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 12, 0xFD, 2}
+  }) // Domain 12
+}
+
+Device(C013) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 13, 0xFD, 2}
+  }) // Domain 13
+}
+
+Device(C014) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 14, 0xFD, 2}
+  }) // Domain 14
+}
+
+Device(C015) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 15, 0xFD, 2}
+  }) // Domain 15
+}
+
+Device(C016) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 16, 0xFD, 2}
+  }) // Domain 16
+}
+
+Device(C017) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 17, 0xFD, 2}
+  }) // Domain 17
+}
+
+Device(C018) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 18, 0xFD, 2}
+  }) // Domain 18
+}
+
+Device(C019) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 19, 0xFD, 2}
+  }) // Domain 19
+}
+
+Device(C020) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xa00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 20, 0xFD, 2}
+  }) // Domain 20
+}
+
+Device(C021) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xa01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 21, 0xFD, 2}
+  }) // Domain 21
+}
+
+Device(C022) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xb00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 22, 0xFD, 2}
+  }) // Domain 22
+}
+
+Device(C023) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xb01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 23, 0xFD, 2}
+  }) // Domain 23
+}
+
+Device(C024) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xc00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 24, 0xFD, 2}
+  }) // Domain 24
+}
+
+Device(C025) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xc01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 25, 0xFD, 2}
+  }) // Domain 25
+}
+
+Device(C026) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xd00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 26, 0xFD, 2}
+  }) // Domain 26
+}
+
+Device(C027) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xd01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 27, 0xFD, 2}
+  }) // Domain 27
+}
+
+Device(C028) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xe00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 28, 0xFD, 2}
+  }) // Domain 28
+}
+
+Device(C029) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xe01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 29, 0xFD, 2}
+  }) // Domain 29
+}
+
+Device(C030) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xf00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 30, 0xFD, 2}
+  }) // Domain 30
+}
+
+Device(C031) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0xf01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 31, 0xFD, 2}
+  }) // Domain 31
+}
+
+Device(C032) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 32, 0xFD, 2}
+  }) // Domain 32
+}
+
+Device(C033) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 33, 0xFD, 2}
+  }) // Domain 33
+}
+
+Device(C034) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 34, 0xFD, 2}
+  }) // Domain 34
+}
+
+Device(C035) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 35, 0xFD, 2}
+  }) // Domain 35
+}
+
+Device(C036) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 36, 0xFD, 2}
+  }) // Domain 36
+}
+
+Device(C037) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 37, 0xFD, 2}
+  }) // Domain 37
+}
+
+Device(C038) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 38, 0xFD, 2}
+  }) // Domain 38
+}
+
+Device(C039) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 39, 0xFD, 2}
+  }) // Domain 39
+}
+
+Device(C040) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 40, 0xFD, 2}
+  }) // Domain 40
+}
+
+Device(C041) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 41, 0xFD, 2}
+  }) // Domain 41
+}
+
+Device(C042) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 42, 0xFD, 2}
+  }) // Domain 42
+}
+
+Device(C043) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 2)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 2)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 2)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 2)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 2)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 2)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 43, 0xFD, 2}
+  }) // Domain 43
+}
+
+Device(C044) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 44, 0xFD, 2}
+  }) // Domain 44
+}
+
+Device(C045) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 45, 0xFD, 2}
+  }) // Domain 45
+}
+
+Device(C046) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 46, 0xFD, 2}
+  }) // Domain 46
+}
+
+Device(C047) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 47, 0xFD, 2}
+  }) // Domain 47
+}
+
+Device(C048) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 48, 0xFD, 2}
+  }) // Domain 48
+}
+
+Device(C049) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 49, 0xFD, 2}
+  }) // Domain 49
+}
+
+Device(C050) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 50, 0xFD, 2}
+  }) // Domain 50
+}
+
+Device(C051) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 2)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 51, 0xFD, 2}
+  }) // Domain 51
+}
+
+Device(C052) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 52, 0xFD, 2}
+  }) // Domain 52
+}
+
+Device(C053) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 53, 0xFD, 2}
+  }) // Domain 53
+}
+
+Device(C054) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 54, 0xFD, 2}
+  }) // Domain 54
+}
+
+Device(C055) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 55, 0xFD, 2}
+  }) // Domain 5
+}
+
+Device(C056) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 56, 0xFD, 2}
+  }) // Domain 56
+}
+
+Device(C057) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 57, 0xFD, 2}
+  }) // Domain 57
+}
+
+Device(C058) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 58, 0xFD, 2}
+  }) // Domain 58
+}
+
+Device(C059) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 59, 0xFD, 2}
+  }) // Domain 59
+}
+
+Device(C060) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 60, 0xFD, 2}
+  }) // Domain 60
+}
+
+Device(C061) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 61, 0xFD, 2}
+  }) // Domain 61
+}
+
+Device(C062) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 62, 0xFD, 2}
+  }) // Domain 62
+}
+
+Device(C063) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x1f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 63, 0xFD, 2}
+  }) // Domain 63
+}
+
+Device(C064) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 64, 0xFD, 2}
+  }) // Domain 64
+}
+
+Device(C065) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 65, 0xFD, 2}
+  }) // Domain 65
+}
+
+Device(C066) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 66, 0xFD, 2}
+  }) // Domain 66
+}
+
+Device(C067) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 67, 0xFD, 2}
+  }) // Domain 67
+}
+
+Device(C068) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 68, 0xFD, 2}
+  }) // Domain 68
+}
+
+Device(C069) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 69, 0xFD, 2}
+  }) // Domain 69
+}
+
+Device(C070) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 70, 0xFD, 2}
+  }) // Domain 70
+}
+
+Device(C071) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 71, 0xFD, 2}
+  }) // Domain 71
+}
+
+Device(C072) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 72, 0xFD, 2}
+  }) // Domain 72
+}
+
+Device(C073) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 73, 0xFD, 2}
+  }) // Domain 73
+}
+
+Device(C074) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 74, 0xFD, 2}
+  }) // Domain 74
+}
+
+Device(C075) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 75, 0xFD, 2}
+  }) // Domain 75
+}
+
+Device(C076) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 76, 0xFD, 2}
+  }) // Domain 76
+}
+
+Device(C077) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 77, 0xFD, 2}
+  }) // Domain 77
+}
+
+Device(C078) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 78, 0xFD, 2}
+  }) // Domain 78
+}
+
+Device(C079) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 79, 0xFD, 2}
+  }) // Domain 79
+}
+
+Device(C080) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 80, 0xFD, 2}
+  }) // Domain 80
+}
+
+Device(C081) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 81, 0xFD, 2}
+  }) // Domain 81
+}
+
+Device(C082) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 82, 0xFD, 2}
+  }) // Domain 82
+}
+
+Device(C083) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 83, 0xFD, 2}
+  }) // Domain 83
+}
+
+Device(C084) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 84, 0xFD, 2}
+  }) // Domain 84
+}
+
+Device(C085) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 85, 0xFD, 2}
+  }) // Domain 85
+}
+
+Device(C086) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 86, 0xFD, 2}
+  }) // Domain 86
+}
+
+Device(C087) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 87, 0xFD, 2}
+  }) // Domain 87
+}
+
+Device(C088) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 88, 0xFD, 2}
+  }) // Domain 88
+}
+
+Device(C089) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 89, 0xFD, 2}
+  }) // Domain 89
+}
+
+Device(C090) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 90, 0xFD, 2}
+  }) // Domain 90
+}
+
+Device(C091) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 91, 0xFD, 2}
+  }) // Domain 91
+}
+
+Device(C092) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 92, 0xFD, 2}
+  }) // Domain 92
+}
+
+Device(C093) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 93, 0xFD, 2}
+  }) // Domain 93
+}
+
+Device(C094) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 94, 0xFD, 2}
+  }) // Domain 94
+}
+
+Device(C095) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x2f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 95, 0xFD, 2}
+  }) // Domain 95
+}
+
+Device(C096) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 96, 0xFD, 2}
+  }) // Domain 96
+}
+
+Device(C097) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 97, 0xFD, 2}
+  }) // Domain 97
+}
+
+Device(C098) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 98, 0xFD, 2}
+  }) // Domain 98
+}
+
+Device(C099) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 99, 0xFD, 2}
+  }) // Domain 99
+}
+
+Device(C100) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 100, 0xFD, 2}
+  }) // Domain 100
+}
+
+Device(C101) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 101, 0xFD, 2}
+  }) // Domain 101
+}
+
+Device(C102) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 102, 0xFD, 2}
+  }) // Domain 102
+}
+
+Device(C103) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 103, 0xFD, 2}
+  }) // Domain 103
+}
+
+Device(C104) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 104, 0xFD, 2}
+  }) // Domain 104
+}
+
+Device(C105) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 105, 0xFD, 2}
+  }) // Domain 105
+}
+
+Device(C106) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 106, 0xFD, 2}
+  }) // Domain 106
+}
+
+Device(C107) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 107, 0xFD, 2}
+  }) // Domain 107
+}
+
+Device(C108) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 108, 0xFD, 2}
+  }) // Domain 108
+}
+
+Device(C109) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 109, 0xFD, 2}
+  }) // Domain 109
+}
+
+Device(C110) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 110, 0xFD, 2}
+  }) // Domain 110
+}
+
+Device(C111) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 111, 0xFD, 2}
+  }) // Domain 111
+}
+
+Device(C112) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 112, 0xFD, 2}
+  }) // Domain 112
+}
+
+Device(C113) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 113, 0xFD, 2}
+  }) // Domain 113
+}
+
+Device(C114) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 114, 0xFD, 2}
+  }) // Domain 114
+}
+
+Device(C115) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 115, 0xFD, 2}
+  }) // Domain 115
+}
+
+Device(C116) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 116, 0xFD, 2}
+  }) // Domain 116
+}
+
+Device(C117) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 117, 0xFD, 2}
+  }) // Domain 117
+}
+
+Device(C118) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 118, 0xFD, 2}
+  }) // Domain 118
+}
+
+Device(C119) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 119, 0xFD, 2}
+  }) // Domain 119
+}
+
+Device(C120) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 120, 0xFD, 2}
+  }) // Domain 120
+}
+
+Device(C121) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 121, 0xFD, 2}
+  }) // Domain 121
+}
+
+Device(C122) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 122, 0xFD, 2}
+  }) // Domain 122
+}
+
+Device(C123) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 123, 0xFD, 2}
+  }) // Domain 123
+}
+
+Device(C124) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 124, 0xFD, 2}
+  }) // Domain 124
+}
+
+Device(C125) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 125, 0xFD, 2}
+  }) // Domain 125
+}
+
+Device(C126) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 126, 0xFD, 2}
+  }) // Domain 126
+}
+
+Device(C127) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x3f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 127, 0xFD, 2}
+  }) // Domain 127
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
new file mode 100755
index 000000000000..b3cc7a1b00e4
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
@@ -0,0 +1,5639 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(C128) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 128, 0xFD, 2}
+  }) // Domain 128
+}
+
+Device(C129) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 1219, 0xFD, 2}
+  }) // Domain 129
+}
+
+Device(C130) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 130, 0xFD, 2}
+  }) // Domain 130
+}
+
+Device(C131) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 131, 0xFD, 2}
+  }) // Domain 131
+}
+
+Device(C132) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 132, 0xFD, 2}
+  }) // Domain 132
+}
+
+Device(C133) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 133, 0xFD, 2}
+  }) // Domain 133
+}
+
+Device(C134) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 134, 0xFD, 2}
+  }) // Domain 134
+}
+
+Device(C135) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 135, 0xFD, 2}
+  }) // Domain 135
+}
+
+Device(C136) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 136, 0xFD, 2}
+  }) // Domain 136
+}
+
+Device(C137) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 137, 0xFD, 2}
+  }) // Domain 137
+}
+
+Device(C138) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 138, 0xFD, 2}
+  }) // Domain 138
+}
+
+Device(C139) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 139, 0xFD, 2}
+  }) // Domain 139
+}
+
+Device(C140) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 140, 0xFD, 2}
+  }) // Domain 140
+}
+
+Device(C141) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 141, 0xFD, 2}
+  }) // Domain 141
+}
+
+Device(C142) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 142, 0xFD, 2}
+  }) // Domain 142
+}
+
+Device(C143) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 143, 0xFD, 2}
+  }) // Domain 143
+}
+
+Device(C144) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 144, 0xFD, 2}
+  }) // Domain 144
+}
+
+Device(C145) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 145, 0xFD, 2}
+  }) // Domain 145
+}
+
+Device(C146) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 146, 0xFD, 2}
+  }) // Domain 146
+}
+
+Device(C147) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 147, 0xFD, 2}
+  }) // Domain 147
+}
+
+Device(C148) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 148, 0xFD, 2}
+  }) // Domain 148
+}
+
+Device(C149) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 149, 0xFD, 2}
+  }) // Domain 149
+}
+
+Device(C150) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 150, 0xFD, 2}
+  }) // Domain 150
+}
+
+Device(C151) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 151, 0xFD, 2}
+  }) // Domain 151
+}
+
+Device(C152) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 152, 0xFD, 2}
+  }) // Domain 152
+}
+
+Device(C153) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 153, 0xFD, 2}
+  }) // Domain 153
+}
+
+Device(C154) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 154, 0xFD, 2}
+  }) // Domain 154
+}
+
+Device(C155) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 155, 0xFD, 2}
+  }) // Domain 155
+}
+
+Device(C156) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 156, 0xFD, 2}
+  }) // Domain 156
+}
+
+Device(C157) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 157, 0xFD, 2}
+  }) // Domain 157
+}
+
+Device(C158) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 158, 0xFD, 2}
+  }) // Domain 158
+}
+
+Device(C159) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x10f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 159, 0xFD, 2}
+  }) // Domain 159
+}
+
+Device(C160) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 160, 0xFD, 2}
+  }) // Domain 160
+}
+
+Device(C161) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 161, 0xFD, 2}
+  }) // Domain 161
+}
+
+Device(C162) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 162, 0xFD, 2}
+  }) // Domain 162
+}
+
+Device(C163) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 163, 0xFD, 2}
+  }) // Domain 163
+}
+
+Device(C164) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 164, 0xFD, 2}
+  }) // Domain 164
+}
+
+Device(C165) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 165, 0xFD, 2}
+  }) // Domain 165
+}
+
+Device(C166) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 166, 0xFD, 2}
+  }) // Domain 166
+}
+
+Device(C167) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 167, 0xFD, 2}
+  }) // Domain 167
+}
+
+Device(C168) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 168, 0xFD, 2}
+  }) // Domain 168
+}
+
+Device(C169) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 169, 0xFD, 2}
+  }) // Domain 169
+}
+
+Device(C170) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 170, 0xFD, 2}
+  }) // Domain 170
+}
+
+Device(C171) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 171, 0xFD, 2}
+  }) // Domain 171
+}
+
+Device(C172) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 172, 0xFD, 2}
+  }) // Domain 172
+}
+
+Device(C173) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 173, 0xFD, 2}
+  }) // Domain 173
+}
+
+Device(C174) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 174, 0xFD, 2}
+  }) // Domain 174
+}
+
+Device(C175) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 175, 0xFD, 2}
+  }) // Domain 175
+}
+
+Device(C176) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 176, 0xFD, 2}
+  }) // Domain 176
+}
+
+Device(C177) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 177, 0xFD, 2}
+  }) // Domain 177
+}
+
+Device(C178) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 178, 0xFD, 2}
+  }) // Domain 178
+}
+
+Device(C179) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 179, 0xFD, 2}
+  }) // Domain 179
+}
+
+Device(C180) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 180, 0xFD, 2}
+  }) // Domain 180
+}
+
+Device(C181) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 181, 0xFD, 2}
+  }) // Domain 181
+}
+
+Device(C182) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 182, 0xFD, 2}
+  }) // Domain 182
+}
+
+Device(C183) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 183, 0xFD, 2}
+  }) // Domain 183
+}
+
+Device(C184) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 184, 0xFD, 2}
+  }) // Domain 184
+}
+
+Device(C185) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 185, 0xFD, 2}
+  }) // Domain 185
+}
+
+Device(C186) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 186, 0xFD, 2}
+  }) // Domain 186
+}
+
+Device(C187) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 187, 0xFD, 2}
+  }) // Domain 187
+}
+
+Device(C188) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 188, 0xFD, 2}
+  }) // Domain 188
+}
+
+Device(C189) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 189, 0xFD, 2}
+  }) // Domain 189
+}
+
+Device(C190) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 190, 0xFD, 2}
+  }) // Domain 190
+}
+
+Device(C191) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x11f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 191, 0xFD, 2}
+  }) // Domain 191
+}
+
+Device(C192) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 192, 0xFD, 2}
+  }) // Domain 192
+}
+
+Device(C193) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 193, 0xFD, 2}
+  }) // Domain 193
+}
+
+Device(C194) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 194, 0xFD, 2}
+  }) // Domain 194
+}
+
+Device(C195) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 195, 0xFD, 2}
+  }) // Domain 195
+}
+
+Device(C196) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 196, 0xFD, 2}
+  }) // Domain 196
+}
+
+Device(C197) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 197, 0xFD, 2}
+  }) // Domain 197
+}
+
+Device(C198) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 198, 0xFD, 2}
+  }) // Domain 198
+}
+
+Device(C199) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 199, 0xFD, 2}
+  }) // Domain 199
+}
+
+Device(C200) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 200, 0xFD, 2}
+  }) // Domain 200
+}
+
+Device(C201) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 201, 0xFD, 2}
+  }) // Domain 201
+}
+
+Device(C202) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 202, 0xFD, 2}
+  }) // Domain 202
+}
+
+Device(C203) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 203, 0xFD, 2}
+  }) // Domain 203
+}
+
+Device(C204) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 204, 0xFD, 2}
+  }) // Domain 204
+}
+
+Device(C205) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 205, 0xFD, 2}
+  }) // Domain 205
+}
+
+Device(C206) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 206, 0xFD, 2}
+  }) // Domain 206
+}
+
+Device(C207) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 207, 0xFD, 2}
+  }) // Domain 207
+}
+
+Device(C208) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 208, 0xFD, 2}
+  }) // Domain 208
+}
+
+Device(C209) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 209, 0xFD, 2}
+  }) // Domain 209
+}
+
+Device(C210) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 210, 0xFD, 2}
+  }) // Domain 210
+}
+
+Device(C211) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 211, 0xFD, 2}
+  }) // Domain 211
+}
+
+Device(C212) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 212, 0xFD, 2}
+  }) // Domain 212
+}
+
+Device(C213) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 213, 0xFD, 2}
+  }) // Domain 213
+}
+
+Device(C214) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 214, 0xFD, 2}
+  }) // Domain 214
+}
+
+Device(C215) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 215, 0xFD, 2}
+  }) // Domain 215
+}
+
+Device(C216) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 216, 0xFD, 2}
+  }) // Domain 216
+}
+
+Device(C217) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 217, 0xFD, 2}
+  }) // Domain 217
+}
+
+Device(C218) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 218, 0xFD, 2}
+  }) // Domain 218
+}
+
+Device(C219) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 219, 0xFD, 2}
+  }) // Domain 219
+}
+
+Device(C220) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 220, 0xFD, 2}
+  }) // Domain 220
+}
+
+Device(C221) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 221, 0xFD, 2}
+  }) // Domain 221
+}
+
+Device(C222) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 222, 0xFD, 2}
+  }) // Domain 222
+}
+
+Device(C223) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x12f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 17)},         // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 17)},         // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 17)},         // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 17)},         // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 17)},         // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 17)},         // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 17)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 17)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 17)},         // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 17)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 17)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 223, 0xFD, 2}
+  }) // Domain 223
+}
+
+Device(C224) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13000)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 224, 0xFD, 2}
+  }) // Domain 224
+}
+
+Device(C225) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13001)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 225, 0xFD, 2}
+  }) // Domain 225
+}
+
+Device(C226) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13100)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 226, 0xFD, 2}
+  }) // Domain 226
+}
+
+Device(C227) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13101)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 227, 0xFD, 2}
+  }) // Domain 227
+}
+
+Device(C228) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13200)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 228, 0xFD, 2}
+  }) // Domain 228
+}
+
+Device(C229) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13201)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 229, 0xFD, 2}
+  }) // Domain 229
+}
+
+Device(C230) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13300)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 230, 0xFD, 2}
+  }) // Domain 230
+}
+
+Device(C231) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13301)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 231, 0xFD, 2}
+  }) // Domain 231
+}
+
+Device(C232) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13400)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 232, 0xFD, 2}
+  }) // Domain 232
+}
+
+Device(C233) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13401)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 233, 0xFD, 2}
+  }) // Domain 233
+}
+
+Device(C234) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13500)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 234, 0xFD, 2}
+  }) // Domain 234
+}
+
+Device(C235) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13501)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 235, 0xFD, 2}
+  }) // Domain 235
+}
+
+Device(C236) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13600)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 236, 0xFD, 2}
+  }) // Domain 236
+}
+
+Device(C237) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13601)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 237, 0xFD, 2}
+  }) // Domain 237
+}
+
+Device(C238) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13700)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 238, 0xFD, 2}
+  }) // Domain 238
+}
+
+Device(C239) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13701)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 239, 0xFD, 2}
+  }) // Domain 239
+}
+
+Device(C240) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13800)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 240, 0xFD, 2}
+  }) // Domain 240
+}
+
+Device(C241) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13801)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 241, 0xFD, 2}
+  }) // Domain 241
+}
+
+Device(C242) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13900)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 242, 0xFD, 2}
+  }) // Domain 242
+}
+
+Device(C243) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13901)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 243, 0xFD, 2}
+  }) // Domain 243
+}
+
+Device(C244) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13a00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 244, 0xFD, 2}
+  }) // Domain 244
+}
+
+Device(C245) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13a01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 245, 0xFD, 2}
+  }) // Domain 245
+}
+
+Device(C246) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13b00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 246, 0xFD, 2}
+  }) // Domain 246
+}
+
+Device(C247) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13b01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 247, 0xFD, 2}
+  }) // Domain 247
+}
+
+Device(C248) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13c00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 248, 0xFD, 2}
+  }) // Domain 248
+}
+
+Device(C249) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13c01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 249, 0xFD, 2}
+  }) // Domain 249
+}
+
+Device(C250) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13d00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 250, 0xFD, 2}
+  }) // Domain 250
+}
+
+Device(C251) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13d01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 251, 0xFD, 2}
+  }) // Domain 251
+}
+
+Device(C252) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13e00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 252, 0xFD, 2}
+  }) // Domain 252
+}
+
+Device(C253) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13e01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 253, 0xFD, 2}
+  }) // Domain 253
+}
+
+Device(C254) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13f00)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package() {
+    Package() {5, 0, 254, 0xFD, 2}
+  }) // Domain 254
+}
+
+Device(C255) {
+  Name(_HID, "ACPI0007")
+  Name(_UID, 0x13f01)
+
+  Method (_LPI, 0, NotSerialized) {
+    return(PLPI)
+  }
+
+  Name(PCPC, Package() {
+    23,                                                         // NumEntries
+    3,                                                          // Revision
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
+    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
+    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
+    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
+  })
+  If (LEqual(CPCE, 0x1)) {
+    Method (_CPC, 0, NotSerialized) {
+      return(PCPC)
+    }
+  }
+  //Performance State dependency
+  Name(_PSD, Package(){
+    Package() {5, 0, 255, 0xFD, 2}
+  }) // Domain 255
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
new file mode 100755
index 000000000000..00c09340b957
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
@@ -0,0 +1,127 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Name (CPCE, 1)                       // CPPC Enable
+Name (LPIE, 0)                       // LPI Enable
+
+Method (_OSC, 4, Serialized) {         // _OSC: Operating System Capabilities
+  CreateDWordField (Arg3, 0x00, STS0)
+  CreateDWordField (Arg3, 0x04, CAP0)
+  If (LEqual(Arg0, ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48")) /* Platform-wide Capabilities */) {
+    If (LNotEqual(Arg1, One)) {
+      And(STS0, 0xFFFFFFE0, STS0)
+      Or(STS0, 0x0A, STS0)          // Unrecognized Revision, OSC failure
+    } Else {
+      If (LEqual(And(CAP0, 0x100), 0x100)) {
+        And(CAP0, 0xFFFFFEFF, CAP0) // No support for OS Initiated LPI
+        And(STS0, 0xFFFFFFE0, STS0)
+        Or(STS0, 0x12, STS0)
+      }
+      If (LEqual(LPIE, 0x1)) {
+        Or(CAP0, 0x80, CAP0)        // Support for LPI
+      } Else {
+        And(CAP0, 0xFFFFFF7F, CAP0) // No support for LPI
+      }
+      If (LEqual(CPCE, 0x1)) {
+        Or(CAP0, 0x40, CAP0)        // Support for CPPCv2
+      } Else {
+        And(CAP0, 0xFFFFFFBF, CAP0) // No support for CPPCv2
+      }
+    }
+  } Else {
+    And(STS0, 0xFFFFFFE0, STS0)
+    Or(STS0, 0x06, STS0)            // Unrecognized Revision, Unrecognized UUID
+  }
+  Return (Arg3)
+}
+
+Name(PLPI, Package() {
+  0,                     // Version
+  1,                     // Level Index
+  2,                     // Count
+  // WFI for CPU (NS-WFI)
+  Package() {
+    1,                   // Min residency (uS)
+    1,                   // Wake latency (uS)
+    1,                   // Flags
+    0,                   // Arch Context Flags
+    100,                 // Residency Counter Frequency
+    0,                   // No parent state
+    ResourceTemplate () {
+      // Register Entry method
+      Register (FFixedHW,
+        0x20,            // Bit Width
+        0x00,            // Bit Offset
+        0xFFFFFFFF,      // Address
+        0x03,            // Access Size
+      )
+    },
+    ResourceTemplate() { // Null Residency Counter
+      Register (SystemMemory, 0, 0, 0, 0)
+    },
+    ResourceTemplate() { // Null Usage Counter
+      Register (SystemMemory, 0, 0, 0, 0)
+    },
+    "Standby",
+  },
+  // Retention state for CPU (S-WFI)
+  Package() {
+    2,                   // Min residency (uS)
+    2,                   // Wake latency (uS)
+    1,                   // Flags
+    0,                   // Arch Context Flags
+    100,                 // Residency Counter Frequency
+    1,                   // Parent node can be in Standby states
+    ResourceTemplate () {
+      // Register Entry method
+      Register (FFixedHW,
+        0x20,            // Bit Width
+        0x00,            // Bit Offset
+        0x00000001,      // Address
+        0x03,            // Access Size
+      )
+    },
+    ResourceTemplate() { // Null Residency Counter
+      Register (SystemMemory, 0, 0, 0, 0)
+    },
+    ResourceTemplate() { // Null Usage Counter
+      Register (SystemMemory, 0, 0, 0, 0)
+    },
+    "Standby_ATF"
+  },
+})
+
+Device (SYST) {            // System state
+  Name(_HID, "ACPI0010")
+  Name(_UID, 1)
+  Name (_LPI, Package() {
+    0,                     // Version
+    0,                     // Level Index
+    1,                     // Count
+    // Retention state for Cluster
+    Package() {
+      100,               // Min residency (uS)
+      100,               // Wake latency (uS)
+      1,                   // Flags
+      0,                   // Arch Context Flags
+      100,                 // Residency Counter Frequency
+      0,                   // No Parent State
+      0x02000100,          // Integer Entry method
+      ResourceTemplate() { // Null Residency Counter
+        Register (SystemMemory, 0, 0, 0, 0)
+      },
+      ResourceTemplate() { // Null Usage Counter
+        Register (SystemMemory, 0, 0, 0, 0)
+      },
+      "Standby"
+    },
+  })
+
+  Include ("CPU-S0.asi")
+  Include ("CPU-S1.asi")
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
new file mode 100755
index 000000000000..b9e2da79b5ef
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
@@ -0,0 +1,575 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
+  //
+  // Board Model
+  Name(\BDMD, "Jade Board")
+  Name(TPMF, 0)  // TPM presence
+  Name(AERF, 0)  // PCIe AER Firmware-First
+  Scope(\_SB) {
+
+    Include ("CPU.asi")
+    Include ("PMU.asi")
+
+    //
+    // Hardware Monitor
+    Device(HM00) {
+      Name(_HID, "APMC0D29")
+      Name(_UID, "HWM0")
+      Name(_DDN, "HWM0")
+      Name(_CCA, ONE)
+      Name(_STR, Unicode("Hardware Monitor Device"))
+      Method(_STA, 0, NotSerialized) {
+        return (0xF)
+      }
+      Name (_DSD, Package () {
+        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+        Package() {
+          Package() {"pcc-channel", 14}
+        }
+      })
+    }
+
+    //
+    // Hardware Monitor
+    Device(HM01) {
+      Name(_HID, "APMC0D29")
+      Name(_UID, "HWM1")
+      Name(_DDN, "HWM1")
+      Name(_CCA, ONE)
+      Name(_STR, Unicode("Hardware Monitor Device"))
+      Method(_STA, 0, NotSerialized) {
+        return (0xF)
+      }
+      Name (_DSD, Package () {
+        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+        Package() {
+          Package() {"pcc-channel", 29}
+        }
+      })
+    }
+
+    //
+    // Hardware Monitor
+    Device(HM02) {
+      Name(_HID, "AMPC0005")
+      Name(_UID, "HWM2")
+      Name(_DDN, "HWM2")
+      Name(_CCA, ONE)
+      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
+      Method(_STA, 0, NotSerialized) {
+        return (0xF)
+      }
+      Name(_CRS, ResourceTemplate() {
+        QWordMemory (
+          ResourceProducer,     // ResourceUsage
+          PosDecode,            // Decode
+          MinFixed,             // IsMinFixed
+          MaxFixed,             // IsMaxFixed
+          Cacheable,            // Cacheable
+          ReadWrite,            // ReadAndWrite
+          0x0000000000000000,   // AddressGranularity - GRA
+          0x0000000088900000,   // AddressMinimum - MIN
+          0x000000008891FFFF,   // AddressMaximum - MAX
+          0x0000000000000000,   // AddressTranslation - TRA
+          0x0000000000020000    // RangeLength - LEN
+        )
+      })
+    }
+
+    //
+    // Hardware Monitor
+    Device(HM03) {
+      Name(_HID, "AMPC0005")
+      Name(_UID, "HWM3")
+      Name(_DDN, "HWM3")
+      Name(_CCA, ONE)
+      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
+      Method(_STA, 0, NotSerialized) {
+        return (0xF)
+      }
+      Name(_CRS, ResourceTemplate() {
+        QWordMemory (
+          ResourceProducer,     // ResourceUsage
+          PosDecode,            // Decode
+          MinFixed,             // IsMinFixed
+          MaxFixed,             // IsMaxFixed
+          Cacheable,            // Cacheable
+          ReadWrite,            // ReadAndWrite
+          0x0000000000000000,   // AddressGranularity - GRA
+          0x0000000088920000,   // AddressMinimum - MIN
+          0x000000008893FFFF,   // AddressMaximum - MAX
+          0x0000000000000000,   // AddressTranslation - TRA
+          0x0000000000020000    // RangeLength - LEN
+        )
+      })
+    }
+
+    //
+    // DesignWare I2C on AHBC bus
+    Device(I2C4) {
+      Name(_HID, "APMC0D0F")
+      Name(_UID, 4)
+      Name(_STR, Unicode("Altra I2C Device"))
+      Method(_STA, 0, NotSerialized) {
+        return (0x0f)
+      }
+      Name(_CCA, ONE)
+      Name(_CRS, ResourceTemplate() {
+        QWordMemory (
+          ResourceProducer,     // ResourceUsage
+          PosDecode,            // Decode
+          MinFixed,             // IsMinFixed
+          MaxFixed,             // IsMaxFixed
+          NonCacheable,         // Cacheable
+          ReadWrite,            // ReadAndWrite
+          0x0000000000000000,   // AddressGranularity - GRA
+          0x00001000026B0000,   // AddressMinimum - MIN
+          0x00001000026BFFFF,   // AddressMaximum - MAX
+          0x0000000000000000,   // AddressTranslation - TRA
+          0x0000000000010000    // RangeLength - LEN
+        )
+        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 105 }
+      })
+      Device (IPI) {
+        Name(_HID, "AMPC0004")
+        Name(_CID, "IPI0001")
+        Name(_STR, Unicode("IPMI_SSIF"))
+        Name(_UID, 0)
+        Name(_CCA, ONE)
+        Method(_STA, 0, NotSerialized) {
+          Return (0x0f)
+        }
+        Method(_IFT) {
+          Return(0x04) // IPMI SSIF
+        }
+        Method(_ADR) {
+          Return(0x10) // SSIF slave address
+        }
+        Method(_SRV) {
+          Return(0x0200) // IPMI Specification Revision
+        }
+        Name(_CRS, ResourceTemplate ()
+        {
+          I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80,
+          AddressingMode7Bit, "\\_SB.I2C4",
+          0x00, ResourceConsumer,,
+          )
+        })
+      }
+      Name(SSCN, Package() { 0x3E2, 0x47D, 0 })
+      Name(FMCN, Package() { 0xA4, 0x13F, 0 })
+    }
+
+    //
+    // Report APEI Errors to GHES via SCI notification.
+    // SCI notification requires one GED and one HED Device
+    //     GED = Generic Event Device (ACPI0013)
+    //     HED = Hardware Error Device (PNP0C33)
+    //
+    Device(GED0) {
+        Name(_HID, "ACPI0013")
+        Name(_UID, Zero)
+        Method(_STA) {
+          Return (0xF)
+        }
+        Name(_CRS, ResourceTemplate () {
+          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 84 } // GHES
+        })
+        Method(_EVT, 1, Serialized) {
+          Switch (ToInteger(Arg0)) {
+            Case (84) { // GHES interrupt
+              Notify (HED0, 0x80)
+            }
+          }
+        }
+    }
+
+    // Shutdown button using GED.
+    Device(GED1) {
+        Name(_HID, "ACPI0013")
+        Name(_CID, "ACPI0013")
+        Name(_UID, One)
+        Method(_STA) {
+          Return (0xF)
+        }
+        Name(_CRS, ResourceTemplate () {
+          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 327 }
+        })
+        OperationRegion(PDDR, SystemMemory, 0x1000027B0004, 4)
+        Field(PDDR, DWordAcc, NoLock, Preserve) {
+          STDI, 8
+        }
+
+        OperationRegion(INTE, SystemMemory, 0x1000027B0030, 4)
+        Field(INTE, DWordAcc, NoLock, Preserve) {
+          STDE, 8
+        }
+
+        OperationRegion(INTT, SystemMemory, 0x1000027B0034, 4)
+        Field(INTT, DWordAcc, NoLock, Preserve) {
+          TYPE, 8
+        }
+
+        OperationRegion(INTP, SystemMemory, 0x1000027B0038, 4)
+        Field(INTP, DWordAcc, NoLock, Preserve) {
+          POLA, 8
+        }
+
+        OperationRegion(INTS, SystemMemory, 0x1000027B003c, 4)
+        Field(INTS, DWordAcc, NoLock, Preserve) {
+          STDS, 8
+        }
+
+        OperationRegion(INTC, SystemMemory, 0x1000027B0040, 4)
+        Field(INTC, DWordAcc, NoLock, Preserve) {
+          SINT, 8
+        }
+
+        OperationRegion(INTM, SystemMemory, 0x1000027B0044, 4)
+        Field(INTM, DWordAcc, NoLock, Preserve) {
+          MASK, 8
+        }
+
+        Method(_INI, 0, NotSerialized) {
+          // Set level type, low active (shutdown)
+          Store (0x00, TYPE)
+          Store (0x00, POLA)
+          // Set Input type (shutdown)
+          Store (0x00, STDI)
+          // Enable interrupt (shutdown)
+          Store (0x80, STDE)
+          // Unmask the interrupt.
+          Store (0x00, MASK)
+        }
+        Method(_EVT, 1, Serialized) {
+          Switch (ToInteger(Arg0)) {
+            Case (327) {
+              if (And (STDS, 0x80)) {
+                //Clear the interrupt.
+                Store (0x80, SINT)
+                // Notify OSPM the power button is pressed
+                Notify (\_SB.PWRB, 0x80)
+              }
+            }
+          }
+        }
+    }
+
+    // Power button device description
+    Device(PWRB) {
+        Name(_HID, EISAID("PNP0C0C"))
+        Name(_ADR, 0)
+        Name(_UID, 0)
+        Name(_CCA, ONE)
+        Method(_STA, 0, Notserialized) {
+            Return (0x0b)
+        }
+    }
+
+    //
+    // UART0 PL011
+    Device(URT0) {
+      Name(_HID, "ARMH0011")
+      Name(_UID, 0)
+      Name(_CCA, ONE)
+      Method(_STA, 0, NotSerialized) {
+        return (0x0f)
+      }
+      Name(_CRS, ResourceTemplate() {
+        QWordMemory (
+          ResourceProducer,     // ResourceUsage
+          PosDecode,            // Decode
+          MinFixed,             // IsMinFixed
+          MaxFixed,             // IsMaxFixed
+          NonCacheable,         // Cacheable
+          ReadWrite,            // ReadAndWrite
+          0x0000000000000000,   // AddressGranularity - GRA
+          0x0000100002600000,   // AddressMinimum - MIN
+          0x0000100002600FFF,   // AddressMaximum - MAX
+          0x0000000000000000,   // AddressTranslation - TRA
+          0x0000000000001000    // RangeLength - LEN
+        )
+        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 98 }
+      })
+    } // UART0
+
+    //
+    // UART2 PL011
+    Device(URT2) {
+      Name(_HID, "ARMH0011")
+      Name(_UID, 1)
+      Name(_CCA, ONE)
+      Method(_STA, 0, NotSerialized) {
+        return (0x0f)
+      }
+      Name(_CRS, ResourceTemplate() {
+        QWordMemory (
+          ResourceProducer,     // ResourceUsage
+          PosDecode,            // Decode
+          MinFixed,             // IsMinFixed
+          MaxFixed,             // IsMaxFixed
+          NonCacheable,         // Cacheable
+          ReadWrite,            // ReadAndWrite
+          0x0000000000000000,   // AddressGranularity - GRA
+          0x0000100002620000,   // AddressMinimum - MIN
+          0x0000100002620FFF,   // AddressMaximum - MAX
+          0x0000000000000000,   // AddressTranslation - TRA
+          0x0000000000001000    // RangeLength - LEN
+        )
+        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 100 }
+      })
+    } // UART1
+
+    Device(HED0)
+    {
+        Name(_HID, EISAID("PNP0C33"))
+        Name(_UID, Zero)
+    }
+
+    Device(NVDR) {
+      Name(_HID, "ACPI0012")
+      Method(_STA, 0, NotSerialized) {
+        return (0xf)
+      }
+      Method (_DSM, 0x4, Serialized) {
+        // Not support any functions for now
+        Return (Buffer() {0})
+      }
+      Device (NVD1) {
+        Name(_ADR, 0x0330)
+        Name(SMRT, Buffer(13) {0})
+        CreateDWordField(SMRT, 0, BSTA)
+        CreateWordField(SMRT, 4, BHTH)
+        CreateWordField(SMRT, 6, BTMP)
+        CreateByteField(SMRT, 8, BETH)
+        CreateByteField(SMRT, 9, BWTH)
+        CreateByteField(SMRT, 10, BNLF)
+        OperationRegion(BUF1, SystemMemory, 0x88980000, 16)
+        Field (BUF1, DWordAcc, NoLock, Preserve) {
+          STAT, 32, //Status
+          HLTH, 16, //Module Health
+          CTMP, 16, //Module Current Status
+          ETHS, 8, //Error Threshold Status
+          WTHS, 8, //Warning Threshold Status
+          NVLF, 8, //NVM Lifetime
+          ,     40 //Reserve
+        }
+        Method (_DSM, 0x4, Serialized) {
+          //Accept only MSF Family type NVDIMM DSM functions
+          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
+            //Handle Func 0 query implemented commands
+            If(LEqual(Arg2, 0)) {
+              //Check revision and returned proper implemented commands
+              //Support only health check for now
+              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
+            }
+            //Handle MSF DSM Func 11 Get Smart and Health Info
+            If(LEqual(Arg2, 11)) {
+              Store(\_SB.NVDR.NVD1.STAT, BSTA)
+              Store(\_SB.NVDR.NVD1.HLTH, BHTH)
+              Store(\_SB.NVDR.NVD1.CTMP, BTMP)
+              Store(\_SB.NVDR.NVD1.ETHS, BETH)
+              Store(\_SB.NVDR.NVD1.WTHS, BWTH)
+              Store(\_SB.NVDR.NVD1.NVLF, BNLF)
+              Return (SMRT)
+            }
+          }
+          Return (Buffer() {0})
+        }
+        Method(_STA, 0, NotSerialized) {
+          return (0xf)
+        }
+      }
+      Device (NVD2) {
+        Name(_ADR, 0x0770)
+        Name(SMRT, Buffer(13) {0})
+        CreateDWordField(SMRT, 0, BSTA)
+        CreateWordField(SMRT, 4, BHTH)
+        CreateWordField(SMRT, 6, BTMP)
+        CreateByteField(SMRT, 8, BETH)
+        CreateByteField(SMRT, 9, BWTH)
+        CreateByteField(SMRT, 10, BNLF)
+        OperationRegion(BUF1, SystemMemory, 0x88988000, 16)
+        Field (BUF1, DWordAcc, NoLock, Preserve) {
+          STAT, 32, //Status
+          HLTH, 16, //Module Health
+          CTMP, 16, //Module Current Status
+          ETHS, 8, //Error Threshold Status
+          WTHS, 8, //Warning Threshold Status
+          NVLF, 8, //NVM Lifetime
+          ,     40 //Reserve
+        }
+        Method (_DSM, 0x4, Serialized) {
+          //Accept only MSF Family type NVDIMM DSM functions
+          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
+            //Handle Func 0 query implemented commands
+            If(LEqual(Arg2, 0)) {
+              //Check revision and returned proper implemented commands
+              //Support only health check for now
+              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
+            }
+            //Handle MSF DSM Func 11 Get Smart and Health Info
+            If(LEqual(Arg2, 11)) {
+              Store(\_SB.NVDR.NVD2.STAT, BSTA)
+              Store(\_SB.NVDR.NVD2.HLTH, BHTH)
+              Store(\_SB.NVDR.NVD2.CTMP, BTMP)
+              Store(\_SB.NVDR.NVD2.ETHS, BETH)
+              Store(\_SB.NVDR.NVD2.WTHS, BWTH)
+              Store(\_SB.NVDR.NVD2.NVLF, BNLF)
+              Return (SMRT)
+            }
+          }
+          Return (Buffer() {0})
+        }
+        Method(_STA, 0, NotSerialized) {
+          return (0xf)
+        }
+      }
+      Device (NVD3) {
+        Name(_ADR, 0x1330)
+        Name(SMRT, Buffer(13) {0})
+        CreateDWordField(SMRT, 0, BSTA)
+        CreateWordField(SMRT, 4, BHTH)
+        CreateWordField(SMRT, 6, BTMP)
+        CreateByteField(SMRT, 8, BETH)
+        CreateByteField(SMRT, 9, BWTH)
+        CreateByteField(SMRT, 10, BNLF)
+        OperationRegion(BUF1, SystemMemory, 0xC0080000, 16)
+        Field (BUF1, DWordAcc, NoLock, Preserve) {
+          STAT, 32, //Status
+          HLTH, 16, //Module Health
+          CTMP, 16, //Module Current Status
+          ETHS, 8, //Error Threshold Status
+          WTHS, 8, //Warning Threshold Status
+          NVLF, 8, //NVM Lifetime
+          ,     40 //Reserve
+        }
+        Method (_DSM, 0x4, Serialized) {
+          //Accept only MSF Family type NVDIMM DSM functions
+          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
+            //Handle Func 0 query implemented commands
+            If(LEqual(Arg2, 0)) {
+              //Check revision and returned proper implemented commands
+              //Support only health check for now
+              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
+            }
+            //Handle MSF DSM Func 11 Get Smart and Health Info
+            If(LEqual(Arg2, 11)) {
+              Store(\_SB.NVDR.NVD3.STAT, BSTA)
+              Store(\_SB.NVDR.NVD3.HLTH, BHTH)
+              Store(\_SB.NVDR.NVD3.CTMP, BTMP)
+              Store(\_SB.NVDR.NVD3.ETHS, BETH)
+              Store(\_SB.NVDR.NVD3.WTHS, BWTH)
+              Store(\_SB.NVDR.NVD3.NVLF, BNLF)
+              Return (SMRT)
+            }
+          }
+          Return (Buffer() {0})
+        }
+        Method(_STA, 0, NotSerialized) {
+          return (0xf)
+        }
+      }
+      Device (NVD4) {
+        Name(_ADR, 0x1770)
+        Name(SMRT, Buffer(13) {0})
+        CreateDWordField(SMRT, 0, BSTA)
+        CreateWordField(SMRT, 4, BHTH)
+        CreateWordField(SMRT, 6, BTMP)
+        CreateByteField(SMRT, 8, BETH)
+        CreateByteField(SMRT, 9, BWTH)
+        CreateByteField(SMRT, 10, BNLF)
+        OperationRegion(BUF1, SystemMemory, 0xC0088000, 16)
+        Field (BUF1, DWordAcc, NoLock, Preserve) {
+          STAT, 32, //Status
+          HLTH, 16, //Module Health
+          CTMP, 16, //Module Current Status
+          ETHS, 8, //Error Threshold Status
+          WTHS, 8, //Warning Threshold Status
+          NVLF, 8, //NVM Lifetime
+          ,     40 //Reserve
+        }
+        Method (_DSM, 0x4, Serialized) {
+          //Accept only MSF Family type NVDIMM DSM functions
+          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
+            //Handle Func 0 query implemented commands
+            If(LEqual(Arg2, 0)) {
+              //Check revision and returned proper implemented commands
+              //Support only health check for now
+              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
+            }
+            //Handle MSF DSM Func 11 Get Smart and Health Info
+            If(LEqual(Arg2, 11)) {
+              Store(\_SB.NVDR.NVD4.STAT, BSTA)
+              Store(\_SB.NVDR.NVD4.HLTH, BHTH)
+              Store(\_SB.NVDR.NVD4.CTMP, BTMP)
+              Store(\_SB.NVDR.NVD4.ETHS, BETH)
+              Store(\_SB.NVDR.NVD4.WTHS, BWTH)
+              Store(\_SB.NVDR.NVD4.NVLF, BNLF)
+              Return (SMRT)
+            }
+          }
+          Return (Buffer() {0})
+        }
+        Method(_STA, 0, NotSerialized) {
+          return (0xf)
+        }
+      }
+    }
+
+    Device (TPM0) {
+      //
+      // TPM 2.0
+      //
+
+      //
+      // TAG for patching TPM2.0 _HID
+      //
+      Name (_HID, "NNNN0000")
+      Name (_CID, "MSFT0101")
+      Name (_UID, 0)
+
+      Name (CRBB, 0x10000000)
+      Name (CRBL, 0x10000000)
+
+      Name (RBUF, ResourceTemplate () {
+        Memory32Fixed (ReadWrite, 0x88500000, 0x1000, PCRE)
+      })
+
+      Method (_CRS, 0x0, Serialized) {
+        // Declare fields in PCRE
+        CreateDWordField(RBUF, ^PCRE._BAS, BASE)
+        CreateDWordField(RBUF, ^PCRE._LEN, LENG)
+
+        // Store updatable values into them
+        Store(CRBB, BASE)
+        Store(CRBL, LENG)
+
+        Return (RBUF)
+      }
+
+      Method (_STR,0) {
+        Return (Unicode ("TPM 2.0 Device"))
+      }
+
+      Method (_STA, 0) {
+        if (TPMF) {
+          Return (0x0f)  //Enable resources
+        }
+        Return (0x0)
+      }
+    }
+
+    Include ("PCI-S0.Rca01.asi")
+    Include ("PCI-S0.asi")
+    Include ("PCI-S1.asi")
+    Include ("PCI-PDRC.asi")
+  }
+} // DSDT
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
new file mode 100644
index 000000000000..16c00c35e3fe
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
@@ -0,0 +1,217 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+  // Motherboard resource consumption for PCIE resource reservation
+  // as upstream discussion "ACPI namespace details for ARM64"
+  Device (PDRC) {
+    Name (_HID, EISAID("PNP0C02"))
+    Name (_UID, 1)
+    // S0 Start here
+    Name (PDRS, ResourceTemplate() {
+      QWordMemory (              // PCIE0 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00003BFFF0000000,   // AddressMinimum - MIN
+        0x00003BFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE1 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00003FFFF0000000,   // AddressMinimum - MIN
+        0x00003FFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE2 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000023FFF0000000,   // AddressMinimum - MIN
+        0x000023FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE3 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000027FFF0000000,   // AddressMinimum - MIN
+        0x000027FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE4 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00002BFFF0000000,   // AddressMinimum - MIN
+        0x00002BFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE5 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00002FFFF0000000,   // AddressMinimum - MIN
+        0x00002FFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      // S1 Start here
+      QWordMemory (              // PCIE6 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00007BFFF0000000,   // AddressMinimum - MIN
+        0x00007BFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE7 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00007FFFF0000000,   // AddressMinimum - MIN
+        0x00007FFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE8 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000063FFF0000000,   // AddressMinimum - MIN
+        0x000063FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIE9 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000067FFF0000000,   // AddressMinimum - MIN
+        0x000067FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+      QWordMemory (              // PCIEA 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00006BFFF0000000,   // AddressMinimum - MIN
+        0x00006BFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIEB 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00006FFFF0000000,   // AddressMinimum - MIN
+        0x00006FFFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIEC 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000033FFF0000000,   // AddressMinimum - MIN
+        0x000033FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (              // PCIED 256M CFG region for ECAM
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x000037FFF0000000,   // AddressMinimum - MIN
+        0x000037FFFFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+    })
+
+    // Current Resource Settings
+    Method (_CRS, 0, Serialized) {
+      Return (PDRS)
+    }
+  }
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
new file mode 100755
index 000000000000..67e1518ebf88
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
@@ -0,0 +1,681 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+  // PCI0 RCA0
+  Device (PCI0) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 12)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI0")
+    Name (_STR, Unicode("PCIe 0 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 128/129/130/131 respectively. PCI0 RCA0
+      //
+      Package() {0x0001FFFF, 0, 0, 128},
+      Package() {0x0001FFFF, 1, 0, 129},
+      Package() {0x0001FFFF, 2, 0, 130},
+      Package() {0x0001FFFF, 3, 0, 131},
+      Package() {0x0002FFFF, 0, 0, 128},
+      Package() {0x0002FFFF, 1, 0, 129},
+      Package() {0x0002FFFF, 2, 0, 130},
+      Package() {0x0002FFFF, 3, 0, 131},
+      Package() {0x0003FFFF, 0, 0, 128},
+      Package() {0x0003FFFF, 1, 0, 129},
+      Package() {0x0003FFFF, 2, 0, 130},
+      Package() {0x0003FFFF, 3, 0, 131},
+      Package() {0x0004FFFF, 0, 0, 128},
+      Package() {0x0004FFFF, 1, 0, 129},
+      Package() {0x0004FFFF, 2, 0, 130},
+      Package() {0x0004FFFF, 3, 0, 131},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x33FFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000040000000,   // AddressMinimum - MIN
+        0x000000004FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000300000000000,   // AddressMinimum - MIN
+        0x000033FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI0 RCA0
+
+  // PCI1 RCA1
+  Device (PCI1) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 13)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI1")
+    Name (_STR, Unicode("PCIe 1 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 132/133/134/135 respectively. PCI1 RCA1
+      //
+      Package() {0x0001FFFF, 0, 0, 132},
+      Package() {0x0001FFFF, 1, 0, 133},
+      Package() {0x0001FFFF, 2, 0, 134},
+      Package() {0x0001FFFF, 3, 0, 135},
+      Package() {0x0002FFFF, 0, 0, 132},
+      Package() {0x0002FFFF, 1, 0, 133},
+      Package() {0x0002FFFF, 2, 0, 134},
+      Package() {0x0002FFFF, 3, 0, 135},
+      Package() {0x0003FFFF, 0, 0, 132},
+      Package() {0x0003FFFF, 1, 0, 133},
+      Package() {0x0003FFFF, 2, 0, 134},
+      Package() {0x0003FFFF, 3, 0, 135},
+      Package() {0x0004FFFF, 0, 0, 132},
+      Package() {0x0004FFFF, 1, 0, 133},
+      Package() {0x0004FFFF, 2, 0, 134},
+      Package() {0x0004FFFF, 3, 0, 135},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x37FFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000050000000,   // AddressMinimum - MIN
+        0x000000005FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000010000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        Cacheable,            // Cacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000340000000000,   // AddressMinimum - MIN
+        0x000037FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI1 RCA1
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
new file mode 100755
index 000000000000..7c05c6768a0e
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
@@ -0,0 +1,2078 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+  // PCI2 RCA2
+  Device (PCI2) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 1)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI2")
+    Name (_STR, Unicode("PCIe 2 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 136/137/138/139 respectively. PCI2 RCA2
+      //
+      Package() {0x0001FFFF, 0, 0, 136},
+      Package() {0x0001FFFF, 1, 0, 137},
+      Package() {0x0001FFFF, 2, 0, 138},
+      Package() {0x0001FFFF, 3, 0, 139},
+      Package() {0x0002FFFF, 0, 0, 136},
+      Package() {0x0002FFFF, 1, 0, 137},
+      Package() {0x0002FFFF, 2, 0, 138},
+      Package() {0x0002FFFF, 3, 0, 139},
+      Package() {0x0003FFFF, 0, 0, 136},
+      Package() {0x0003FFFF, 1, 0, 137},
+      Package() {0x0003FFFF, 2, 0, 138},
+      Package() {0x0003FFFF, 3, 0, 139},
+      Package() {0x0004FFFF, 0, 0, 136},
+      Package() {0x0004FFFF, 1, 0, 137},
+      Package() {0x0004FFFF, 2, 0, 138},
+      Package() {0x0004FFFF, 3, 0, 139},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x3BFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE80000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000030000000,   // AddressMinimum - MIN
+        0x0000000037FFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000380000000000,   // AddressMinimum - MIN
+        0x00003BFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP, 0) // PCI _OSC Support Field value
+    Name (CTRL, 0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3,0,CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI2 RCA2
+
+  // PCI3 RCA3
+  Device (PCI3) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 0)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI3")
+    Name (_STR, Unicode("PCIe 3 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 140/141/142/143 respectively. PCI3 RCA3
+      //
+      Package() {0x0001FFFF, 0, 0, 140},
+      Package() {0x0001FFFF, 1, 0, 141},
+      Package() {0x0001FFFF, 2, 0, 142},
+      Package() {0x0001FFFF, 3, 0, 143},
+      Package() {0x0002FFFF, 0, 0, 140},
+      Package() {0x0002FFFF, 1, 0, 141},
+      Package() {0x0002FFFF, 2, 0, 142},
+      Package() {0x0002FFFF, 3, 0, 143},
+      Package() {0x0003FFFF, 0, 0, 140},
+      Package() {0x0003FFFF, 1, 0, 141},
+      Package() {0x0003FFFF, 2, 0, 142},
+      Package() {0x0003FFFF, 3, 0, 143},
+      Package() {0x0004FFFF, 0, 0, 140},
+      Package() {0x0004FFFF, 1, 0, 141},
+      Package() {0x0004FFFF, 2, 0, 142},
+      Package() {0x0004FFFF, 3, 0, 143},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x3FFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to Return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE00000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000038000000,   // AddressMinimum - MIN
+        0x000000003FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00003C0000000000,   // AddressMinimum - MIN
+        0x00003FFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP, 0) // PCI _OSC Support Field value
+    Name (CTRL, 0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI3 RCA3
+
+  // PCI4 RCB0
+  Device (PCI4) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 2)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI4")
+    Name (_STR, Unicode("PCIe 4 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 144/145/146/147 respectively. PCI4 RCB0
+      //
+      Package() {0x0001FFFF, 0, 0, 144},
+      Package() {0x0001FFFF, 1, 0, 145},
+      Package() {0x0001FFFF, 2, 0, 146},
+      Package() {0x0001FFFF, 3, 0, 147},
+      Package() {0x0002FFFF, 0, 0, 144},
+      Package() {0x0002FFFF, 1, 0, 145},
+      Package() {0x0002FFFF, 2, 0, 146},
+      Package() {0x0002FFFF, 3, 0, 147},
+      Package() {0x0003FFFF, 0, 0, 144},
+      Package() {0x0003FFFF, 1, 0, 145},
+      Package() {0x0003FFFF, 2, 0, 146},
+      Package() {0x0003FFFF, 3, 0, 147},
+      Package() {0x0004FFFF, 0, 0, 144},
+      Package() {0x0004FFFF, 1, 0, 145},
+      Package() {0x0004FFFF, 2, 0, 146},
+      Package() {0x0004FFFF, 3, 0, 147},
+      Package() {0x0005FFFF, 0, 0, 144},
+      Package() {0x0005FFFF, 1, 0, 145},
+      Package() {0x0005FFFF, 2, 0, 146},
+      Package() {0x0005FFFF, 3, 0, 147},
+      Package() {0x0006FFFF, 0, 0, 144},
+      Package() {0x0006FFFF, 1, 0, 145},
+      Package() {0x0006FFFF, 2, 0, 146},
+      Package() {0x0006FFFF, 3, 0, 147},
+      Package() {0x0007FFFF, 0, 0, 144},
+      Package() {0x0007FFFF, 1, 0, 145},
+      Package() {0x0007FFFF, 2, 0, 146},
+      Package() {0x0007FFFF, 3, 0, 147},
+      Package() {0x0008FFFF, 0, 0, 144},
+      Package() {0x0008FFFF, 1, 0, 145},
+      Package() {0x0008FFFF, 2, 0, 146},
+      Package() {0x0008FFFF, 3, 0, 147},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x23FFF0000000)
+    }
+
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FEC0000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000001000000,   // AddressMinimum - MIN
+        0x0000000007FFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000007000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000200000000000,   // AddressMinimum - MIN
+        0x000023FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2))
+        {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI4 RCB0
+
+  // PCI5 RCB1
+  Device (PCI5) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID,"PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 3)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI5")
+    Name (_STR, Unicode("PCIe 5 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 148/149/150/151 respectively. PCI5 RCB1
+      //
+      Package() {0x0001FFFF, 0, 0, 148},
+      Package() {0x0001FFFF, 1, 0, 149},
+      Package() {0x0001FFFF, 2, 0, 150},
+      Package() {0x0001FFFF, 3, 0, 151},
+      Package() {0x0002FFFF, 0, 0, 148},
+      Package() {0x0002FFFF, 1, 0, 149},
+      Package() {0x0002FFFF, 2, 0, 150},
+      Package() {0x0002FFFF, 3, 0, 151},
+      Package() {0x0003FFFF, 0, 0, 148},
+      Package() {0x0003FFFF, 1, 0, 149},
+      Package() {0x0003FFFF, 2, 0, 150},
+      Package() {0x0003FFFF, 3, 0, 151},
+      Package() {0x0004FFFF, 0, 0, 148},
+      Package() {0x0004FFFF, 1, 0, 149},
+      Package() {0x0004FFFF, 2, 0, 150},
+      Package() {0x0004FFFF, 3, 0, 151},
+      Package() {0x0005FFFF, 0, 0, 148},
+      Package() {0x0005FFFF, 1, 0, 149},
+      Package() {0x0005FFFF, 2, 0, 150},
+      Package() {0x0005FFFF, 3, 0, 151},
+      Package() {0x0006FFFF, 0, 0, 148},
+      Package() {0x0006FFFF, 1, 0, 149},
+      Package() {0x0006FFFF, 2, 0, 150},
+      Package() {0x0006FFFF, 3, 0, 151},
+      Package() {0x0007FFFF, 0, 0, 148},
+      Package() {0x0007FFFF, 1, 0, 149},
+      Package() {0x0007FFFF, 2, 0, 150},
+      Package() {0x0007FFFF, 3, 0, 151},
+      Package() {0x0008FFFF, 0, 0, 148},
+      Package() {0x0008FFFF, 1, 0, 149},
+      Package() {0x0008FFFF, 2, 0, 150},
+      Package() {0x0008FFFF, 3, 0, 151},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x27FFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FF00000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000008000000,   // AddressMinimum - MIN
+        0x000000000FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000240000000000,   // AddressMinimum - MIN
+        0x000027FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP, 0) // PCI _OSC Support Field value
+    Name (CTRL, 0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+            Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+            Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2))
+        {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI5 RCB1
+
+
+  // PCI6 RCB2
+  Device (PCI6) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID,"PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID,"PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 4)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI6")
+    Name (_STR, Unicode("PCIe 6 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 152/153/154/155 respectively. PCI6 RCB2
+      //
+      Package() {0x0001FFFF, 0, 0, 152},
+      Package() {0x0001FFFF, 1, 0, 153},
+      Package() {0x0001FFFF, 2, 0, 154},
+      Package() {0x0001FFFF, 3, 0, 155},
+      Package() {0x0002FFFF, 0, 0, 152},
+      Package() {0x0002FFFF, 1, 0, 153},
+      Package() {0x0002FFFF, 2, 0, 154},
+      Package() {0x0002FFFF, 3, 0, 155},
+      Package() {0x0003FFFF, 0, 0, 152},
+      Package() {0x0003FFFF, 1, 0, 153},
+      Package() {0x0003FFFF, 2, 0, 154},
+      Package() {0x0003FFFF, 3, 0, 155},
+      Package() {0x0004FFFF, 0, 0, 152},
+      Package() {0x0004FFFF, 1, 0, 153},
+      Package() {0x0004FFFF, 2, 0, 154},
+      Package() {0x0004FFFF, 3, 0, 155},
+      Package() {0x0005FFFF, 0, 0, 152},
+      Package() {0x0005FFFF, 1, 0, 153},
+      Package() {0x0005FFFF, 2, 0, 154},
+      Package() {0x0005FFFF, 3, 0, 155},
+      Package() {0x0006FFFF, 0, 0, 152},
+      Package() {0x0006FFFF, 1, 0, 153},
+      Package() {0x0006FFFF, 2, 0, 154},
+      Package() {0x0006FFFF, 3, 0, 155},
+      Package() {0x0007FFFF, 0, 0, 152},
+      Package() {0x0007FFFF, 1, 0, 153},
+      Package() {0x0007FFFF, 2, 0, 154},
+      Package() {0x0007FFFF, 3, 0, 155},
+      Package() {0x0008FFFF, 0, 0, 152},
+      Package() {0x0008FFFF, 1, 0, 153},
+      Package() {0x0008FFFF, 2, 0, 154},
+      Package() {0x0008FFFF, 3, 0, 155},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x2BFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000010000000,   // AddressMinimum - MIN
+        0x0000000017FFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000280000000000,   // AddressMinimum - MIN
+        0x00002BFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3,0,CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3,4,CDW2)
+        CreateDWordField (Arg3,8,CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2,SUPP)
+        Store (CDW3,CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL,0x1E,CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1,One)) {
+          Or (CDW1,0x08,CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3,CTRL)) {
+          Or (CDW1,0x10,CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL,CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1,4,CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI6 RCB2
+
+  // PCI7 RCB3
+  Device (PCI7) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID,"PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID,"PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 5)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCI7")
+    Name (_STR, Unicode("PCIe 7 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 156/157/158/159 respectively. PCI7 RCB3
+      //
+      Package() {0x0001FFFF, 0, 0, 156},
+      Package() {0x0001FFFF, 1, 0, 157},
+      Package() {0x0001FFFF, 2, 0, 158},
+      Package() {0x0001FFFF, 3, 0, 159},
+      Package() {0x0002FFFF, 0, 0, 156},
+      Package() {0x0002FFFF, 1, 0, 157},
+      Package() {0x0002FFFF, 2, 0, 158},
+      Package() {0x0002FFFF, 3, 0, 159},
+      Package() {0x0003FFFF, 0, 0, 156},
+      Package() {0x0003FFFF, 1, 0, 157},
+      Package() {0x0003FFFF, 2, 0, 158},
+      Package() {0x0003FFFF, 3, 0, 159},
+      Package() {0x0004FFFF, 0, 0, 156},
+      Package() {0x0004FFFF, 1, 0, 157},
+      Package() {0x0004FFFF, 2, 0, 158},
+      Package() {0x0004FFFF, 3, 0, 159},
+      Package() {0x0005FFFF, 0, 0, 156},
+      Package() {0x0005FFFF, 1, 0, 157},
+      Package() {0x0005FFFF, 2, 0, 158},
+      Package() {0x0005FFFF, 3, 0, 159},
+      Package() {0x0006FFFF, 0, 0, 156},
+      Package() {0x0006FFFF, 1, 0, 157},
+      Package() {0x0006FFFF, 2, 0, 158},
+      Package() {0x0006FFFF, 3, 0, 159},
+      Package() {0x0007FFFF, 0, 0, 156},
+      Package() {0x0007FFFF, 1, 0, 157},
+      Package() {0x0007FFFF, 2, 0, 158},
+      Package() {0x0007FFFF, 3, 0, 159},
+      Package() {0x0008FFFF, 0, 0, 156},
+      Package() {0x0008FFFF, 1, 0, 157},
+      Package() {0x0008FFFF, 2, 0, 158},
+      Package() {0x0008FFFF, 3, 0, 159},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x2FFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000018000000,   // AddressMinimum - MIN
+        0x000000001FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00002C0000000000,   // AddressMinimum - MIN
+        0x00002FFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3,0,CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3,4,CDW2)
+        CreateDWordField (Arg3,8,CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2,SUPP)
+        Store (CDW3,CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL,0x1E,CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1,One)) {
+          Or (CDW1,0x08,CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3,CTRL)) {
+          Or (CDW1,0x10,CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL,CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1,4,CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCI7 RCB3
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
new file mode 100755
index 000000000000..2757f3124b83
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
@@ -0,0 +1,2087 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+  //
+  // S1 Start here
+  //
+
+  // PCIE6 S1 RCA2
+  Device (PCIA) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID,"PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID,"PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 6)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCIA")
+    Name (_STR, Unicode("PCIe 10 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 136/137/138/139 + 320 respectively. PCIA RCA2
+      //
+      Package() {0x0001FFFF, 0, 0, 456},
+      Package() {0x0001FFFF, 1, 0, 457},
+      Package() {0x0001FFFF, 2, 0, 458},
+      Package() {0x0001FFFF, 3, 0, 459},
+      Package() {0x0002FFFF, 0, 0, 456},
+      Package() {0x0002FFFF, 1, 0, 457},
+      Package() {0x0002FFFF, 2, 0, 458},
+      Package() {0x0002FFFF, 3, 0, 459},
+      Package() {0x0003FFFF, 0, 0, 456},
+      Package() {0x0003FFFF, 1, 0, 457},
+      Package() {0x0003FFFF, 2, 0, 458},
+      Package() {0x0003FFFF, 3, 0, 459},
+      Package() {0x0004FFFF, 0, 0, 456},
+      Package() {0x0004FFFF, 1, 0, 457},
+      Package() {0x0004FFFF, 2, 0, 458},
+      Package() {0x0004FFFF, 3, 0, 459},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x7BFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FF80000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000070000000,   // AddressMinimum - MIN
+        0x0000000077FFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000780000000000,   // AddressMinimum - MIN
+        0x00007BFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3,0,CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3,4,CDW2)
+        CreateDWordField (Arg3,8,CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2,SUPP)
+        Store (CDW3,CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL,0x1E,CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1,One)) {
+          Or (CDW1,0x08,CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3,CTRL)) {
+          Or (CDW1,0x10,CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL,CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1,4,CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCIA RCA2
+
+  // PCIEB RCA3
+  Device (PCIB) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID,"PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID,"PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 7)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCIB")
+    Name (_STR, Unicode("PCIe 11 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 140/141/142/143 + 320 respectively. PCIB RCA3
+      //
+      Package() {0x0001FFFF, 0, 0, 460},
+      Package() {0x0001FFFF, 1, 0, 461},
+      Package() {0x0001FFFF, 2, 0, 462},
+      Package() {0x0001FFFF, 3, 0, 463},
+      Package() {0x0002FFFF, 0, 0, 460},
+      Package() {0x0002FFFF, 1, 0, 461},
+      Package() {0x0002FFFF, 2, 0, 462},
+      Package() {0x0002FFFF, 3, 0, 463},
+      Package() {0x0003FFFF, 0, 0, 460},
+      Package() {0x0003FFFF, 1, 0, 461},
+      Package() {0x0003FFFF, 2, 0, 462},
+      Package() {0x0003FFFF, 3, 0, 463},
+      Package() {0x0004FFFF, 0, 0, 460},
+      Package() {0x0004FFFF, 1, 0, 461},
+      Package() {0x0004FFFF, 2, 0, 462},
+      Package() {0x0004FFFF, 3, 0, 463},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x7FFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FFC0000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000078000000,   // AddressMinimum - MIN
+        0x000000007FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00007C0000000000,   // AddressMinimum - MIN
+        0x00007FFFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3,0,CDW1)
+      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3,4,CDW2)
+        CreateDWordField (Arg3,8,CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2,SUPP)
+        Store (CDW3,CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL,0x1E,CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1,One)) {
+            Or (CDW1,0x08,CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3,CTRL)) {
+            Or (CDW1,0x10,CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL,CDW3)
+        Return (Arg3)
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1,4,CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCIB RCA3
+
+  // PCIC RCB0
+  Device (PCIC) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 8)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCIC")
+    Name (_STR, Unicode("PCIe 12 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 144/145/146/147 + 320 respectively. PCIC RCB0
+      //
+      Package() {0x0001FFFF, 0, 0, 464},
+      Package() {0x0001FFFF, 1, 0, 465},
+      Package() {0x0001FFFF, 2, 0, 466},
+      Package() {0x0001FFFF, 3, 0, 467},
+      Package() {0x0002FFFF, 0, 0, 464},
+      Package() {0x0002FFFF, 1, 0, 465},
+      Package() {0x0002FFFF, 2, 0, 466},
+      Package() {0x0002FFFF, 3, 0, 467},
+      Package() {0x0003FFFF, 0, 0, 464},
+      Package() {0x0003FFFF, 1, 0, 465},
+      Package() {0x0003FFFF, 2, 0, 466},
+      Package() {0x0003FFFF, 3, 0, 467},
+      Package() {0x0004FFFF, 0, 0, 464},
+      Package() {0x0004FFFF, 1, 0, 465},
+      Package() {0x0004FFFF, 2, 0, 466},
+      Package() {0x0004FFFF, 3, 0, 467},
+      Package() {0x0005FFFF, 0, 0, 464},
+      Package() {0x0005FFFF, 1, 0, 465},
+      Package() {0x0005FFFF, 2, 0, 466},
+      Package() {0x0005FFFF, 3, 0, 467},
+      Package() {0x0006FFFF, 0, 0, 464},
+      Package() {0x0006FFFF, 1, 0, 465},
+      Package() {0x0006FFFF, 2, 0, 466},
+      Package() {0x0006FFFF, 3, 0, 467},
+      Package() {0x0007FFFF, 0, 0, 464},
+      Package() {0x0007FFFF, 1, 0, 465},
+      Package() {0x0007FFFF, 2, 0, 466},
+      Package() {0x0007FFFF, 3, 0, 467},
+      Package() {0x0008FFFF, 0, 0, 464},
+      Package() {0x0008FFFF, 1, 0, 465},
+      Package() {0x0008FFFF, 2, 0, 466},
+      Package() {0x0008FFFF, 3, 0, 467},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x63FFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000040000000,   // AddressMinimum - MIN
+        0x0000000047FFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000600000000000,   // AddressMinimum - MIN
+        0x000063FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCIC RCB0
+
+  // PCID RCB1
+  Device (PCID) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 9)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCID")
+    Name (_STR, Unicode("PCIe 13 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 148/149/150/151 + 320 respectively. PCID RCB1
+      //
+      Package() {0x0001FFFF, 0, 0, 468},
+      Package() {0x0001FFFF, 1, 0, 469},
+      Package() {0x0001FFFF, 2, 0, 470},
+      Package() {0x0001FFFF, 3, 0, 471},
+      Package() {0x0002FFFF, 0, 0, 468},
+      Package() {0x0002FFFF, 1, 0, 469},
+      Package() {0x0002FFFF, 2, 0, 470},
+      Package() {0x0002FFFF, 3, 0, 471},
+      Package() {0x0003FFFF, 0, 0, 468},
+      Package() {0x0003FFFF, 1, 0, 469},
+      Package() {0x0003FFFF, 2, 0, 470},
+      Package() {0x0003FFFF, 3, 0, 471},
+      Package() {0x0004FFFF, 0, 0, 468},
+      Package() {0x0004FFFF, 1, 0, 469},
+      Package() {0x0004FFFF, 2, 0, 470},
+      Package() {0x0004FFFF, 3, 0, 471},
+      Package() {0x0005FFFF, 0, 0, 468},
+      Package() {0x0005FFFF, 1, 0, 469},
+      Package() {0x0005FFFF, 2, 0, 470},
+      Package() {0x0005FFFF, 3, 0, 471},
+      Package() {0x0006FFFF, 0, 0, 468},
+      Package() {0x0006FFFF, 1, 0, 469},
+      Package() {0x0006FFFF, 2, 0, 470},
+      Package() {0x0006FFFF, 3, 0, 471},
+      Package() {0x0007FFFF, 0, 0, 468},
+      Package() {0x0007FFFF, 1, 0, 469},
+      Package() {0x0007FFFF, 2, 0, 470},
+      Package() {0x0007FFFF, 3, 0, 471},
+      Package() {0x0008FFFF, 0, 0, 468},
+      Package() {0x0008FFFF, 1, 0, 469},
+      Package() {0x0008FFFF, 2, 0, 470},
+      Package() {0x0008FFFF, 3, 0, 471},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x67FFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000048000000,   // AddressMinimum - MIN
+        0x000000004FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000640000000000,   // AddressMinimum - MIN
+        0x000067FFDFFFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCID RCB1
+
+  // PCIE RCB2
+  Device (PCIE) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 10)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCIE")
+    Name (_STR, Unicode("PCIe 14 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 152/153/154/155 + 320 respectively. PCIE RCB2
+      //
+      Package() {0x0001FFFF, 0, 0, 472},
+      Package() {0x0001FFFF, 1, 0, 473},
+      Package() {0x0001FFFF, 2, 0, 474},
+      Package() {0x0001FFFF, 3, 0, 475},
+      Package() {0x0002FFFF, 0, 0, 472},
+      Package() {0x0002FFFF, 1, 0, 473},
+      Package() {0x0002FFFF, 2, 0, 474},
+      Package() {0x0002FFFF, 3, 0, 475},
+      Package() {0x0003FFFF, 0, 0, 472},
+      Package() {0x0003FFFF, 1, 0, 473},
+      Package() {0x0003FFFF, 2, 0, 474},
+      Package() {0x0003FFFF, 3, 0, 475},
+      Package() {0x0004FFFF, 0, 0, 472},
+      Package() {0x0004FFFF, 1, 0, 473},
+      Package() {0x0004FFFF, 2, 0, 474},
+      Package() {0x0004FFFF, 3, 0, 475},
+      Package() {0x0005FFFF, 0, 0, 472},
+      Package() {0x0005FFFF, 1, 0, 473},
+      Package() {0x0005FFFF, 2, 0, 474},
+      Package() {0x0005FFFF, 3, 0, 475},
+      Package() {0x0006FFFF, 0, 0, 472},
+      Package() {0x0006FFFF, 1, 0, 473},
+      Package() {0x0006FFFF, 2, 0, 474},
+      Package() {0x0006FFFF, 3, 0, 475},
+      Package() {0x0007FFFF, 0, 0, 472},
+      Package() {0x0007FFFF, 1, 0, 473},
+      Package() {0x0007FFFF, 2, 0, 474},
+      Package() {0x0007FFFF, 3, 0, 475},
+      Package() {0x0008FFFF, 0, 0, 472},
+      Package() {0x0008FFFF, 1, 0, 473},
+      Package() {0x0008FFFF, 2, 0, 474},
+      Package() {0x0008FFFF, 3, 0, 475},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x6BFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000050000000,   // AddressMinimum - MIN
+        0x0000000057FFFFFF,   // AddressMaximum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000680000000000,   // AddressMinimum - MIN
+        0x00006BFFDFFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCIE RCB2
+
+  // PCIF RCB3
+  Device (PCIF) {
+    //
+    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
+    // Section 6.1.5
+    //
+
+    Name (_HID, "PNP0A08")
+    Name (_CCA, ONE)
+
+    Method (_STA, 0, NotSerialized) {
+      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
+                                        // run-time patching as the representation of 0 is special
+                                        // encoding and cannot be patched to expand with extra bytes
+                                        // easily. As such, we default to 0xF and patch this based
+                                        // on whether the port was enabled or not by the BIOS.
+    }
+
+    //
+    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
+    // root complex for use with pre-PCIe operating systems.
+    // Section 6.1.2
+    //
+
+    Name (_CID, "PNP0A03")
+
+    //
+    // Declare the segment number of this root complex. Most systems only
+    // have one segment, which is numbered 0.
+    // Section 6.5.6
+    //
+
+    Name (_SEG, 11)
+
+    //
+    // Declare the base bus number, which is the bus number of the root
+    // bus in this root complex. This is usually 0, but need not be.
+    // For root complexes supporting multiple root busses, this should
+    // be the lowest numbered root bus.
+    // Section 6.5.5
+    //
+
+    Name (_BBN, 0)
+
+    //
+    // The _UID value provides a way of uniquely identifying a device
+    // in the case where more than one instance of a specific device
+    // is implemented with the same _HID/_CID. For systems with a
+    // single root complex, this is usually just 0. For systems with
+    // multiple root complexes, this should be different for each
+    // root complex.
+    // Section 6.1.12
+    //
+
+    Name (_UID, "PCIF")
+    Name (_STR, Unicode("PCIe 15 Device"))
+
+    //
+    // Declare the PCI Routing Table.
+    // This defines SPI mappings of the four line-based interrupts
+    // associated with the root complex and hierarchy below it.
+    // Section 6.2.12
+    //
+
+    Name (_PRT, Package() {
+
+      //
+      // Routing for device 0, all functions.
+      // Note: ARM doesn't support LNK nodes, so the third param
+      // is 0 and the fourth param is the SPI number of the interrupt
+      // line. In this example, the A/B/C/D interrupts are wired to
+      // SPI lines 156/157/158/159 + 320 respectively. PCIF RCB3
+      //
+      Package() {0x0001FFFF, 0, 0, 476},
+      Package() {0x0001FFFF, 1, 0, 477},
+      Package() {0x0001FFFF, 2, 0, 478},
+      Package() {0x0001FFFF, 3, 0, 479},
+      Package() {0x0002FFFF, 0, 0, 476},
+      Package() {0x0002FFFF, 1, 0, 477},
+      Package() {0x0002FFFF, 2, 0, 478},
+      Package() {0x0002FFFF, 3, 0, 479},
+      Package() {0x0003FFFF, 0, 0, 476},
+      Package() {0x0003FFFF, 1, 0, 477},
+      Package() {0x0003FFFF, 2, 0, 478},
+      Package() {0x0003FFFF, 3, 0, 479},
+      Package() {0x0004FFFF, 0, 0, 476},
+      Package() {0x0004FFFF, 1, 0, 477},
+      Package() {0x0004FFFF, 2, 0, 478},
+      Package() {0x0004FFFF, 3, 0, 479},
+      Package() {0x0005FFFF, 0, 0, 476},
+      Package() {0x0005FFFF, 1, 0, 477},
+      Package() {0x0005FFFF, 2, 0, 478},
+      Package() {0x0005FFFF, 3, 0, 479},
+      Package() {0x0006FFFF, 0, 0, 476},
+      Package() {0x0006FFFF, 1, 0, 477},
+      Package() {0x0006FFFF, 2, 0, 478},
+      Package() {0x0006FFFF, 3, 0, 479},
+      Package() {0x0007FFFF, 0, 0, 476},
+      Package() {0x0007FFFF, 1, 0, 477},
+      Package() {0x0007FFFF, 2, 0, 478},
+      Package() {0x0007FFFF, 3, 0, 479},
+      Package() {0x0008FFFF, 0, 0, 476},
+      Package() {0x0008FFFF, 1, 0, 477},
+      Package() {0x0008FFFF, 2, 0, 478},
+      Package() {0x0008FFFF, 3, 0, 479},
+    })
+
+    //
+    // Declare the resources assigned to this root complex.
+    // Section 6.2.2
+    //
+    Method (_CBA, 0, Serialized) {
+      Return (0x6FFFF0000000)
+    }
+
+    //
+    // Declare a ResourceTemplate buffer to return the resource
+    // requirements from _CRS.
+    // Section 19.5.109
+    //
+
+    Name (RBUF, ResourceTemplate () {
+
+      //
+      // Declare the range of bus numbers assigned to this root
+      // complex. In this example, the minimum bus number will be
+      // 0, the maximum bus number will be 0xFF, supporting
+      // 256 busses total.
+      // Section 19.5.141
+      //
+
+      WordBusNumber (
+        ResourceProducer,
+        MinFixed,   // IsMinFixed
+        MaxFixed,   // IsMaxFixed
+        PosDecode,  // Decode
+        0,          // AddressGranularity
+        0,          // AddressMinimum - Minimum Bus Number
+        255,        // AddressMaximum - Maximum Bus Number
+        0,          // AddressTranslation - Set to 0
+        256)        // RangeLength - Number of Busses
+
+      //
+      // Declare the memory range to be used for BAR memory
+      // windows. This declares a 4GB region starting at
+      // 0x4000000000.
+      // Section 19.5.80
+      //
+      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x0000000058000000,   // AddressMinimum - MIN
+        0x000000005FFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x0000000008000000    // RangeLength - LEN
+      )
+
+      QWordMemory (
+        ResourceProducer,     // ResourceUsage
+        PosDecode,            // Decode
+        MinFixed,             // IsMinFixed
+        MaxFixed,             // IsMaxFixed
+        NonCacheable,         // NonCacheable
+        ReadWrite,            // ReadAndWrite
+        0x0000000000000000,   // AddressGranularity - GRA
+        0x00006C0000000000,   // AddressMinimum - MIN
+        0x00006FFFDFFFFFFF,   // AddressMinimum - MAX
+        0x0000000000000000,   // AddressTranslation - TRA
+        0x000003FFE0000000    // RangeLength - LEN
+      )
+    })
+
+    Method (_CRS, 0, Serialized) {
+      Return (RBUF)
+    }
+
+    //
+    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
+    //
+    // Argments:
+    //   Arg0  A Buffer containing a UUID
+    //   Arg1  An Integer containing a Revision ID of the buffer format
+    //   Arg2  An Integer containing a count of entries in Arg3
+    //   Arg3  A Buffer containing a list of DWORD capabilities
+    // Return Value:
+    //   A Buffer containing a list of capabilities
+    // See the APCI spec, Section 6.2.10,
+    // and the PCI FW spec, Section 4.5.
+    //
+    // The following is an example, and may need modification for
+    // specific implementations.
+    //
+
+    Name (SUPP,0) // PCI _OSC Support Field value
+    Name (CTRL,0) // PCI _OSC Control Field value
+
+    Method (_OSC, 4) {
+
+      //
+      // Look for the PCI Host Bridge Interface UUID.
+      // Section 6.2.10.3
+      //
+
+      //
+      // Create DWord-adressable fields from the Capabilities Buffer
+      // Create CDW1 outside the test as it's used in the else clause.
+      //
+
+      CreateDWordField (Arg3, 0, CDW1)
+      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+
+        CreateDWordField (Arg3, 4, CDW2)
+        CreateDWordField (Arg3, 8, CDW3)
+
+        //
+        // Save Capabilities DWord 2 & 3
+        //
+
+        Store (CDW2, SUPP)
+        Store (CDW3, CTRL)
+
+        //
+        // Only allow native hot plug control if OS supports:
+        //  ASPM
+        //  Clock PM
+        //  MSI/MSI-X
+        //
+
+        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
+
+          //
+          // Mask bit 0 (and undefined bits)
+          //
+
+          And (CTRL, 0x1E, CTRL)
+        }
+
+        //
+        // Never allow native Hot plug, PME.
+        // Never allow SHPC (no SHPC controller in this system).
+        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
+        // Allows PCI Express Capability Structure control
+        //
+
+        If (AERF) {
+          And (CTRL, 0x10, CTRL)
+        } Else {
+          And (CTRL, 0x18, CTRL)
+        }
+
+        //
+        // Check for unknown revision.
+        //
+
+        If (LNotEqual (Arg1, One)) {
+          Or (CDW1, 0x08, CDW1)
+        }
+
+        //
+        // Check if capabilities bits were masked.
+        //
+
+        If (LNotEqual (CDW3, CTRL)) {
+          Or (CDW1, 0x10, CDW1)
+        }
+
+        //
+        // Update DWORD3 in the buffer.
+        //
+
+        Store (CTRL, CDW3)
+        Return (Arg3)
+
+      } Else {
+
+        //
+        // Unrecognized UUID
+        //
+
+        Or (CDW1, 4, CDW1)
+        Return (Arg3)
+      }
+    } // End _OSC
+
+    //
+    // Declare a _DSM method for various functions called by the OS.
+    // See the APCI spec, Section 9.14.1,
+    // and the PCI FW spec, Section 4.6.
+    // See also:
+    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+    //
+
+    Method (_DSM, 0x4, Serialized) {
+
+      //
+      // Match against the _DSM PCI GUID.
+      //
+
+      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
+
+        Switch (ToInteger(Arg2)) {
+          //
+          // Function 0: Return supported functions as a bitfield
+          // with one bit for each supported function.
+          // Bit 0 must always be set, as that represents
+          // function 0 (which is what is being called here).
+          // Support for different functions may depend on
+          // the revision ID of the interface, passed as Arg1.
+          //
+
+          Case (0) {
+
+              //
+              // Functions 0-7 are supported.
+              //
+
+              Return (Buffer() {0x01})
+          }
+        }
+      }
+
+      //
+      // If not one of the function identifiers we recognize, then return a buffer
+      // with bit 0 set to 0 indicating no functions supported.
+      //
+
+      Return (Buffer() {0})
+    }
+
+    //
+    // Root Port 0 Device within the Root Complex.
+    //
+    Device (RP0) {
+      //
+      // Device 0, Function 0.
+      //
+
+      Name (_ADR, 0x00000000)
+    }
+
+    Method (_PXM, 0, NotSerialized) {
+      // Patch by code
+      Return(0xFF)
+    }
+  } // PCIF RCB3
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
new file mode 100755
index 000000000000..0e9db557d925
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
@@ -0,0 +1,1303 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(CMN0) {
+  Name(_HID, "ARMHC600") // Device Identification Objects
+  Name(_CID, "ARMHC600")
+  Name(_UID, 0)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("CMN0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+  QWordMemory (
+    ResourceConsumer,     // ResourceUsage
+    PosDecode,            // Decode
+    MinFixed,             // IsMinFixed
+    MaxFixed,             // IsMaxFixed
+    NonCacheable,         // Cacheable
+    ReadWrite,            // ReadAndWrite
+    0x0000000000000000,   // AddressGranularity - GRA
+    0x0000100010000000,   // AddressMinimum - MIN
+    0x000010001fffffff,   // AddressMaximum - MAX
+    0x0000000000000000,   // AddressTranslation - TRA
+    0x0000000010000000    // RangeLength - LEN
+  )
+  QWordMemory (
+    ResourceConsumer,     // ResourceUsage
+    PosDecode,            // Decode
+    MinFixed,             // IsMinFixed
+    MaxFixed,             // IsMaxFixed
+    NonCacheable,         // Cacheable
+    ReadWrite,            // ReadAndWrite
+    0x0000000000000000,   // AddressGranularity - GRA
+    0x0000100012500000,   // AddressMinimum - MIN
+    0x00001000164fffff,   // AddressMaximum - MAX
+    0x0000000000000000,   // AddressTranslation - TRA
+    0x0000000004000000    // RangeLength - LEN
+  )
+  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 314 }
+  })
+}
+
+Device(MC00) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008C000A00,   // AddressMinimum - MIN
+      0x000010008C000BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC01) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 1)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008C400A00,   // AddressMinimum - MIN
+      0x000010008C400BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC02) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 2)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU2"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008C800A00,   // AddressMinimum - MIN
+      0x000010008C800BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC03) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 3)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU3"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008CC00A00,   // AddressMinimum - MIN
+      0x000010008CC00BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC04) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 4)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU4"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008D000A00,   // AddressMinimum - MIN
+      0x000010008D000BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC05) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 5)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU5"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008D400A00,   // AddressMinimum - MIN
+      0x000010008D400BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC06) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 6)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU6"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008D800A00,   // AddressMinimum - MIN
+      0x000010008D800BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(MC07) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 7)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 0: MCU7"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000010008DC00A00,   // AddressMinimum - MIN
+      0x000010008DC00BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
+  })
+}
+
+Device(DU00) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 64 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x000000,
+          0x000100
+        }
+      }
+    }
+  })
+}
+
+Device(DU01) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 65 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x010000,
+          0x010100
+        }
+      }
+    }
+  })
+}
+
+Device(DU02) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x2)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x2 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 66 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x020000,
+          0x020100
+        }
+      }
+    }
+  })
+}
+
+Device(DU03) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x3)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x3 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 67 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x030000,
+          0x030100
+        }
+      }
+    }
+  })
+}
+
+Device(DU04) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 68 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x040000,
+          0x040100
+        }
+      }
+    }
+  })
+}
+
+Device(DU05) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 69 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x050000,
+          0x050100
+        }
+      }
+    }
+  })
+}
+
+Device(DU06) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x6)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x6 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 71 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x060000,
+          0x060100
+        }
+      }
+    }
+  })
+}
+
+Device(DU07) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x7)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x7 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 80 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x070000,
+          0x070100
+        }
+      }
+    }
+  })
+}
+
+Device(DU08) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x8)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x8 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 81 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x080000,
+          0x080100
+        }
+      }
+    }
+  })
+}
+
+Device(DU09) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x9)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x9 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 82 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x090000,
+          0x090100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0A) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xA)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xA Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 83 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0A0000,
+          0x0A0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0B) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xB)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xB Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 115 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0B0000,
+          0x0B0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0C) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xC)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xC Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 116 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0C0000,
+          0x0C0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0D) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xD)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xD Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 221 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0D0000,
+          0x0D0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0E) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xE)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xE Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 222 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0E0000,
+          0x0E0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU0F) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0xF)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0xF Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 223 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x0F0000,
+          0x0F0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU10) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x10)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x10 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 248 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100000,
+          0x100100
+        }
+      }
+    }
+  })
+}
+
+Device(DU11) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x11)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x11 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 249 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x110000,
+          0x110100
+        }
+      }
+    }
+  })
+}
+
+Device(DU12) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x12)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x12 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 250 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x120000,
+          0x120100
+        }
+      }
+    }
+  })
+}
+
+Device(DU13) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x13)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x13 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 251 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x130000,
+          0x130100
+        }
+      }
+    }
+  })
+}
+
+Device(DU14) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x14)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x14 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 252 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x140000,
+          0x140100
+        }
+      }
+    }
+  })
+}
+
+Device(DU15) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x15)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x15 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 253 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x150000,
+          0x150100
+        }
+      }
+    }
+  })
+}
+
+Device(DU16) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x16)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x16 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 254 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x160000,
+          0x160100
+        }
+      }
+    }
+  })
+}
+
+Device(DU17) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x17)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x17 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 255 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x170000,
+          0x170100
+        }
+      }
+    }
+  })
+}
+
+Device(DU18) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x18)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x18 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 297 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x180000,
+          0x180100
+        }
+      }
+    }
+  })
+}
+
+Device(DU19) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x19)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x19 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 298 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x190000,
+          0x190100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1A) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1A)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1A Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 299 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1A0000,
+          0x1A0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1B) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1B)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1B Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 300 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1B0000,
+          0x1B0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1C) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1C)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1C Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 301 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1C0000,
+          0x1C0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1D) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1D)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1D Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 313 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1D0000,
+          0x1D0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1E) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1E)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1E Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 316 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1E0000,
+          0x1E0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU1F) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x1F)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x1F Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 317 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1F0000,
+          0x1F0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU20) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x20)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x20 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 318 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x200000,
+          0x200100
+        }
+      }
+    }
+  })
+}
+
+Device(DU21) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x21)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x21 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 319 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x210000,
+          0x210100
+        }
+      }
+    }
+  })
+}
+
+Device(DU22) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x22)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x22 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 344 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x220000,
+          0x220100
+        }
+      }
+    }
+  })
+}
+
+Device(DU23) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x23)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x23 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 345 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x230000,
+          0x230100
+        }
+      }
+    }
+  })
+}
+
+Device(DU24) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x24)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x24 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 346 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x240000,
+          0x240100
+        }
+      }
+    }
+  })
+}
+
+Device(DU25) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x25)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x25 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 347 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x250000,
+          0x250100
+        }
+      }
+    }
+  })
+}
+
+Device(DU26) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x26)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x26 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 348 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x260000,
+          0x260100
+        }
+      }
+    }
+  })
+}
+
+Device(DU27) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x27)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x27 Socket 0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 349 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x270000,
+          0x270100
+        }
+      }
+    }
+  })
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
new file mode 100755
index 000000000000..1ae1bac8098b
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
@@ -0,0 +1,1303 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Device(CMN1) {
+  Name(_HID, "ARMHC600") // Device Identification Objects
+  Name(_CID, "ARMHC600")
+  Name(_UID, 1)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("CMN1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+  QWordMemory (
+    ResourceConsumer,     // ResourceUsage
+    PosDecode,            // Decode
+    MinFixed,             // IsMinFixed
+    MaxFixed,             // IsMaxFixed
+    NonCacheable,         // Cacheable
+    ReadWrite,            // ReadAndWrite
+    0x0000000000000000,   // AddressGranularity - GRA
+    0x0000500010000000,   // AddressMinimum - MIN
+    0x000050001fffffff,   // AddressMaximum - MAX
+    0x0000000000000000,   // AddressTranslation - TRA
+    0x0000000010000000    // RangeLength - LEN
+  )
+  QWordMemory (
+    ResourceConsumer,     // ResourceUsage
+    PosDecode,            // Decode
+    MinFixed,             // IsMinFixed
+    MaxFixed,             // IsMaxFixed
+    NonCacheable,         // Cacheable
+    ReadWrite,            // ReadAndWrite
+    0x0000000000000000,   // AddressGranularity - GRA
+    0x0000500012500000,   // AddressMinimum - MIN
+    0x00005000164fffff,   // AddressMaximum - MAX
+    0x0000000000000000,   // AddressTranslation - TRA
+    0x0000000004000000    // RangeLength - LEN
+  )
+  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 634 }
+  })
+}
+
+Device(MC10) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 8)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU0"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008C000A00,   // AddressMinimum - MIN
+      0x000050008C000BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC11) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 9)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008C400A00,   // AddressMinimum - MIN
+      0x000050008C400BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC12) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xa)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU2"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008C800A00,   // AddressMinimum - MIN
+      0x000050008C800BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC13) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xb)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU3"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008CC00A00,   // AddressMinimum - MIN
+      0x000050008CC00BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC14) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xc)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU4"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008D000A00,   // AddressMinimum - MIN
+      0x000050008D000BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC15) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xd)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU5"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008D400A00,   // AddressMinimum - MIN
+      0x000050008D400BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC16) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xe)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU6"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008D800A00,   // AddressMinimum - MIN
+      0x000050008D800BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(MC17) {
+  Name(_HID, "ARMHD620")
+  Name(_CID, "ARMHD620")
+  Name(_UID, 0xf)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("Socket 1: MCU7"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    QWordMemory (
+      ResourceProducer,     // ResourceUsage
+      PosDecode,            // Decode
+      MinFixed,             // IsMinFixed
+      MaxFixed,             // IsMaxFixed
+      NonCacheable,         // Cacheable
+      ReadWrite,            // ReadAndWrite
+      0x0000000000000000,   // AddressGranularity - GRA
+      0x000050008DC00A00,   // AddressMinimum - MIN
+      0x000050008DC00BFF,   // AddressMaximum - MAX
+      0x0000000000000000,   // AddressTranslation - TRA
+      0x0000000000000200    // RangeLength - LEN
+    )
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
+  })
+}
+
+Device(DU40) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x40)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x40 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 384 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100000000,
+          0x100000100
+        }
+      }
+    }
+  })
+}
+
+Device(DU41) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x41)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x41 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 385 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100010000,
+          0x100010100
+        }
+      }
+    }
+  })
+}
+
+Device(DU42) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x42)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x42 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 386 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100020000,
+          0x100020100
+        }
+      }
+    }
+  })
+}
+
+Device(DU43) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x43)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x43 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 387 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100030000,
+          0x100030100
+        }
+      }
+    }
+  })
+}
+
+Device(DU44) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x44)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x44 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 388 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100040000,
+          0x100040100
+        }
+      }
+    }
+  })
+}
+
+Device(DU45) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x45)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x45 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 389 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100050000,
+          0x100050100
+        }
+      }
+    }
+  })
+}
+
+Device(DU46) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x46)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x46 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 391 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100060000,
+          0x100060100
+        }
+      }
+    }
+  })
+}
+
+Device(DU47) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x47)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x47 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 400 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100070000,
+          0x100070100
+        }
+      }
+    }
+  })
+}
+
+Device(DU48) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x48)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x48 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 401 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100080000,
+          0x100080100
+        }
+      }
+    }
+  })
+}
+
+Device(DU49) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x49)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x49 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 402 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100090000,
+          0x100090100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4A) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4A)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4A Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 403 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000A0000,
+          0x1000A0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4B) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4B)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4B Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 435 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000B0000,
+          0x1000B0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4C) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4C)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4C Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 436 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000C0000,
+          0x1000C0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4D) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4D)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4D Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 541 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000D0000,
+          0x1000D0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4E) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4E)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4E Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 542 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000E0000,
+          0x1000E0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU4F) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x4F)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x4F Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 543 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1000F0000,
+          0x1000F0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU50) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x50)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x50 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 568 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100100000,
+          0x100100100
+        }
+      }
+    }
+  })
+}
+
+Device(DU51) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x51)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x51 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 569 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100110000,
+          0x100110100
+        }
+      }
+    }
+  })
+}
+
+Device(DU52) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x52)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x52 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 570 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100120000,
+          0x100120100
+        }
+      }
+    }
+  })
+}
+
+Device(DU53) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x53)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x53 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 571 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100130000,
+          0x100130100
+        }
+      }
+    }
+  })
+}
+
+Device(DU54) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x54)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x54 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 572 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100140000,
+          0x100140100
+        }
+      }
+    }
+  })
+}
+
+Device(DU55) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x55)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x55 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 573 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100150000,
+          0x100150100
+        }
+      }
+    }
+  })
+}
+
+Device(DU56) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x56)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x56 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 574 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100160000,
+          0x100160100
+        }
+      }
+    }
+  })
+}
+
+Device(DU57) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x57)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x57 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 575 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100170000,
+          0x100170100
+        }
+      }
+    }
+  })
+}
+
+Device(DU58) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x58)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x58 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 617 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100180000,
+          0x100180100
+        }
+      }
+    }
+  })
+}
+
+Device(DU59) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x59)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x59 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 618 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100190000,
+          0x100190100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5A) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5A)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5A Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 619 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001A0000,
+          0x1001A0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5B) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5B)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5B Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 620 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001B0000,
+          0x1001B0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5C) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5C)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5C Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 621 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001C0000,
+          0x1001C0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5D) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5D)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5D Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 633 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001D0000,
+          0x1001D0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5E) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5E)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5E Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 636 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001E0000,
+          0x1001E0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU5F) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x5F)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x5F Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 637 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x1001F0000,
+          0x1001F0100
+        }
+      }
+    }
+  })
+}
+
+Device(DU60) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x60)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x60 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 638 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100200000,
+          0x100200100
+        }
+      }
+    }
+  })
+}
+
+Device(DU61) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x61)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x61 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 639 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100210000,
+          0x100210100
+        }
+      }
+    }
+  })
+}
+
+Device(DU62) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x62)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x62 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 664 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100220000,
+          0x100220100
+        }
+      }
+    }
+  })
+}
+
+Device(DU63) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x63)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x63 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 665 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100230000,
+          0x100230100
+        }
+      }
+    }
+  })
+}
+
+Device(DU64) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x64)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x64 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 666 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100240000,
+          0x100240100
+        }
+      }
+    }
+  })
+}
+
+Device(DU65) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x65)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x65 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 667 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100250000,
+          0x100250100
+        }
+      }
+    }
+  })
+}
+
+Device(DU66) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x66)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x66 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 668 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100260000,
+          0x100260100
+        }
+      }
+    }
+  })
+}
+
+Device(DU67) {
+  Name(_HID, "ARMHD500")
+  Name(_CID, "ARMHD500")
+  Name(_UID, 0x67)
+  Name(_CCA, ONE)
+  Name(_STR, Unicode("DSU CPM 0x67 Socket 1"))
+  Method(_STA, 0, NotSerialized) {
+    Return (0x0f)
+  }
+  Name(_CRS, ResourceTemplate() {
+    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 669 }
+  })
+  Name (_DSD, Package () {
+    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
+    Package () {
+      Package (2) {
+        "cpus",
+        Package (2) {
+          0x100270000,
+          0x100270100
+        }
+      }
+    }
+  })
+}
diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
new file mode 100644
index 000000000000..0d177de8696d
--- /dev/null
+++ b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
@@ -0,0 +1,10 @@
+/** @file
+
+  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+Include ("PMU-S0.asi")
+Include ("PMU-S1.asi")
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
new file mode 100644
index 000000000000..a80f1e81b24f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
@@ -0,0 +1,33 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Acpi.h>
+#include <AcpiHeader.h>
+
+#define BOOT_ERROR_REGION_LENGTH  0x50000
+#define BOOT_ERROR_REGION_BASE    0x0000000088230000
+
+#pragma pack(1)
+
+EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER Bert = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE,
+    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER,
+    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_REVISION
+  ),
+  BOOT_ERROR_REGION_LENGTH,
+  BOOT_ERROR_REGION_BASE
+};
+
+#pragma pack()
+
+//
+// Reference the table being generated to prevent the optimizer from removing
+// the data structure from the executable
+//
+VOID* CONST ReferenceAcpiTable = &Bert;
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
new file mode 100644
index 000000000000..bc2bbded11fd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
@@ -0,0 +1,87 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Acpi.h>
+#include <IndustryStandard/DebugPort2Table.h>
+#include <AcpiHeader.h>
+
+#pragma pack(1)
+
+#define DBG2_NUM_DEBUG_PORTS                       1
+#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS   1
+#define DBG2_NAMESPACESTRING_FIELD_SIZE            10
+#define SERIAL_PORT_PL011_UART_ADDR_SIZE           0x8
+
+#define NAME_STR_UART2     {'\\', '_', 'S', 'B', '.', 'U', 'R', 'T', '2', '\0'}
+
+typedef struct {
+  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
+  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;
+  UINT32                                        AddressSize;
+  UINT8                                         NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];
+} DBG2_DEBUG_DEVICE_INFORMATION;
+
+typedef struct {
+  EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE       Description;
+  DBG2_DEBUG_DEVICE_INFORMATION                 Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS];
+} DBG2_TABLE;
+
+
+#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) {                                    \
+    {                                                                                                                 \
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,         /* UINT8     Revision */                        \
+      sizeof (DBG2_DEBUG_DEVICE_INFORMATION),                         /* UINT16    Length */                          \
+      NumReg,                                                         /* UINT8     NumberofGenericAddressRegisters */ \
+      DBG2_NAMESPACESTRING_FIELD_SIZE,                                /* UINT16    NameSpaceStringLength */           \
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString),     /* UINT16    NameSpaceStringOffset */           \
+      0,                                                              /* UINT16    OemDataLength */                   \
+      0,                                                              /* UINT16    OemDataOffset */                   \
+      EFI_ACPI_DBG2_PORT_TYPE_SERIAL,                                 /* UINT16    Port Type */                       \
+      SubType,                                                        /* UINT16    Port Subtype */                    \
+      {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE},               /* UINT8     Reserved[2] */                     \
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16    BaseAddressRegister Offset */      \
+      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize)          /* UINT16    AddressSize Offset */              \
+    },                                                                                                                \
+    ARM_GAS32 (UartBase),                            /* EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
+    UartAddrLen,                                     /* UINT32  AddressSize */                                        \
+    UartNameStr                                      /* UINT8   NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE] */   \
+  }
+
+
+STATIC DBG2_TABLE Dbg2 = {
+  {
+    __ACPI_HEADER (
+      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
+      DBG2_TABLE,
+      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
+    ),
+    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
+    DBG2_NUM_DEBUG_PORTS                                 /* UINT32  NumberDbgDeviceInfo */
+  },
+  {
+    // Kernel Debug Port
+    DBG2_DEBUG_PORT_DDI (
+      DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,
+      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART,
+      FixedPcdGet64 (PcdSerialDbgRegisterBase),
+      SERIAL_PORT_PL011_UART_ADDR_SIZE,
+      NAME_STR_UART2
+      ),
+  }
+};
+
+#pragma pack()
+
+//
+// Reference the table being generated to prevent the optimizer from removing
+// the data structure from the executable
+//
+VOID* CONST ReferenceAcpiTable = &Dbg2;
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
new file mode 100755
index 000000000000..9607b2e403e0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
@@ -0,0 +1,165 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+[0004]                          Signature : "EINJ"    [Error Injection table]
+[0004]                       Table Length : 00000150
+[0001]                           Revision : 01
+[0001]                           Checksum : 09
+[0006]                             Oem ID : "Ampere"
+[0008]                       Oem Table ID : "Altra   "
+[0004]                       Oem Revision : 00000001
+[0004]                    Asl Compiler ID : "INTL"
+[0004]              Asl Compiler Revision : 20100528
+
+[0004]            Injection Header Length : 00000030
+[0001]                              Flags : 00
+[0003]                           Reserved : 000000
+[0004]              Injection Entry Count : 00000009
+
+[0001]                             Action : 00 [Begin Operation]
+[0001]                        Instruction : 00 [Read Register]
+[0001]              Flags (decoded below) : 00
+                   Preserve Register Bits : 0
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088220000
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 01 [Get Trigger Table]
+[0001]                        Instruction : 00 [Read Register]
+[0001]              Flags (decoded below) : 00
+                   Preserve Register Bits : 0
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088220040
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 08 [Set Error Type With Address]
+[0001]                        Instruction : 02 [Write Register]
+[0001]              Flags (decoded below) : 01
+                   Preserve Register Bits : 1
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 20
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 03 [DWord Access:32]
+[0008]                            Address : 0000000088221000
+
+[0008]                              Value : 00000000
+[0008]                               Mask : FFFFFFFF
+
+[0001]                             Action : 02 [Set Error Type]
+[0001]                        Instruction : 02 [Write Register]
+[0001]              Flags (decoded below) : 01
+                   Preserve Register Bits : 1
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 20
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [DWord Access:64]
+[0008]                            Address : 0000000088220080
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 03 [Get Error Type]
+[0001]                        Instruction : 00 [Read Register]
+[0001]              Flags (decoded below) : 00
+                   Preserve Register Bits : 0
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 00000000882200c0
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 04 [End Operation]
+[0001]                        Instruction : 03 [Write Register Value]
+[0001]              Flags (decoded below) : 01
+                   Preserve Register Bits : 1
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088220100
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 05 [Execute Operation]
+[0001]                        Instruction : 03 [Write Register Value]
+[0001]              Flags (decoded below) : 01
+                   Preserve Register Bits : 1
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 20
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 03 [DWord Access:32]
+[0008]                            Address : 0000100000543010
+
+[0008]                              Value : B1A00000
+[0008]                               Mask : FFFFFFFF
+
+[0001]                             Action : 06 [Check Busy Status]
+[0001]                        Instruction : 01 [Read Register Value]
+[0001]              Flags (decoded below) : 00
+                   Preserve Register Bits : 0
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088220140
+
+[0008]                              Value : 0000000000000001
+[0008]                               Mask : FFFFFFFFFFFFFFFF
+
+[0001]                             Action : 07 [Get Command Status]
+[0001]                        Instruction : 00 [Read Register]
+[0001]              Flags (decoded below) : 01
+                   Preserve Register Bits : 1
+[0001]                           Reserved : 00
+
+[0012]                    Register Region : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088220180
+
+[0008]                              Value : 0000000000000000
+[0008]                               Mask : FFFFFFFFFFFFFFFF
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
new file mode 100644
index 000000000000..5be828f1cdf0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
@@ -0,0 +1,87 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/AcpiLib.h>
+#include <IndustryStandard/Acpi63.h>
+#include <AcpiHeader.h>
+
+//
+// This macro defines the FADT flag options.
+//
+#define FADT_FLAGS  (EFI_ACPI_6_3_HW_REDUCED_ACPI | \
+                     EFI_ACPI_6_3_PWR_BUTTON)
+
+
+EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
+    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE,
+    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
+  ),
+  0,                                                                        // UINT32     FirmwareCtrl
+  0,                                                                        // UINT32     Dsdt
+  EFI_ACPI_RESERVED_BYTE,                                                   // UINT8      Reserved0
+  EFI_ACPI_6_3_PM_PROFILE_PERFORMANCE_SERVER,                               // UINT8      PreferredPmProfile
+  0,                                                                        // UINT16     SciInt
+  0,                                                                        // UINT32     SmiCmd
+  0,                                                                        // UINT8      AcpiEnable
+  0,                                                                        // UINT8      AcpiDisable
+  0,                                                                        // UINT8      S4BiosReq
+  0,                                                                        // UINT8      PstateCnt
+  0,                                                                        // UINT32     Pm1aEvtBlk
+  0,                                                                        // UINT32     Pm1bEvtBlk
+  0,                                                                        // UINT32     Pm1aCntBlk
+  0,                                                                        // UINT32     Pm1bCntBlk
+  0,                                                                        // UINT32     Pm2CntBlk
+  0,                                                                        // UINT32     PmTmrBlk
+  0,                                                                        // UINT32     Gpe0Blk
+  0,                                                                        // UINT32     Gpe1Blk
+  0,                                                                        // UINT8      Pm1EvtLen
+  0,                                                                        // UINT8      Pm1CntLen
+  0,                                                                        // UINT8      Pm2CntLen
+  0,                                                                        // UINT8      PmTmrLen
+  0,                                                                        // UINT8      Gpe0BlkLen
+  0,                                                                        // UINT8      Gpe1BlkLen
+  0,                                                                        // UINT8      Gpe1Base
+  0,                                                                        // UINT8      CstCnt
+  0,                                                                        // UINT16     PLvl2Lat
+  0,                                                                        // UINT16     PLvl3Lat
+  0,                                                                        // UINT16     FlushSize
+  0,                                                                        // UINT16     FlushStride
+  0,                                                                        // UINT8      DutyOffset
+  0,                                                                        // UINT8      DutyWidth
+  0,                                                                        // UINT8      DayAlrm
+  0,                                                                        // UINT8      MonAlrm
+  0,                                                                        // UINT8      Century
+  0,                                                                        // UINT16     IaPcBootArch
+  0,                                                                        // UINT8      Reserved1
+  FADT_FLAGS,                                                               // UINT32     Flags
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  ResetReg
+  0,                                                                        // UINT8      ResetValue
+  EFI_ACPI_6_3_ARM_PSCI_COMPLIANT,                                          // UINT16     ArmBootArchFlags
+  EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,                 // UINT8      MinorRevision
+  0,                                                                        // UINT64     XFirmwareCtrl
+  0,                                                                        // UINT64     XDsdt
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk
+  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk
+  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepControlReg
+  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg
+  0                                                                         // UINT64 HypervisorVendorIdentity
+};
+
+//
+// Reference the table being generated to prevent the optimizer from removing the
+// data structure from the executable
+//
+VOID* CONST ReferenceAcpiTable = &Fadt;
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
new file mode 100644
index 000000000000..3824bd6bb956
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
@@ -0,0 +1,180 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/PcdLib.h>
+#include <Library/AcpiLib.h>
+#include <IndustryStandard/Acpi63.h>
+#include <AcpiHeader.h>
+
+#define SYSTEM_TIMER_BASE_ADDRESS       0xFFFFFFFFFFFFFFFF
+#define CNT_READ_BASE_ADDRESS           0xFFFFFFFFFFFFFFFF
+
+#define SECURE_TIMER_EL1_GSIV           0x1D
+#define NON_SECURE_TIMER_EL1_GSIV       0x1E
+#define VIRTUAL_TIMER_GSIV              0x1B
+#define NON_SECURE_EL2_GSIV             0x1A
+
+#define GTDT_TIMER_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
+#define GTDT_TIMER_LEVEL_TRIGGERED  0
+#define GTDT_TIMER_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
+#define GTDT_TIMER_ACTIVE_HIGH      0
+#define GTDT_TIMER_SAVE_CONTEXT     EFI_ACPI_6_3_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
+#define GTDT_TIMER_LOSE_CONTEXT     0
+
+#define GTDT_GTIMER_FLAGS          (GTDT_TIMER_LOSE_CONTEXT | GTDT_TIMER_ACTIVE_HIGH | GTDT_TIMER_LEVEL_TRIGGERED)
+
+#define WATCHDOG_COUNT              FixedPcdGet32 (PcdWatchdogCount)
+#define PLATFORM_TIMER_COUNT        (WATCHDOG_COUNT + 1)
+#define TIMER_FRAMES_COUNT          3
+
+#define GT_BLOCK_CTL_BASE               0x0000100002700000
+#define GT_BLOCK_FRAME0_CTL_BASE        0x0000100002710000
+#define GT_BLOCK_FRAME0_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
+#define GT_BLOCK_FRAME0_GSIV            0x58
+
+#define GT_BLOCK_FRAME1_CTL_BASE        0x0000100002720000
+#define GT_BLOCK_FRAME1_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
+#define GT_BLOCK_FRAME1_GSIV            0x59
+
+#define GT_BLOCK_FRAME2_CTL_BASE        0x0000100002730000
+#define GT_BLOCK_FRAME2_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
+#define GT_BLOCK_FRAME2_GSIV            0x5A
+
+#define GTX_TIMER_EDGE_TRIGGERED        EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE
+#define GTX_TIMER_LEVEL_TRIGGERED       0
+#define GTX_TIMER_ACTIVE_LOW            EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
+#define GTX_TIMER_ACTIVE_HIGH           0
+
+#define GTX_TIMER_FLAGS                 (GTX_TIMER_ACTIVE_HIGH | GTX_TIMER_LEVEL_TRIGGERED)
+
+#define GTX_TIMER_SECURE                EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER
+#define GTX_TIMER_NON_SECURE            0
+#define GTX_TIMER_SAVE_CONTEXT          EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY
+#define GTX_TIMER_LOSE_CONTEXT          0
+
+#define GTX_COMMON_FLAGS_S              (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_SECURE)
+#define GTX_COMMON_FLAGS_NS             (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_NON_SECURE)
+
+#define SBSA_WATCHDOG_REFRESH_BASE     0x00001000027D0000
+#define SBSA_WATCHDOG_CONTROL_BASE     0x00001000027C0000
+#define SBSA_WATCHDOG_GSIV             0x5C
+
+#define SBSA_WATCHDOG_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
+#define SBSA_WATCHDOG_LEVEL_TRIGGERED  0
+#define SBSA_WATCHDOG_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
+#define SBSA_WATCHDOG_ACTIVE_HIGH      0
+#define SBSA_WATCHDOG_SECURE           EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER
+#define SBSA_WATCHDOG_NON_SECURE       0
+
+#define SBSA_WATCHDOG_FLAGS            (SBSA_WATCHDOG_NON_SECURE | SBSA_WATCHDOG_ACTIVE_HIGH | SBSA_WATCHDOG_LEVEL_TRIGGERED)
+
+#pragma pack (1)
+
+typedef struct {
+  EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE          Gtdt;
+  EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE                  GtBlock;
+  EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE            Frames[TIMER_FRAMES_COUNT];
+#if (WATCHDOG_COUNT != 0)
+  EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE     Watchdogs[WATCHDOG_COUNT];
+#endif
+} EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES;
+
+#pragma pack ()
+
+EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES Gtdt = {
+  {
+    __ACPI_HEADER (
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES,
+      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
+    ),
+    SYSTEM_TIMER_BASE_ADDRESS,                              // UINT64  CntControlBasePhysicalAddress
+    EFI_ACPI_RESERVED_DWORD,                                // UINT32  Reserved
+    SECURE_TIMER_EL1_GSIV,                                  // UINT32  SecurePL1TimerGSIV
+    GTDT_GTIMER_FLAGS,                                      // UINT32  SecurePL1TimerFlags
+    NON_SECURE_TIMER_EL1_GSIV,                              // UINT32  NonSecurePL1TimerGSIV
+    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL1TimerFlags
+    VIRTUAL_TIMER_GSIV,                                     // UINT32  VirtualTimerGSIV
+    GTDT_GTIMER_FLAGS,                                      // UINT32  VirtualTimerFlags
+    NON_SECURE_EL2_GSIV,                                    // UINT32  NonSecurePL2TimerGSIV
+    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL2TimerFlags
+    CNT_READ_BASE_ADDRESS,                                  // UINT64  CntReadBasePhysicalAddress
+    PLATFORM_TIMER_COUNT,                                   // UINT32  PlatformTimerCount
+    sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE),  // UINT32  PlatformTimerOffset
+  },
+  {
+    EFI_ACPI_6_3_GTDT_GT_BLOCK,                           // UINT8 Type
+    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT16 Length
+      + sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE) *
+        TIMER_FRAMES_COUNT,
+    EFI_ACPI_RESERVED_BYTE,                               // UINT8 Reserved
+    GT_BLOCK_CTL_BASE,                                    // UINT64 CntCtlBase
+    TIMER_FRAMES_COUNT,                                   // UINT32 GTBlockTimerCount
+    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT32 GTBlockTimerOffset
+  },
+  {
+    {
+      0,                                                    // UINT8 GTFrameNumber
+      {EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
+      GT_BLOCK_FRAME0_CTL_BASE,                             // UINT64 CntBaseX
+      GT_BLOCK_FRAME0_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
+      GT_BLOCK_FRAME0_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
+      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
+      0,                                                    // UINT32 GTxVirtualTimerGSIV
+      0,                                                    // UINT32 GTxVirtualTimerFlags
+      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
+    },
+    {
+      1,                                                    // UINT8 GTFrameNumber
+      {EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
+      GT_BLOCK_FRAME1_CTL_BASE,                             // UINT64 CntBaseX
+      GT_BLOCK_FRAME1_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
+      GT_BLOCK_FRAME1_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
+      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
+      0,                                                    // UINT32 GTxVirtualTimerGSIV
+      0,                                                    // UINT32 GTxVirtualTimerFlags
+      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
+    },
+    {
+      2,                                                    // UINT8 GTFrameNumber
+      {EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE,
+       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
+      GT_BLOCK_FRAME2_CTL_BASE,                             // UINT64 CntBaseX
+      GT_BLOCK_FRAME2_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
+      GT_BLOCK_FRAME2_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
+      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
+      0,                                                    // UINT32 GTxVirtualTimerGSIV
+      0,                                                    // UINT32 GTxVirtualTimerFlags
+      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
+    },
+  },
+#if (WATCHDOG_COUNT != 0)
+  {
+    {
+      EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG,                      // UINT8 Type
+      sizeof(EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE),    // UINT16 Length
+      EFI_ACPI_RESERVED_BYTE,                                       // UINT8 Reserved
+      SBSA_WATCHDOG_REFRESH_BASE,                                   // UINT64 RefreshFramePhysicalAddress
+      SBSA_WATCHDOG_CONTROL_BASE,                                   // UINT64 WatchdogControlFramePhysicalAddress
+      SBSA_WATCHDOG_GSIV,                                           // UINT32 WatchdogTimerGSIV
+      SBSA_WATCHDOG_FLAGS                                           // UINT32 WatchdogTimerFlags
+    }
+  }
+#endif
+};
+
+//
+// Reference the table being generated to prevent the optimizer from removing the
+// data structure from the executable
+//
+VOID* CONST ReferenceAcpiTable = &Gtdt;
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
new file mode 100644
index 000000000000..4413428719b8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
@@ -0,0 +1,330 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+[0004]                          Signature : "HEST"    [Hardware Error Source Table]
+[0004]                       Table Length : 00000308
+[0001]                           Revision : 01
+[0001]                           Checksum : 20
+[0006]                             Oem ID : "Ampere"
+[0008]                       Oem Table ID : "Altra   "
+[0004]                       Oem Revision : 00000001
+[0004]                    Asl Compiler ID : "INTL"
+[0004]              Asl Compiler Revision : 20100528
+
+[0004]                 Error Source Count : 00000008
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0000
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200000
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000100000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1D00000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0001
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200008
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 00 [Polled]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000100000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1C00000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0002
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200010
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000100000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1F00000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0006
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200030
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000100000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1900000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0007
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200038
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000100000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1900001
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0003
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200018
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000500000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1D00000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0004
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200020
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 00 [Polled]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000500000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1C00000
+
+[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
+[0002]                          Source Id : 0005
+[0002]                  Related Source Id : FFFF
+[0001]                           Reserved : 00
+[0001]                            Enabled : 01
+[0004]             Records To Preallocate : 00000001
+[0004]            Max Sections Per Record : 00000001
+[0004]                Max Raw Data Length : 00001000
+
+[0012]               Error Status Address : [Generic Address Structure]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000000088200028
+
+[0028]                             Notify : [Hardware Error Notification Structure]
+[0001]                        Notify Type : 03 [SCI]
+[0001]                      Notify Length : 1C
+[0002]         Configuration Write Enable : 0000
+[0004]                       PollInterval : 00000BB8
+[0004]                             Vector : 00000000
+[0004]            Polling Threshold Value : 00000000
+[0004]           Polling Threshold Window : 00000000
+[0004]              Error Threshold Value : 00000000
+[0004]             Error Threshold Window : 00000000
+
+[0004]          Error Status Block Length : 00001000
+
+[0012]                  Read Ack Register : [Generic Address Structure v2]
+[0001]                           Space ID : 00 [SystemMemory]
+[0001]                          Bit Width : 40
+[0001]                         Bit Offset : 00
+[0001]               Encoded Access Width : 04 [QWord Access:64]
+[0008]                            Address : 0000500000543010
+
+[0008]                  Read Ack Preserve : 00000000
+[0008]                     Read Ack Write : B1F00000
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
new file mode 100644
index 000000000000..3c0a048552cf
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
@@ -0,0 +1,17 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+[0004]                          Signature : "SDEI"
+[0004]                       Table Length : 0000003E
+[0001]                           Revision : 01
+[0001]                           Checksum : 59
+[0006]                             Oem ID : "Ampere"
+[0008]                       Oem Table ID : "Altra "
+[0004]                       Oem Revision : 00000001
+[0004]                    Asl Compiler ID : "INTL"
+[0004]              Asl Compiler Revision : 20160930
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
new file mode 100644
index 000000000000..42042f8a3474
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
@@ -0,0 +1,81 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/PcdLib.h>
+#include <Library/AcpiLib.h>
+#include <IndustryStandard/Acpi63.h>
+#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
+#include <AcpiHeader.h>
+
+STATIC EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE Spcr = {
+  __ACPI_HEADER (
+    EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE,
+    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION
+    ),
+  // UINT8                                   InterfaceType;
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART,
+  // UINT8                                   Reserved1[3];
+  {
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE,
+    EFI_ACPI_RESERVED_BYTE
+  },
+  // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  BaseAddress;
+  ARM_GAS32 (FixedPcdGet64 (PcdSerialRegisterBase)),
+  // UINT8                                   InterruptType;
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC,
+  // UINT8                                   Irq;
+  0,                                         // Not used on ARM
+  // UINT32                                  GlobalSystemInterrupt;
+  FixedPcdGet32 (PL011UartInterrupt),
+  // UINT8                                   BaudRate;
+#if (FixedPcdGet64 (PcdUartDefaultBaudRate) == 9600)
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600,
+#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 19200)
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200,
+#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 57600)
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600,
+#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 115200)
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200,
+#else
+#error Unsupported SPCR Baud Rate
+#endif
+  // UINT8                                   Parity;
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY,
+  // UINT8                                   StopBits;
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1,
+  // UINT8                                   FlowControl;
+  0,
+  // UINT8                                   TerminalType;
+  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8,
+  // UINT8                                   Reserved2;
+  EFI_ACPI_RESERVED_BYTE,
+  // UINT16                                  PciDeviceId;
+  0xFFFF,
+  // UINT16                                  PciVendorId;
+  0xFFFF,
+  // UINT8                                   PciBusNumber;
+  0x00,
+  // UINT8                                   PciDeviceNumber;
+  0x00,
+  // UINT8                                   PciFunctionNumber;
+  0x00,
+  // UINT32                                  PciFlags;
+  0x00000000,
+  // UINT8                                   PciSegment;
+  0x00,
+  // UINT32                                  Reserved3;
+  EFI_ACPI_RESERVED_DWORD
+};
+
+//
+// Reference the table being generated to prevent the optimizer from removing the
+// data structure from the executable
+//
+VOID* CONST ReferenceAcpiTable = &Spcr;
diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
new file mode 100755
index 000000000000..cdb4bf5de9bf
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
@@ -0,0 +1,15 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+DefinitionBlock("Ssdt.aml", "SSDT", 2, "Ampere", "Altra   ", 0x00000001)
+{
+    Method (MAIN, 0, NotSerialized)
+    {
+        Return (Zero)
+    }
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (13 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-05  0:05   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
                   ` (19 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provides essential functions to initialize the PCIe Root Complex of
Ampere Altra processor.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                   |    3 +
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc               |    1 +
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf  |   68 ++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h        |  164 +++
 Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h                       |  203 ++++
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h       |  582 +++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h |   64 +
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h  |   30 +
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c       | 1266 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c    |  536 +++++++++
 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c  |  610 ++++++++++
 11 files changed, 3527 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index d5b12a81e9bf..0d79673ce50a 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -37,6 +37,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
   MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
 
+  ##  @libraryclass  Defines a set of methods to initialize Pcie
+  PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h
+
   ##  @libraryclass  Defines a set of methods to access flash memory.
   FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
 
diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 11f50f2f09cd..fc8e0b40ee19 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -83,6 +83,7 @@ [LibraryClasses.common]
   NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
   MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
   SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
+  PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
   AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
   TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
   I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
new file mode 100755
index 000000000000..fe20d4675518
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
@@ -0,0 +1,68 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PcieCoreLib
+  FILE_GUID                      = 8ABFA0FC-313E-11E8-B467-0ED5F89F718B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PcieCoreLib
+
+[Sources]
+  PcieCore.c
+  PcieCore.h
+  PcieCoreCapCfg.h
+  PcieCoreLib.c
+  PciePatchAcpi.c
+  PciePatchAcpi.h
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraBinPkg/AmpereAltraBinPkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[BuildOptions]
+  *_*_*_CC_FLAGS = -Wno-error=switch -Wno-missing-braces
+
+[LibraryClasses]
+  AmpereCpuLib
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  GpioLib
+  IoLib
+  MemoryAllocationLib
+  PcdLib
+  PcieBoardLib
+  PciePhyLib
+  SerialPortLib
+  SystemFirmwareInterfaceLib
+  TimerLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
+
+[Protocols]
+  gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+  gEfiAcpiSdtProtocolGuid # PROTOCOL ALWAYS_CONSUMED
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  gEfiAcpiTableProtocolGuid AND gEfiAcpiSdtProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
new file mode 100644
index 000000000000..99038454f534
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
@@ -0,0 +1,164 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_CORE_LIB_H_
+#define PCI_CORE_LIB_H_
+
+#include <Library/PciHostBridgeLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+/**
+  Get RootBridge disable status.
+
+  @param  HBIndex[In]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[In]           Index to identify of underneath PCIE Root bridge.
+
+  @retval BOOLEAN               Return RootBridge disable status.
+**/
+BOOLEAN
+Ac01PcieCheckRootBridgeDisabled (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  );
+
+/**
+  Prepare to start PCIE core BSP driver
+
+  @param ImageHandle[in]        Handle for the image.
+  @param SystemTable[in]        Address of the system table.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+**/
+EFI_STATUS
+Ac01PcieSetup (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  );
+
+/**
+  Prepare to end PCIE core BSP driver.
+**/
+VOID
+Ac01PcieEnd (
+  VOID
+  );
+
+/**
+  Get Total HostBridge.
+
+  @retval UINTN                 Return Total HostBridge.
+**/
+UINT8
+Ac01PcieGetTotalHBs (
+  VOID
+  );
+
+/**
+  Get Total RootBridge per HostBridge.
+
+  @param  RCIndex[in]           Index to identify of Root Complex.
+
+  @retval UINTN                 Return Total RootBridge per HostBridge.
+**/
+UINT8
+Ac01PcieGetTotalRBsPerHB (
+  IN UINTN RCIndex
+  );
+
+/**
+  Get RootBridge Attribute.
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
+
+  @retval UINTN                 Return RootBridge Attribute.
+**/
+UINTN
+Ac01PcieGetRootBridgeAttribute (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  );
+
+/**
+  Get RootBridge Segment number
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
+
+  @retval UINTN                 Return RootBridge Segment number.
+**/
+UINTN
+Ac01PcieGetRootBridgeSegmentNumber (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  );
+
+/**
+  Initialize Host bridge
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+**/
+EFI_STATUS
+Ac01PcieSetupHostBridge (
+  IN UINTN HBIndex
+  );
+
+/**
+  Initialize Root bridge
+
+  @param  HBIndex[in]            Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]            Index to identify of underneath PCIE Root bridge.
+  @param  RootBridgeInstance[in] The pointer of instance of the Root bridge IO.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+  @retval EFI_DEVICE_ERROR      Error when initializing.
+**/
+EFI_STATUS
+Ac01PcieSetupRootBridge (
+  IN UINTN           HBIndex,
+  IN UINTN           RBIndex,
+  IN PCI_ROOT_BRIDGE *RootBridge
+  );
+
+/**
+  Reads/Writes an PCI configuration register.
+
+  @param  RootInstance[in]      Pointer to RootInstance structure.
+  @param  Address[in]           Address which want to read or write to.
+  @param  Write[in]             Indicate that this is a read or write command.
+  @param  Width[in]             Specify the width of the data.
+  @param  Data[in, out]         The buffer to hold the data.
+
+  @retval EFI_SUCCESS           Read/Write successfully.
+**/
+EFI_STATUS
+Ac01PcieConfigRW (
+  IN     VOID    *RootInstance,
+  IN     UINT64  Address,
+  IN     BOOLEAN Write,
+  IN     UINTN   Width,
+  IN OUT VOID    *Data
+  );
+
+/**
+  Callback funciton for EndEnumeration notification from PCI stack.
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
+  @param  Phase[in]             The phase of enumeration as informed from PCI stack.
+**/
+VOID
+Ac01PcieHostBridgeNotifyPhase (
+  IN UINTN                                         HBIndex,
+  IN UINTN                                         RBIndex,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+  );
+
+#endif /* PCI_CORE_LIB_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h b/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
new file mode 100644
index 000000000000..fb4c8bbbe994
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
@@ -0,0 +1,203 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_H_
+#define PCIE_H_
+
+#define PCIE_CORE_DEBUG
+#define PCIE_CORE_CFG_DEBUG
+#undef PCIE_CORE_MMIO_DEBUG
+
+#ifdef PCIE_CORE_CFG_DEBUG
+#define PCIE_DEBUG_CFG(arg...)               \
+  if (DebugCodeEnabled()) {                  \
+    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
+    DEBUG ((DEBUG_INFO,## arg));             \
+  }
+#else
+#define PCIE_DEBUG_CFG(arg...)
+#endif
+
+#ifdef PCIE_CORE_CSR_DEBUG
+#define PCIE_CSR_DEBUG(arg...)               \
+  if (DebugCodeEnabled()) {                  \
+    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
+    DEBUG((DEBUG_INFO,## arg))               \
+  }
+#else
+#define PCIE_CSR_DEBUG(arg...)
+#endif
+
+#ifdef PCIE_CORE_PHY_DEBUG
+#define PCIE_PHY_DEBUG(arg...)               \
+  if (DebugCodeEnabled()) {                  \
+    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
+    DEBUG ((DEBUG_INFO,## arg))              \
+  }
+#else
+#define PCIE_PHY_DEBUG(arg...)
+#endif
+
+#ifdef PCIE_CORE_DEBUG
+#define PCIE_DEBUG(arg...)                   \
+  if (DebugCodeEnabled()) {                  \
+    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
+    DEBUG ((DEBUG_INFO,## arg));             \
+  }
+#else
+#define PCIE_DEBUG(arg...)
+#endif
+
+#define PCIE_WARN(arg...)                   \
+  DEBUG ((DEBUG_WARN,"PCICore (WARN): "));  \
+  DEBUG ((DEBUG_WARN,## arg))
+
+#define PCIE_ERR(arg...)                      \
+  DEBUG ((DEBUG_ERROR,"PCICore (ERROR): "));  \
+  DEBUG ((DEBUG_ERROR,## arg))
+
+#define RCS_PER_SOCKET          8
+
+#define PCIE_ERRATA_SPEED1      0x0001 // Limited speed errata
+
+#define PRESET_INVALID          0xFF
+
+/* Max number for AC01 PCIE Root Complexes */
+#define MAX_AC01_PCIE_ROOT_COMPLEX   16
+
+/* Max number for AC01 PCIE Root Bridge under each Root Complex */
+#define MAX_AC01_PCIE_ROOT_BRIDGE    1
+
+/* The base address of {TCU, CSR, MMCONFIG} Registers */
+#define AC01_PCIE_REGISTER_BASE    0x33FFE0000000, 0x37FFE0000000, 0x3BFFE0000000, 0x3FFFE0000000, 0x23FFE0000000, 0x27FFE0000000, 0x2BFFE0000000, 0x2FFFE0000000, 0x73FFE0000000, 0x77FFE0000000, 0x7BFFE0000000, 0x7FFFE0000000, 0x63FFE0000000, 0x67FFE0000000, 0x6BFFE0000000, 0x6FFFE0000000
+
+/* The base address of MMIO Registers */
+#define AC01_PCIE_MMIO_BASE        0x300000000000, 0x340000000000, 0x380000000000, 0x3C0000000000, 0x200000000000, 0x240000000000, 0x280000000000, 0x2C0000000000, 0x700000000000, 0x740000000000, 0x780000000000, 0x7C0000000000, 0x600000000000, 0x640000000000, 0x680000000000, 0x6C0000000000
+
+/* The base address of MMIO32 Registers*/
+#define AC01_PCIE_MMIO32_BASE      0x000020000000, 0x000028000000, 0x000030000000, 0x000038000000, 0x000001000000, 0x000008000000, 0x000010000000, 0x000018000000, 0x000060000000, 0x000068000000, 0x000070000000, 0x000078000000, 0x000040000000, 0x000048000000, 0x000050000000, 0x000058000000
+
+/* The base address of MMIO32 Registers */
+#define AC01_PCIE_MMIO32_BASE_1P   0x000040000000, 0x000050000000, 0x000060000000, 0x000070000000, 0x000001000000, 0x000010000000, 0x000020000000, 0x000030000000, 0, 0, 0, 0, 0, 0, 0, 0
+
+/* DSDT RCA2 PCIe Meme32 Attribute */
+#define AC01_PCIE_RCA2_QMEM    0x0000000000000000, 0x0000000060000000, 0x000000006FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+/* DSDT RCA3 PCIe Meme32 Attribute */
+#define AC01_PCIE_RCA3_QMEM    0x0000000000000000, 0x0000000070000000, 0x000000007FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+/* DSDT RCB0 PCIe Meme32 Attribute */
+#define AC01_PCIE_RCB0_QMEM    0x0000000000000000, 0x0000000001000000, 0x000000000FFFFFFF, 0x0000000000000000, 0x000000000F000000
+
+/* DSDT RCB1 PCIe Meme32 Attribute */
+#define AC01_PCIE_RCB1_QMEM    0x0000000000000000, 0x0000000010000000, 0x000000001FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+/* DSDT RCB2 PCIe Meme32 Attribute*/
+#define AC01_PCIE_RCB2_QMEM    0x0000000000000000, 0x0000000020000000, 0x000000002FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+/* DSDT RCB3 PCIe Meme32 Attribute */
+#define AC01_PCIE_RCB3_QMEM    0x0000000000000000, 0x0000000030000000, 0x000000003FFFFFFF, 0x0000000000000000, 0x0000000010000000
+
+/* The start of TBU PMU IRQ array. */
+#define SMMU_TBU_PMU_IRQ_START_ARRAY  224, 230, 236, 242, 160, 170, 180, 190, 544, 550, 556, 562, 480, 490, 500, 510
+
+/* The start of TCU PMU IRQ array */
+#define SMMU_TCU_PMU_IRQ_START_ARRAY  256, 257, 258, 259, 260, 261, 262, 263, 576, 577, 578, 579, 580, 581, 582, 583
+
+enum PCIE_LINK_WIDTH {
+  LNKW_NONE = 0,
+  LNKW_X1 = 0x1,
+  LNKW_X2 = 0x2,
+  LNKW_X4 = 0x4,
+  LNKW_X8 = 0x8,
+  LNKW_X16 = 0x10,
+};
+
+enum PCIE_LINK_SPEED {
+  SPEED_NONE = 0,
+  SPEED_GEN1 = 0x1,
+  SPEED_GEN2 = 0x2,
+  SPEED_GEN3 = 0x4,
+  SPEED_GEN4 = 0x8,
+};
+
+enum PCIE_CONTROLLER {
+  PCIE_0 = 0,
+  PCIE_1,
+  PCIE_2,
+  PCIE_3,
+  PCIE_4,
+  MAX_PCIE_A = PCIE_4,
+  PCIE_5,
+  PCIE_6,
+  PCIE_7,
+  MAX_PCIE,
+  MAX_PCIE_B = MAX_PCIE
+};
+
+enum RC_TYPE {
+  RCA,
+  RCB
+};
+
+enum RC_BLOCK {
+  RCA0 = 0,
+  RCA1,
+  RCA2,
+  RCA3,
+  MAX_RCA,
+  RCB0 = MAX_RCA,
+  RCB1,
+  RCB2,
+  RCB3,
+  MAX_RCB,
+  MAX_RC = MAX_RCB
+};
+
+typedef struct {
+  UINT64  CsrAddr;               // Pointer to CSR Address
+  UINT64  SnpsRamAddr;           // Pointer to Synopsys SRAM address
+  UINT8   MaxGen;                // Max speed Gen-1/-2/-3/-4
+  UINT8   CurGen;                // Current speed Gen-1/-2/-3/-4
+  UINT8   MaxWidth;              // Max lanes x2/x4/x8/x16
+  UINT8   CurWidth;              // Current lanes x2/x4/x8/x16
+  UINT8   ID;                    // ID of the controller within Root Complex
+  UINT8   DevNum;                // Device number as part of Bus:Dev:Func
+  BOOLEAN Active;                // Active? Used in bi-furcation mode
+  BOOLEAN LinkUp;                // PHY and PCIE linkup
+  BOOLEAN HotPlug;               // Hotplug support
+} AC01_PCIE;
+
+typedef struct {
+  UINT64    BaseAddr;
+  UINT64    TcuAddr;
+  UINT64    HBAddr;
+  UINT64    MsgAddr;
+  UINT64    SerdesAddr;
+  UINT64    MmcfgAddr;
+  UINT64    MmioAddr;
+  UINT64    Mmio32Addr;
+  UINT64    IoAddr;
+  AC01_PCIE Pcie[MAX_PCIE_B];
+  UINT8     MaxPcieController;
+  UINT8     Type;
+  UINT8     ID;
+  UINT8     DevMapHi;               // Copy of High Devmap programmed to Host bridge
+  UINT8     DevMapLo;               // Copy of Low Devmap programmed to Host bridge
+  UINT8     DefaultDevMapHi;        // Default of High devmap based on board settings
+  UINT8     DefaultDevMapLo;        // Default of Low devmap based on board settings
+  UINT8     Socket;
+  BOOLEAN   Active;
+  UINT8     Logical;
+  VOID      *RootBridge;            // Pointer to Stack PCI_ROOT_BRIDGE
+  UINT32    Flags;                  // Flags
+  UINT8     PresetGen3[MAX_PCIE_B]; // Preset for Gen3
+  UINT8     PresetGen4[MAX_PCIE_B]; // Preset for Gen4
+} AC01_RC;
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
new file mode 100644
index 000000000000..9dd1627a85d0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
@@ -0,0 +1,582 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIECORE_H_
+#define PCIECORE_H_
+
+#include <IndustryStandard/Pci.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+
+#include "Pcie.h"
+#include "PcieCoreCapCfg.h"
+
+#ifndef BIT
+#define BIT(nr)                         (1 << (nr))
+#endif
+
+#define MAX_REINIT                       3
+#define MAX_RETRAIN                      10
+
+#define LINK_RETRAIN_SUCCESS             0
+#define LINK_RETRAIN_FAILED              -1
+#define LINK_RETRAIN_WRONG_PARAMETER     1
+
+#define AMPERE_PCIE_VENDORID             0x1DEF
+#define AC01_HOST_BRIDGE_DEVICEID_RCA    0xE100
+#define AC01_HOST_BRIDGE_DEVICEID_RCB    0xE110
+#define AC01_PCIE_BRIDGE_DEVICEID_RCA    0xE101
+#define AC01_PCIE_BRIDGE_DEVICEID_RCB    0xE111
+
+#define PCIE_MEMRDY_TIMEOUT     10            // 10 us
+#define PCIE_PIPE_CLOCK_TIMEOUT 20000         // 20,000 us
+#define PCIE_RETRAIN_TRANSITION_TIMEOUT 20000 // 20,000 us
+
+#define LINK_POLL_US_TIMER      1
+#define IO_SPACE                0x2000
+#define MMIO32_SPACE            0x8000000ULL
+#define MMIO_SPACE              0x3FFE0000000ULL
+
+#define TCU_OFFSET              0
+#define HB_CSR_OFFSET           0x01000000
+#define PCIE0_CSR_OFFSET        0x01010000
+#define PCIE1_CSR_OFFSET        0x01020000
+#define PCIE2_CSR_OFFSET        0x01030000
+#define PCIE3_CSR_OFFSET        0x01040000
+#define PCIE4_CSR_OFFSET        0x01010000
+#define PCIE5_CSR_OFFSET        0x01020000
+#define PCIE6_CSR_OFFSET        0x01030000
+#define PCIE7_CSR_OFFSET        0x01040000
+#define SNPSRAM_OFFSET          0x9000
+#define SERDES_CSR_OFFSET       0x01200000
+#define MMCONFIG_OFFSET         0x10000000
+
+
+/* DATA LINK registers */
+#define DLINK_VENDOR_CAP_ID       0x25
+#define DLINK_VSEC                0x80000001
+#define DATA_LINK_FEATURE_CAP_OFF 0X4
+
+/* PL16 CAP registers */
+#define PL16_CAP_ID                     0x26
+#define PL16G_CAP_OFF_20H_REG_OFF       0x20
+#define PL16G_STATUS_REG_OFF            0x0C
+#define PL16G_STATUS_EQ_CPL_GET(val)    (val & 0x1)
+#define PL16G_STATUS_EQ_CPL_P1_GET(val) ((val & 0x2) >> 1)
+#define PL16G_STATUS_EQ_CPL_P2_GET(val) ((val & 0x4) >> 2)
+#define PL16G_STATUS_EQ_CPL_P3_GET(val) ((val & 0x8) >> 3)
+#define DSP_16G_TX_PRESET0_SET(dst,src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
+#define DSP_16G_TX_PRESET1_SET(dst,src) (((dst) & ~0xF00) | (((UINT32) (src) << 8) & 0xF00))
+#define DSP_16G_TX_PRESET2_SET(dst,src) (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
+#define DSP_16G_TX_PRESET3_SET(dst,src) (((dst) & ~0xF000000) | (((UINT32) (src) << 24) & 0xF000000))
+#define DSP_16G_RXTX_PRESET0_SET(dst,src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+#define DSP_16G_RXTX_PRESET1_SET(dst,src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
+#define DSP_16G_RXTX_PRESET2_SET(dst,src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
+#define DSP_16G_RXTX_PRESET3_SET(dst,src) (((dst) & ~0xFF000000) | (((UINT32) (src) << 24) & 0xFF000000))
+
+/* PCIe PF0_PORT_LOGIC registers */
+#define PORT_LOCIG_VC0_P_RX_Q_CTRL_OFF      0x748
+#define PORT_LOCIG_VC0_NP_RX_Q_CTRL_OFF     0x74C
+
+/* TCU registers */
+#define SMMU_GBPA    0x044
+
+/* SNPSRAM Synopsys Memory Read/Write Margin registers */
+#define SPRF_RMR                0x0
+#define SPSRAM_RMR              0x4
+#define TPRF_RMR                0x8
+#define TPSRAM_RMR              0xC
+
+//
+// Host bridge registers
+//
+#define HBRCAPDMR               0x0
+#define HBRCBPDMR               0x4
+#define HBPDVIDR                0x10
+#define HBPRBNR                 0x14
+#define HBPREVIDR               0x18
+#define HBPSIDR                 0x1C
+#define HBPCLSSR                0x20
+
+// HBRCAPDMR
+#define RCAPCIDEVMAP_SET(dst, src) (((dst) & ~0x7) | (((UINT32) (src)) & 0x7))
+#define RCAPCIDEVMAP_GET(val) ((val) & 0x7)
+
+// HBRCBPDMR
+#define RCBPCIDEVMAPLO_SET(dst, src) (((dst) & ~0x7) | (((UINT32) (src)) & 0x7))
+#define RCBPCIDEVMAPLO_GET(val) ((val) & 0x7)
+
+#define RCBPCIDEVMAPHI_SET(dst, src) (((dst) & ~0x70) | (((UINT32) (src) << 4) & 0x70))
+#define RCBPCIDEVMAPHI_GET(val) (((val) & 0x7) >> 4)
+
+// HBPDVIDR
+#define PCIVENDID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src))  & 0xFFFF))
+#define PCIVENDID_GET(val) ((val) & 0xFFFF)
+
+#define PCIDEVID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
+#define PCIDEVID_GET(val) (((val) & 0xFFFF0000) >> 16)
+
+// HBPRBNR
+#define PCIRBNUM_SET(dst, src) (((dst) & ~0x1F) | (((UINT32) (src)) & 0x1F))
+
+// HBPREVIDR
+#define PCIREVID_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+
+// HBPSIDR
+#define PCISUBSYSVENDID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
+
+#define PCISUBSYSID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
+
+// HBPCLSSR
+#define CACHELINESIZE_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+
+//
+// PCIE core register
+//
+#define LINKCTRL                0x0
+#define LINKSTAT                0x4
+#define IRQSEL                  0xC
+#define HOTPLUGSTAT             0x28
+#define IRQENABLE               0x30
+#define IRQEVENTSTAT            0x38
+#define BLOCKEVENTSTAT          0x3c
+#define RESET                   0xC000
+#define CLOCK                   0xC004
+#define MEMRDYR                 0xC104
+#define RAMSDR                  0xC10C
+
+// LINKCTRL
+#define LTSSMENB_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+#define DEVICETYPE_SET(dst, src) (((dst) & ~0xF0) | (((UINT32) (src) << 4) & 0xF0))
+#define DEVICETYPE_GET(val) (((val) & 0xF0) >> 4)
+
+// LINKSTAT
+#define PHY_STATUS_MASK         (1 << 2)
+#define SMLH_LTSSM_STATE_MASK   0x3f00
+#define SMLH_LTSSM_STATE_GET(val) ((val & 0x3F00) >> 8)
+#define RDLH_SMLH_LINKUP_STATUS_GET(val)    (val & 0x3)
+#define PHY_STATUS_MASK_BIT     0x04
+#define SMLH_LINK_UP_MASK_BIT   0x02
+#define RDLH_LINK_UP_MASK_BIT   0x01
+
+// IRQSEL
+#define AER_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+#define PME_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
+#define LINKAUTOBW_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
+#define BWMGMT_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << 3) & 0x8))
+#define EQRQST_SET(dst, src) (((dst) & ~0x10) | (((UINT32) (src) << 4) & 0x10))
+#define INTPIN_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
+
+// SLOTCAP
+#define SLOT_HPC_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
+
+// HOTPLUGSTAT
+#define PWR_IND_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+#define ATTEN_IND_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
+#define PWR_CTRL_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
+#define EML_CTRL_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << 3) & 0x8))
+
+// IRQENABLE
+#define LINKUP_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
+
+// IRQEVENTSTAT
+#define BLOCK_INT_MASK          (1 << 4)
+#define PCIE_INT_MASK           (1 << 3)
+
+// BLOCKEVENTSTAT
+#define LINKUP_MASK             (1 << 0)
+
+// RESET
+#define DWCPCIE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+#define RESET_MASK              0x1
+
+// CLOCK
+#define AXIPIPE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+// RAMSDR
+#define SD_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+//
+// PHY registers
+//
+#define RSTCTRL                 0x0
+#define PHYCTRL                 0x4
+#define RAMCTRL                 0x8
+#define RAMSTAT                 0xC
+#define PLLCTRL                 0x10
+#define PHYLPKCTRL              0x14
+#define PHYTERMOFFSET0          0x18
+#define PHYTERMOFFSET1          0x1C
+#define PHYTERMOFFSET2          0x20
+#define PHYTERMOFFSET3          0x24
+#define RXTERM                  0x28
+#define PHYDIAGCTRL             0x2C
+
+// RSTCTRL
+#define PHY_RESET_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+// PHYCTRL
+#define PWR_STABLE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+//
+// PCIe config space registers
+//
+#define TYPE1_DEV_ID_VEND_ID_REG                0
+#define TYPE1_CLASS_CODE_REV_ID_REG             0x8
+#define TYPE1_CAP_PTR_REG                       0x34
+#define SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG       0x18
+#define BRIDGE_CTRL_INT_PIN_INT_LINE_REG        0x3c
+#define CON_STATUS_REG                          (PM_CAP + 0x4)
+#define LINK_CAPABILITIES_REG                   (PCIE_CAP + 0xc)
+#define LINK_CONTROL_LINK_STATUS_REG            (PCIE_CAP + 0x10)
+#define SLOT_CAPABILITIES_REG                   (PCIE_CAP + 0x14)
+#define DEVICE_CONTROL2_DEVICE_STATUS2_REG      (PCIE_CAP + 0x28)
+#define LINK_CAPABILITIES2_REG                  (PCIE_CAP + 0x2c)
+#define LINK_CONTROL2_LINK_STATUS2_REG          (PCIE_CAP + 0x30)
+#define UNCORR_ERR_STATUS_OFF                   (AER_CAP + 0x4)
+#define UNCORR_ERR_MASK_OFF                     (AER_CAP + 0x8)
+#define RESOURCE_CON_REG_VC0                    (VC_CAP + 0x14)
+#define RESOURCE_CON_REG_VC1                    (VC_CAP + 0x20)
+#define RESOURCE_STATUS_REG_VC1                 (VC_CAP + 0x24)
+#define SD_CONTROL1_REG                         (RAS_DES_CAP+0xA0)
+#define CCIX_TP_CAP_TP_HDR2_OFF                 (CCIX_TP_CAP + 0x8)
+#define ESM_MNDTRY_RATE_CAP_OFF                 (CCIX_TP_CAP + 0xc)
+#define ESM_STAT_OFF                            (CCIX_TP_CAP + 0x14)
+#define ESM_CNTL_OFF                            (CCIX_TP_CAP + 0x18)
+#define ESM_LN_EQ_CNTL_25G_0_OFF                (CCIX_TP_CAP + 0x2c)
+#define PORT_LINK_CTRL_OFF                      0x710
+#define FILTER_MASK_2_OFF                       0x720
+#define GEN2_CTRL_OFF                           0x80c
+#define GEN3_RELATED_OFF                        0x890
+#define GEN3_EQ_CONTROL_OFF                     0x8A8
+#define MISC_CONTROL_1_OFF                      0x8bc
+#define AMBA_ERROR_RESPONSE_DEFAULT_OFF         0x8d0
+#define AMBA_LINK_TIMEOUT_OFF                   0x8d4
+#define AMBA_ORDERING_CTRL_OFF                  0x8d8
+#define DTIM_CTRL0_OFF                          0xab0
+#define AUX_CLK_FREQ_OFF                        0xb40
+#define CCIX_CTRL_OFF                           0xc20
+
+#define DEV_MASK 0x00F8000
+#define BUS_MASK 0xFF00000
+#define BUS_NUM(Addr) ((((UINT64)(Addr)) & BUS_MASK) >> 20)
+#define DEV_NUM(Addr) ((((UINT64)(Addr)) & DEV_MASK) >> 15)
+#define CFG_REG(Addr) (((UINT64)Addr) & 0x7FFF)
+
+// TYPE1_DEV_ID_VEND_ID_REG
+#define VENDOR_ID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
+#define DEVICE_ID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
+
+// TYPE1_CLASS_CODE_REV_ID_REG
+#define BASE_CLASS_CODE_SET(dst, src) (((dst) & ~0xFF000000) | (((UINT32) (src) << 24) & 0xFF000000))
+#define SUBCLASS_CODE_SET(dst, src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
+#define PROGRAM_INTERFACE_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
+#define REVISION_ID_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+
+// SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG
+#define SUB_BUS_SET(dst, src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
+#define SEC_BUS_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
+#define PRIM_BUS_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+
+// BRIDGE_CTRL_INT_PIN_INT_LINE_REG
+#define INT_PIN_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
+
+// CON_STATUS_REG
+#define POWER_STATE_SET(dst, src) (((dst) & ~0x3) | (((UINT32) (src)) & 0x3))
+
+// DEVICE_CONTROL2_DEVICE_STATUS2_REG
+#define PCIE_CAP_CPL_TIMEOUT_VALUE_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
+
+// LINK_CAPABILITIES_REG
+#define PCIE_CAP_ID                             0x10
+#define LINK_CAPABILITIES_REG_OFF               0xC
+#define LINK_CONTROL_LINK_STATUS_OFF            0x10
+#define PCIE_CAP_MAX_LINK_WIDTH_X1              0x1
+#define PCIE_CAP_MAX_LINK_WIDTH_X2              0x2
+#define PCIE_CAP_MAX_LINK_WIDTH_X4              0x4
+#define PCIE_CAP_MAX_LINK_WIDTH_X8              0x8
+#define PCIE_CAP_MAX_LINK_WIDTH_X16             0x10
+#define PCIE_CAP_MAX_LINK_WIDTH_GET(val) ((val & 0x3F0) >> 4)
+#define PCIE_CAP_MAX_LINK_WIDTH_SET(dst, src) (((dst) & ~0x3F0) | (((UINT32) (src) << 4) & 0x3F0))
+#define MAX_LINK_SPEED_25                       0x1
+#define MAX_LINK_SPEED_50                       0x2
+#define MAX_LINK_SPEED_80                       0x3
+#define MAX_LINK_SPEED_160                      0x4
+#define MAX_LINK_SPEED_320                      0x5
+#define PCIE_CAP_MAX_LINK_SPEED_GET(val) ((val & 0xF))
+#define PCIE_CAP_MAX_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
+#define PCIE_CAP_SLOT_CLK_CONFIG_SET(dst, src) (((dst) & ~0x10000000) | (((UINT32) (src) << 28) & 0x10000000))
+#define NO_ASPM_SUPPORTED                       0x0
+#define L0S_SUPPORTED                           0x1
+#define L1_SUPPORTED                            0x2
+#define L0S_L1_SUPPORTED                        0x3
+#define PCIE_CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET(dst, src) (((dst) & ~0xC00) | (((UINT32)(src) << 10) & 0xC00))
+
+// LINK_CONTROL_LINK_STATUS_REG
+#define PCIE_CAP_DLL_ACTIVE_GET(val) ((val & 0x20000000) >> 29)
+#define PCIE_CAP_NEGO_LINK_WIDTH_GET(val) ((val & 0x3F00000) >> 20)
+#define PCIE_CAP_LINK_SPEED_GET(val) ((val & 0xF0000) >> 16)
+#define PCIE_CAP_LINK_SPEED_SET(dst, src) (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
+#define CAP_LINK_SPEED_TO_VECTOR(val)          BIT((val)-1)
+#define PCIE_CAP_EN_CLK_POWER_MAN_GET(val) ((val & 0x100) >> 8)
+#define PCIE_CAP_EN_CLK_POWER_MAN_SET(dst, src) (((dst) & ~0x100) | (((UINT32) (src) << 8) & 0x100))
+#define PCIE_CAP_RETRAIN_LINK_SET(dst, src) (((dst) & ~0x20) | (((UINT32) (src) << 5) & 0x20))
+#define PCIE_CAP_COMMON_CLK_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
+#define PCIE_CAP_LINK_TRAINING_GET(val)     ((val & 0x8000000) >> 27)
+
+// LINK_CAPABILITIES2_REG
+#define LINK_SPEED_VECTOR_25                    BIT(0)
+#define LINK_SPEED_VECTOR_50                    BIT(1)
+#define LINK_SPEED_VECTOR_80                    BIT(2)
+#define LINK_SPEED_VECTOR_160                   BIT(3)
+#define LINK_SPEED_VECTOR_320                   BIT(4)
+#define PCIE_CAP_SUPPORT_LINK_SPEED_VECTOR_GET(val) ((val & 0xFE) >> 1)
+#define PCIE_CAP_SUPPORT_LINK_SPEED_VECTOR_SET(dst, src) (((dst) & ~0xFE) | (((UINT32) (src) << 1) & 0xFE))
+#define PCIE_CAP_EQ_CPL_GET(val)        ((val & 0x20000) >> 17)
+#define PCIE_CAP_EQ_CPL_P1_GET(val)     ((val & 0x40000) >> 18)
+#define PCIE_CAP_EQ_CPL_P2_GET(val)     ((val & 0x80000) >> 19)
+#define PCIE_CAP_EQ_CPL_P3_GET(val)     ((val & 0x100000) >> 20)
+
+// LINK_CONTROL2_LINK_STATUS2_REG
+#define PCIE_CAP_TARGET_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
+
+// Secondary Capability
+#define SPCIE_CAP_ID                0x19
+#define CAP_OFF_0C                  0x0C
+#define LINK_CONTROL3_REG_OFF       0x4
+#define DSP_TX_PRESET0_SET(dst,src)  (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
+#define DSP_TX_PRESET1_SET(dst,src)  (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
+
+// UNCORR_ERR_STATUS_OFF
+#define CMPLT_TIMEOUT_ERR_STATUS_GET(val) ((val & 0x4000) >> 14)
+#define CMPLT_TIMEOUT_ERR_STATUS_SET(dst, src) (((dst) & ~0x4000) | (((UINT32) (src) << 14) & 0x4000))
+
+// UNCORR_ERR_MASK_OFF
+#define CMPLT_TIMEOUT_ERR_MASK_SET(dst, src) (((dst) & ~0x4000) | (((UINT32) (src) << 14) & 0x4000))
+#define SDES_ERR_MASK_SET(dst, src) (((dst) & ~0x20) | (((UINT32)(src) << 5) & 0x20))
+
+// RESOURCE_STATUS_REG_VC1
+#define VC_NEGO_PENDING_VC1_GET(val) ((val & 0x20000) >> 17)
+
+// SD_CONTROL1_REG
+#define FORCE_DETECT_LANE_EN_SET(dst, src) (((dst) & ~0x10000) | (((UINT32) (src) << 16) & 0x10000))
+
+// CCIX_TP_CAP_TP_HDR2_OFF
+#define ESM_REACH_LENGTH_GET(val) ((val & 0x60000) >> 17)
+#define ESM_CALIBRATION_TIME_GET(val) ((val & 0x700000) >> 20)
+#define ESM_CALIBRATION_TIME_SET(dst, src) (((dst) & ~0x700000) | (((UINT32) (src) << 20) & 0x700000))
+
+// ESM_STAT_OFF
+#define ESM_CALIB_CMPLT_GET(val) ((val & 0x80) >> 7)
+#define ESM_CURNT_DATA_RATE_GET(val) ((val & 0x7F) >> 0)
+
+// ESM_CNTL_OFF
+#define QUICK_EQ_TIMEOUT_SET(dst, src) (((dst) & ~0x1C000000) | (((UINT32) (src) << 26) & 0x1C000000))
+#define LINK_REACH_TARGET_GET(val) ((val & 0x1000000) >> 24)
+#define LINK_REACH_TARGET_SET(dst, src) (((dst) & ~0x1000000) | (((UINT32) (src) << 24) & 0x1000000))
+#define ESM_EXT_EQ3_DSP_TIMEOUT_GET(val) ((val & 0x700000) >> 20)
+#define ESM_EXT_EQ3_DSP_TIMEOUT_SET(dst, src) (((dst) & ~0x700000) | (((UINT32) (src) << 20) & 0x700000))
+#define ESM_EXT_EQ2_USP_TIMEOUT_GET(val) ((val & 0x70000) >> 16)
+#define ESM_EXT_EQ2_USP_TIMEOUT_SET(dst, src) (((dst) & ~0x70000) | (((UINT32) (src) << 16) & 0x70000))
+#define ESM_ENABLE_SET(dst, src) (((dst) & ~0x8000) | (((UINT32) (src) << 15) & 0x8000))
+#define ESM_DATA_RATE1_SET(dst, src) (((dst) & ~0x7F00) | (((UINT32) (src) << 8) & 0x7F00))
+#define ESM_PERFORM_CAL_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
+#define ESM_DATA_RATE0_SET(dst, src) (((dst) & ~0x7F) | (((UINT32) (src)) & 0x7F))
+
+// PORT_LINK_CTRL_OFF
+#define LINK_CAPABLE_X1                 0x1
+#define LINK_CAPABLE_X2                 0x3
+#define LINK_CAPABLE_X4                 0x7
+#define LINK_CAPABLE_X8                 0xF
+#define LINK_CAPABLE_X16                0x1F
+#define LINK_CAPABLE_X32                0x3F
+#define LINK_CAPABLE_SET(dst, src) (((dst) & ~0x3F0000) | (((UINT32) (src) << 16) & 0x3F0000))
+#define FAST_LINK_MODE_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
+
+// FILTER_MASK_2_OFF
+#define CX_FLT_MASK_VENMSG0_DROP_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+#define CX_FLT_MASK_VENMSG1_DROP_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
+#define CX_FLT_MASK_DABORT_4UCPL_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
+
+// GEN2_CTRL_OFF
+#define NUM_OF_LANES_X2                 0x2
+#define NUM_OF_LANES_X4                 0x4
+#define NUM_OF_LANES_X8                 0x8
+#define NUM_OF_LANES_X16                0x10
+#define NUM_OF_LANES_SET(dst, src) (((dst) & ~0x1F00) | (((UINT32) (src) << 8) & 0x1F00))
+
+// GEN3_RELATED_OFF
+#define RATE_SHADOW_SEL_SET(dst, src) (((dst) & ~0x3000000) | (((UINT32) (src) << 24) & 0x3000000))
+#define EQ_PHASE_2_3_SET(dst, src) (((dst) & ~0x200) | (((UINT32) (src) << 9) & 0x200))
+#define RXEQ_REGRDLESS_SET(dst, src) (((dst) & ~0x2000) | (((UINT32) (src) << 13) & 0x2000))
+
+// GEN3_EQ_CONTROL_OFF
+#define GEN3_EQ_FB_MODE(dst, src) (((dst) & ~0xF) | ((UINT32) (src) & 0xF))
+#define GEN3_EQ_PRESET_VEC(dst, src) (((dst) & 0xFF0000FF) | (((UINT32) (src) << 8) & 0xFFFF00))
+#define GEN3_EQ_INIT_EVAL(dst,src) (((dst) & ~0x1000000) | (((UINT32) (src) << 24) & 0x1000000))
+
+// MISC_CONTROL_1_OFF
+#define DBI_RO_WR_EN_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+// AMBA_ERROR_RESPONSE_DEFAULT_OFF
+#define AMBA_ERROR_RESPONSE_CRS_SET(dst, src) (((dst) & ~0x18) | (((UINT32) (src) << 3) & 0x18))
+#define AMBA_ERROR_RESPONSE_GLOBAL_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
+
+// AMBA_LINK_TIMEOUT_OFF
+#define LINK_TIMEOUT_PERIOD_DEFAULT_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
+
+// AMBA_ORDERING_CTRL_OFF
+#define AX_MSTR_ZEROLREAD_FW_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
+
+// DTIM_CTRL0_OFF
+#define DTIM_CTRL0_ROOT_PORT_ID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
+
+// AUX_CLK_FREQ_OFF
+#define AUX_CLK_500MHZ 500
+#define AUX_CLK_FREQ_SET(dst, src) (((dst) & ~0x1FF) | (((UINT32) (src)) & 0x1FF))
+
+#define EXT_CAP_OFFSET_START 0x100
+
+enum LTSSM_STATE {
+  S_DETECT_QUIET = 0,
+  S_DETECT_ACT,
+  S_POLL_ACTIVE,
+  S_POLL_COMPLIANCE,
+  S_POLL_CONFIG,
+  S_PRE_DETECT_QUIET,
+  S_DETECT_WAIT,
+  S_CFG_LINKWD_START,
+  S_CFG_LINKWD_ACEPT,
+  S_CFG_LANENUM_WAI,
+  S_CFG_LANENUM_ACEPT,
+  S_CFG_COMPLETE,
+  S_CFG_IDLE,
+  S_RCVRY_LOCK,
+  S_RCVRY_SPEED,
+  S_RCVRY_RCVRCFG,
+  S_RCVRY_IDLE,
+  S_L0,
+  S_L0S,
+  S_L123_SEND_EIDLE,
+  S_L1_IDLE,
+  S_L2_IDLE,
+  S_L2_WAKE,
+  S_DISABLED_ENTRY,
+  S_DISABLED_IDLE,
+  S_DISABLED,
+  S_LPBK_ENTRY,
+  S_LPBK_ACTIVE,
+  S_LPBK_EXIT,
+  S_LPBK_EXIT_TIMEOUT,
+  S_HOT_RESET_ENTRY,
+  S_HOT_RESET,
+  S_RCVRY_EQ0,
+  S_RCVRY_EQ1,
+  S_RCVRY_EQ2,
+  S_RCVRY_EQ3,
+  MAX_LTSSM_STATE
+};
+
+INT32
+Ac01PcieCfgOut32 (
+  VOID   *Addr,
+  UINT32 Val
+  );
+
+INT32
+Ac01PcieCfgOut16 (
+  VOID   *Addr,
+  UINT16 Val
+  );
+
+INT32
+Ac01PcieCfgOut8 (
+  VOID  *Addr,
+  UINT8 Val
+  );
+
+INT32
+Ac01PcieCfgIn32 (
+  VOID   *Addr,
+  UINT32 *Val
+  );
+
+INT32
+Ac01PcieCfgIn16 (
+  VOID   *Addr,
+  UINT16 *Val
+  );
+
+INT32
+Ac01PcieCfgIn8 (
+  VOID  *Addr,
+  UINT8 *Val
+  );
+
+INT32
+Ac01PcieCoreSetup (
+  AC01_RC *RC
+  );
+
+VOID
+Ac01PcieCoreResetPort (
+  AC01_RC *RC
+  );
+
+VOID
+Ac01PcieClearConfigPort (
+  AC01_RC *RC
+  );
+
+AC01_RC *
+GetRCList (
+  UINT8 Idx
+  );
+
+VOID
+Ac01PcieCoreBuildRCStruct (
+  AC01_RC *RC,
+  UINT64  RegBase,
+  UINT64  MmioBase,
+  UINT64  Mmio32Base
+  );
+
+INT32
+Ac01PcieCoreSetupRC (
+  IN AC01_RC *RC,
+  IN UINT8   ReInit,
+  IN UINT8   ReInitPcieIndex
+  );
+
+VOID
+Ac01PcieCoreUpdateLink (
+  IN  AC01_RC *RC,
+  OUT BOOLEAN *IsNextRoundNeeded,
+  OUT INT8    *FailedPciePtr,
+  OUT INT8    *FailedPcieCount
+  );
+
+VOID
+Ac01PcieCoreEndEnumeration (
+  AC01_RC *RC
+  );
+
+INT32
+Ac01PcieCoreQoSLinkCheckRecovery (
+  IN AC01_RC *RC,
+  IN INTN    PcieIndex
+  );
+
+#endif /* PCIECORE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
new file mode 100755
index 000000000000..0da47cb4e9d3
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
@@ -0,0 +1,64 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef X16_CAP_PORT_CFG_H_
+#define X16_CAP_PORT_CFG_H_
+
+
+/* PCIe config space capabilities offset */
+#define PM_CAP          0x40
+#define MSI_CAP         0x50
+#define PCIE_CAP        0x70
+#define MSIX_CAP        0xB0
+#define SLOT_CAP        0xC0
+#define VPD_CAP         0xD0
+#define SATA_CAP        0xE0
+#define CFG_NEXT_CAP    0x40
+#define PM_NEXT_CAP     0x70
+#define MSI_NEXT_CAP    0x00
+#define PCIE_NEXT_CAP   0x00
+#define MSIX_NEXT_CAP   0x00
+#define SLOT_NEXT_CAP   0x00
+#define VPD_NEXT_CAP    0x00
+#define SATA_NEXT_CAP   0x00
+#define BASE_CAP        0x100
+#define AER_CAP         0x100
+#define VC_CAP          0x148
+#define SN_CAP          0x178
+#define PB_CAP          0x178
+#define ARI_CAP         0x178
+#define SPCIE_CAP_x8    0x148
+#define SPCIE_CAP       0x178
+#define PL16G_CAP       0x1A8
+#define MARGIN_CAP      0x1D8
+#define PL32G_CAP       0x220
+#define SRIOV_CAP       0x220
+#define TPH_CAP         0x220
+#define ATS_CAP         0x220
+#define ACS_CAP         0x230
+#define PRS_CAP         0x238
+#define LTR_CAP         0x248
+#define L1SUB_CAP       0x248
+#define PASID_CAP       0x248
+#define DPA_CAP         0x248
+#define DPC_CAP         0x248
+#define MPCIE_CAP       0x248
+#define FRSQ_CAP        0x248
+#define RTR_CAP         0x248
+#define LN_CAP          0x248
+#define RAS_DES_CAP     0x248
+#define VSECRAS_CAP     0x348
+#define DLINK_CAP       0x380
+#define PTM_CAP         0x38C
+#define PTM_VSEC_CAP    0x38C
+#define CCIX_TP_CAP     0x38C
+#define CXS_CAP         0x3D0
+#define RBAR_CAP        0x3E8
+#define VF_RBAR_CAP     0x3E8
+
+#endif /* X16_CAP_PORT_CFG_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
new file mode 100755
index 000000000000..c9356f658778
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
@@ -0,0 +1,30 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIEPATCHACPI_H_
+#define PCIEPATCHACPI_H_
+
+EFI_STATUS
+EFIAPI
+AcpiPatchPciMem32 (
+  INT8 *PciSegEnabled
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiInstallMcfg (
+  INT8 *PciSegEnabled
+  );
+
+EFI_STATUS
+EFIAPI
+AcpiInstallIort (
+  INT8 *PciSegEnabled
+  );
+
+#endif /* PCIEPATCHACPI_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
new file mode 100644
index 000000000000..a798d995ba9d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
@@ -0,0 +1,1266 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcieBoardLib.h>
+#include <Library/PciePhyLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <PlatformInfoHob.h>
+
+#include "Pcie.h"
+#include "PcieCore.h"
+
+#define DEV_MASK 0x00F8000
+#define BUS_MASK 0xFF00000
+
+STATIC INT32
+Ac01PcieCsrOut32 (
+  VOID   *Addr,
+  UINT32 Val
+  )
+{
+  MmioWrite32 ((UINT64)Addr, Val);
+  PCIE_CSR_DEBUG (
+    "PCIE CSR WR: 0x%p value: 0x%08X (0x%08X)\n",
+    Addr,
+    Val,
+    MmioRead32 ((UINT64)Addr)
+    );
+
+  return 0;
+}
+
+STATIC INT32
+Ac01PcieCsrOut32Serdes (
+  VOID   *Addr,
+  UINT32 Val
+  )
+{
+  MmioWrite32 ((UINT64)Addr, Val);
+  PCIE_CSR_DEBUG (
+    "PCIE CSR WR: 0x%p value: 0x%08X (0x%08X)\n",
+    Addr,
+    Val,
+    MmioRead32 ((UINT64)Addr)
+    );
+
+  return 0;
+}
+
+STATIC INT32
+Ac01PcieCsrIn32 (
+  VOID   *Addr,
+  UINT32 *Val
+  )
+{
+  *Val = MmioRead32 ((UINT64)Addr);
+  PCIE_CSR_DEBUG ("PCIE CSR RD: 0x%p value: 0x%08X\n", Addr, *Val);
+
+  return 0;
+}
+
+STATIC INT32
+Ac01PcieCsrIn32Serdes (
+  VOID   *Addr,
+  UINT32 *Val
+  )
+{
+  *Val = MmioRead32 ((UINT64)Addr);
+  PCIE_CSR_DEBUG ("PCIE CSR RD: 0x%p value: 0x%08X\n", Addr, *Val);
+
+  return 0;
+}
+
+VOID
+Ac01PcieMmioRd (
+  UINT64 Addr,
+  UINT32 *Val
+  )
+{
+  Ac01PcieCsrIn32Serdes ((VOID *)Addr, (UINT32 *)Val);
+}
+
+VOID
+Ac01PcieMmioWr (
+  UINT64 Addr,
+  UINT32 Val
+  )
+{
+  Ac01PcieCsrOut32Serdes ((VOID *)Addr, (UINT32)Val);
+}
+
+VOID
+Ac01PciePuts (
+  CONST CHAR8 *Msg
+  )
+{
+  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
+}
+
+VOID
+Ac01PciePutInt (
+  UINT32 val
+  )
+{
+  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
+}
+
+VOID
+Ac01PciePutHex (
+  UINT64 val
+  )
+{
+  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
+}
+
+INT32
+Ac01PcieDebugPrint (
+  CONST CHAR8 *fmt,
+  ...
+  )
+{
+  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
+  return 0;
+}
+
+VOID
+Ac01PcieDelay (
+  UINT32 Val
+  )
+{
+  MicroSecondDelay (Val);
+}
+
+/**
+   Write 32-bit value to config space address
+
+   @param Addr          Address within config space
+   @param Val           32-bit value to write
+**/
+INT32
+Ac01PcieCfgOut32 (
+  IN VOID   *Addr,
+  IN UINT32 Val
+  )
+{
+  MmioWrite32 ((UINT64)Addr, Val);
+  PCIE_DEBUG_CFG (
+    "PCIE CFG WR: 0x%p value: 0x%08X (0x%08X)\n",
+    Addr,
+    Val,
+    MmioRead32 ((UINT64)Addr)
+    );
+
+  return 0;
+}
+
+/**
+   Write 16-bit value to config space address
+
+   @param Addr          Address within config space
+   @param Val           16-bit value to write
+**/
+INT32
+Ac01PcieCfgOut16 (
+  IN VOID   *Addr,
+  IN UINT16 Val
+  )
+{
+  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
+  UINT32 Val32  = MmioRead32 (AlignedAddr);
+
+  switch ((UINT64)Addr & 0x3) {
+  case 2:
+    Val32 &= ~0xFFFF0000;
+    Val32 |= (UINT32)Val << 16;
+    break;
+
+  case 0:
+  default:
+    Val32 &= ~0xFFFF;
+    Val32 |= Val;
+    break;
+  }
+  MmioWrite32 (AlignedAddr, Val32);
+  PCIE_DEBUG_CFG (
+    "PCIE CFG WR16: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
+    Addr,
+    Val,
+    AlignedAddr,
+    MmioRead32 ((UINT64)AlignedAddr)
+    );
+
+  return 0;
+}
+
+/**
+   Write 8-bit value to config space address
+
+   @param Addr          Address within config space
+   @param Val           8-bit value to write
+**/
+INT32
+Ac01PcieCfgOut8 (
+  IN VOID  *Addr,
+  IN UINT8 Val
+  )
+{
+  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
+  UINT32 Val32  = MmioRead32 (AlignedAddr);
+
+  switch ((UINT64)Addr & 0x3) {
+  case 0:
+    Val32 &= ~0xFF;
+    Val32 |= Val;
+    break;
+
+  case 1:
+    Val32 &= ~0xFF00;
+    Val32 |= (UINT32)Val << 8;
+    break;
+
+  case 2:
+    Val32 &= ~0xFF0000;
+    Val32 |= (UINT32)Val << 16;
+    break;
+
+  case 3:
+  default:
+    Val32 &= ~0xFF000000;
+    Val32 |= (UINT32)Val << 24;
+    break;
+  }
+  MmioWrite32 (AlignedAddr, Val32);
+  PCIE_DEBUG_CFG (
+    "PCIE CFG WR8: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
+    Addr,
+    Val,
+    AlignedAddr,
+    MmioRead32 ((UINT64)AlignedAddr)
+    );
+
+  return 0;
+}
+
+/**
+   Read 32-bit value from config space address
+
+   @param Addr          Address within config space
+   @param Val           Point to address for read value
+**/
+INT32
+Ac01PcieCfgIn32 (
+  IN  VOID   *Addr,
+  OUT UINT32 *Val
+  )
+{
+  UINT32 RegC, Reg18;
+  UINT8  MfHt, Primary = 0, Sec = 0, Sub = 0;
+
+  if ((BUS_NUM (Addr) > 0) && (DEV_NUM (Addr) > 0) && (CFG_REG (Addr) == 0)) {
+    *Val = MmioRead32 ((UINT64)Addr);
+    PCIE_DEBUG_CFG (
+      "PCIE CFG RD: B%X|D%X 0x%p value: 0x%08X\n",
+      BUS_NUM (Addr),
+      DEV_NUM (Addr),
+      Addr,
+      *Val
+      );
+
+    if (*Val != 0xffffffff) {
+      RegC = MmioRead32 ((UINT64)Addr + 0xC);
+      PCIE_DEBUG_CFG ("Peek PCIE MfHt RD32: 0x%p value: 0x%08X\n", Addr + 0xc, RegC);
+      MfHt = RegC >> 16;
+      PCIE_DEBUG_CFG ("  Peek RD8 MfHt=0x%02X\n", MfHt);
+
+      if ((MfHt & 0x7F)!= 0) { /* Type 1 header */
+        Reg18 = MmioRead32 ((UINT64)Addr + 0x18);
+        Primary = Reg18; Sec = Reg18 >> 8; Sub = Reg18 >> 16;
+        PCIE_DEBUG_CFG (
+          "  Bus Peek PCIE Sub:%01X Sec:%01X Primary:%01X  RD: 0x%p value: 0x%08X\n",
+          Sub,
+          Sec,
+          Primary,
+          Addr + 0x18,
+          Reg18
+          );
+      }
+      if ((MfHt == 0) || (Primary != 0)) { /* QS RPs Primary Bus is 0b */
+        *Val = 0xffffffff;
+        PCIE_DEBUG_CFG (
+          "  Skip RD32 B%X|D%X PCIE CFG RD: 0x%p return 0xffffffff\n",
+          BUS_NUM (Addr),
+          DEV_NUM (Addr),
+          Addr
+          );
+      }
+    }
+  } else {
+    *Val = MmioRead32 ((UINT64)Addr);
+  }
+  PCIE_DEBUG_CFG ("PCIE CFG RD: 0x%p value: 0x%08X\n", Addr, *Val);
+
+  return 0;
+}
+
+/**
+   Read 16-bit value from config space address
+
+   @param Addr          Address within config space
+   @param Val           Point to address for read value
+**/
+INT32
+Ac01PcieCfgIn16 (
+  IN  VOID   *Addr,
+  OUT UINT16 *Val
+  )
+{
+  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
+  UINT32 RegC, Reg18;
+  UINT8  MfHt, Primary = 0, Sec = 0, Sub = 0;
+  UINT32 Val32;
+
+  if ((BUS_NUM (Addr) > 0) && (DEV_NUM (Addr) > 0) && (CFG_REG (Addr) == 0)) {
+    *Val = MmioRead32 ((UINT64)Addr);
+    PCIE_DEBUG_CFG (
+      "PCIE CFG16 RD: B%X|D%X 0x%p value: 0x%08X\n",
+      BUS_NUM (Addr),
+      DEV_NUM (Addr),
+      Addr,
+      *Val
+      );
+
+    if (*Val != 0xffff) {
+      RegC = MmioRead32 ((UINT64)Addr + 0xC);
+      PCIE_DEBUG_CFG ("  Peek PCIE MfHt RD: 0x%p value: 0x%08X\n", Addr + 0xc, RegC);
+      MfHt = RegC >> 16;
+      PCIE_DEBUG_CFG ("  Peek RD8 MfHt=0x%02X\n", MfHt);
+
+
+      if ((MfHt & 0x7F)!= 0) { /* Type 1 header */
+        Reg18 = MmioRead32 ((UINT64)Addr + 0x18);
+        Primary = Reg18; Sec = Reg18 >> 8; Sub = Reg18 >> 16;
+        PCIE_DEBUG_CFG (
+          "  Bus Peek PCIE Sub:%01X Sec:%01X Primary:%01X  RD: 0x%p value: 0x%08X\n",
+          Sub,
+          Sec,
+          Primary,
+          Addr + 0x18,
+          Reg18
+          );
+      }
+      if ((MfHt == 0) || (Primary != 0)) { /* QS RPs Primary Bus is 0b */
+        *Val = 0xffff;
+        PCIE_DEBUG_CFG (
+          "  Skip RD16 B%X|D%X PCIE CFG RD: 0x%p return 0xffff\n",
+          BUS_NUM (Addr),
+          DEV_NUM (Addr),
+          Addr
+          );
+        return 0;
+      }
+    }
+  }
+
+  Val32 = MmioRead32 (AlignedAddr);
+  switch ((UINT64)Addr & 0x3) {
+  case 2:
+    *Val = Val32 >> 16;
+    break;
+
+  case 0:
+  default:
+    *Val = Val32;
+    break;
+  }
+  PCIE_DEBUG_CFG (
+    "PCIE CFG RD16: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
+    Addr,
+    *Val,
+    AlignedAddr,
+    Val32
+    );
+
+  return 0;
+}
+
+/**
+   Read 8-bit value from config space address
+
+   @param Addr          Address within config space
+   @param Val           Point to address for read value
+**/
+INT32
+Ac01PcieCfgIn8 (
+  IN  VOID  *Addr,
+  OUT UINT8 *Val
+  )
+{
+  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
+  if ((((UINT64)Addr & DEV_MASK) >> 15 )> 0 && (((UINT64)Addr & BUS_MASK)  >> 20)> 0) {
+    *Val = 0xff;
+    return 0;
+  }
+
+  UINT32 Val32 = MmioRead32 (AlignedAddr);
+  switch ((UINT64)Addr & 0x3) {
+  case 3:
+    *Val = Val32 >> 24;
+    break;
+
+  case 2:
+    *Val = Val32 >> 16;
+    break;
+
+  case 1:
+    *Val = Val32 >> 8;
+    break;
+
+  case 0:
+  default:
+    *Val = Val32;
+    break;
+  }
+  PCIE_DEBUG_CFG (
+    "PCIE CFG RD8: 0x%p value: 0x%02X (0x%08llX 0x%08X)\n",
+    Addr,
+    *Val,
+    AlignedAddr,
+    Val32
+    );
+
+  return 0;
+}
+
+/**
+   Return the next extended capability address
+
+   @param RC              Pointer to AC01_RC structure
+   @param PcieIndex       PCIe index
+   @param IsRC            0x1: Checking RC configuration space
+                          0x0: Checking EP configuration space
+   @param ExtendedCapId
+**/
+UINT64
+PcieCheckCap (
+  IN AC01_RC *RC,
+  IN INTN    PcieIndex,
+  IN BOOLEAN IsRC,
+  IN UINT16  ExtendedCapId
+  )
+{
+  VOID   *CfgAddr;
+  UINT32 Val = 0, NextCap = 0, CapId = 0, ExCap = 0;
+
+  if (IsRC) {
+    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+  } else {
+    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 20));
+  }
+
+  Ac01PcieCsrIn32 (CfgAddr + TYPE1_CAP_PTR_REG, &Val);
+  NextCap = Val & 0xFF;
+
+  // Loop untill desired capability is found else return 0
+  while (1) {
+    if ((NextCap & 0x3) != 0) {
+      /* Not alignment, just return */
+      return 0;
+    }
+    Ac01PcieCsrIn32 (CfgAddr + NextCap, &Val);
+    if (NextCap < EXT_CAP_OFFSET_START) {
+      CapId = Val & 0xFF;
+    } else {
+      CapId = Val & 0xFFFF;
+    }
+
+    if (CapId == ExtendedCapId) {
+      return (UINT64)(CfgAddr + NextCap);
+    }
+
+    if (NextCap < EXT_CAP_OFFSET_START) {
+      NextCap = (Val & 0xFFFF) >> 8;
+    } else {
+      NextCap = (Val & 0xFFFF0000) >> 20;
+    }
+
+    if ((NextCap == 0) && (ExCap == 0)) {
+      ExCap = 1;
+      NextCap = EXT_CAP_OFFSET_START;
+    }
+
+    if ((NextCap == 0) && (ExCap == 1)) {
+      return (UINT64)0;
+    }
+  }
+}
+
+/**
+   Read 8-bit value from config space address
+
+   @param RC          Pointer to AC01_RC strucutre
+   @param RegBase     Base address of CSR, TCU, Hostbridge, Msg, Serdes, and MMCFG register
+   @param MmioBase    Base address of 32-bit MMIO
+   @param Mmio32Base  Base address of 64-bit MMIO
+**/
+VOID
+Ac01PcieCoreBuildRCStruct (
+  AC01_RC *RC,
+  UINT64  RegBase,
+  UINT64  MmioBase,
+  UINT64  Mmio32Base
+  )
+{
+  INTN PcieIndex;
+
+  RC->BaseAddr = RegBase;
+  RC->TcuAddr = RegBase + TCU_OFFSET;
+  RC->HBAddr = RegBase + HB_CSR_OFFSET;
+  RC->SerdesAddr = RegBase + SERDES_CSR_OFFSET;
+  RC->MmcfgAddr = RegBase + MMCONFIG_OFFSET;
+  RC->MmioAddr = MmioBase;
+  RC->Mmio32Addr = Mmio32Base;
+  RC->IoAddr = Mmio32Base + MMIO32_SPACE - IO_SPACE;
+
+  RC->Type = (RC->ID < MAX_RCA) ? RCA : RCB;
+  RC->MaxPcieController = (RC->Type == RCB) ? MAX_PCIE_B : MAX_PCIE_A;
+
+  PcieBoardParseRCParams (RC);
+
+  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
+    RC->Pcie[PcieIndex].ID = PcieIndex;
+    RC->Pcie[PcieIndex].CsrAddr = RC->BaseAddr + PCIE0_CSR_OFFSET + PcieIndex*0x10000;
+    RC->Pcie[PcieIndex].SnpsRamAddr = RC->Pcie[PcieIndex].CsrAddr + SNPSRAM_OFFSET;
+    RC->Pcie[PcieIndex].DevNum = PcieIndex + 1;
+  }
+
+  PCIE_DEBUG (
+    " + S%d - RC%a%d, MMCfgAddr:0x%lx, MmioAddr:0x%lx, Mmio32Addr:0x%lx, Enabled:%a\n",
+    RC->Socket,
+    (RC->Type == RCA) ? "A" : "B",
+    RC->ID,
+    RC->MmcfgAddr,
+    RC->MmioAddr,
+    RC->Mmio32Addr,
+    (RC->Active) ? "Y" : "N"
+    );
+  PCIE_DEBUG (" +   DevMapLo/Hi: 0x%x/0x%x\n", RC->DevMapLo, RC->DevMapHi);
+  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
+    PCIE_DEBUG (
+      " +     PCIE%d:0x%lx - Enabled:%a - DevNum:0x%x\n",
+      PcieIndex,
+      RC->Pcie[PcieIndex].CsrAddr,
+      (RC->Pcie[PcieIndex].Active) ? "Y" : "N",
+      RC->Pcie[PcieIndex].DevNum
+      );
+  }
+}
+
+/**
+   Configure equalization settings
+
+   @param RC              Pointer to AC01_RC structure
+   @param PcieIndex       PCIe index
+**/
+STATIC
+VOID
+Ac01PcieConfigureEqualization (
+  IN AC01_RC *RC,
+  IN INTN    PcieIndex
+  )
+{
+  VOID   *CfgAddr;
+  UINT32 Val;
+
+  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+
+  // Select the FoM method, need double-write to convey settings
+  Ac01PcieCfgIn32 (CfgAddr + GEN3_EQ_CONTROL_OFF, &Val);
+  Val = GEN3_EQ_FB_MODE (Val, 0x1);
+  Val = GEN3_EQ_PRESET_VEC (Val, 0x3FF);
+  Val = GEN3_EQ_INIT_EVAL (Val, 0x1);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_EQ_CONTROL_OFF, Val);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_EQ_CONTROL_OFF, Val);
+  Ac01PcieCfgIn32 (CfgAddr + GEN3_EQ_CONTROL_OFF, &Val);
+}
+
+/**
+   Configure presets for GEN3 equalization
+
+   @param RC              Pointer to AC01_RC structure
+   @param PcieIndex       PCIe index
+**/
+STATIC
+VOID
+Ac01PcieConfigurePresetGen3 (
+  IN AC01_RC *RC,
+  IN INTN    PcieIndex
+  )
+{
+  VOID   *CfgAddr, *SpcieBaseAddr;
+  UINT32 Val, Idx;
+  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+
+  // Bring to legacy mode
+  Ac01PcieCfgIn32 (CfgAddr + GEN3_RELATED_OFF, &Val);
+  Val = RATE_SHADOW_SEL_SET (Val, 0);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
+  Val = EQ_PHASE_2_3_SET (Val, 0);
+  Val = RXEQ_REGRDLESS_SET (Val, 1);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
+
+  // Generate SPCIE capability address
+  SpcieBaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, SPCIE_CAP_ID);
+  if (SpcieBaseAddr == 0) {
+    PCIE_ERR (
+      "PCIE%d.%d: Cannot get SPCIE capability address\n",
+      RC->ID,
+      PcieIndex
+      );
+    return;
+  }
+
+  for (Idx=0; Idx < RC->Pcie[PcieIndex].MaxWidth/2; Idx++) {
+    // Program Preset to Gen3 EQ Lane Control
+    Ac01PcieCfgIn32 (SpcieBaseAddr + CAP_OFF_0C + Idx*4, &Val);
+    Val = DSP_TX_PRESET0_SET (Val, 0x7);
+    Val = DSP_TX_PRESET1_SET (Val, 0x7);
+    Ac01PcieCfgOut32 (SpcieBaseAddr + CAP_OFF_0C + Idx*4, Val);
+  }
+}
+
+/**
+   Configure presets for GEN4 equalization
+
+   @param RC              Pointer to AC01_RC structure
+   @param PcieIndex       PCIe index
+**/
+STATIC
+VOID
+Ac01PcieConfigurePresetGen4 (
+  IN AC01_RC *RC,
+  IN INTN    PcieIndex
+  )
+{
+  UINT32 Val;
+  VOID   *CfgAddr, *SpcieBaseAddr, *Pl16BaseAddr;
+  UINT32 LinkWidth, i;
+  UINT8  Preset;
+
+  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+
+  // Bring to legacy mode
+  Ac01PcieCfgIn32 (CfgAddr + GEN3_RELATED_OFF, &Val);
+  Val = RATE_SHADOW_SEL_SET (Val, 1);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
+  Val = EQ_PHASE_2_3_SET (Val, 0);
+  Val = RXEQ_REGRDLESS_SET (Val, 1);
+  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
+
+  // Generate the PL16 capability address
+  Pl16BaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, PL16_CAP_ID);
+  if (Pl16BaseAddr == 0) {
+    PCIE_ERR (
+      "PCIE%d.%d: Cannot get PL16 capability address\n",
+      RC->ID,
+      PcieIndex
+      );
+    return;
+  }
+
+  // Generate the SPCIE capability address
+  SpcieBaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, SPCIE_CAP_ID);
+  if (SpcieBaseAddr == 0) {
+    PCIE_ERR (
+      "PCIE%d.%d: Cannot get SPICE capability address\n",
+      RC->ID,
+      PcieIndex
+      );
+    return;
+  }
+
+  // Configure downstream Gen4 Tx preset
+  if (RC->PresetGen4[PcieIndex] == PRESET_INVALID) {
+    Preset = 0x57; // Default Gen4 preset
+  } else {
+    Preset = RC->PresetGen4[PcieIndex];
+  }
+
+  LinkWidth = RC->Pcie[PcieIndex].MaxWidth;
+  if (LinkWidth == 0x2) {
+    Ac01PcieCfgIn32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF, &Val);
+    Val = DSP_16G_RXTX_PRESET0_SET (Val, Preset);
+    Val = DSP_16G_RXTX_PRESET1_SET (Val, Preset);
+    Ac01PcieCfgOut32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF, Val);
+  } else {
+    for (i = 0; i < LinkWidth/4; i++) {
+      Ac01PcieCfgIn32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF + i*4, &Val);
+      Val = DSP_16G_RXTX_PRESET0_SET (Val, Preset);
+      Val = DSP_16G_RXTX_PRESET1_SET (Val, Preset);
+      Val = DSP_16G_RXTX_PRESET2_SET (Val, Preset);
+      Val = DSP_16G_RXTX_PRESET3_SET (Val, Preset);
+      Ac01PcieCfgOut32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF + i*4, Val);
+    }
+  }
+
+  // Configure Gen3 preset
+  for (i = 0; i < LinkWidth/2; i++) {
+    Ac01PcieCfgIn32 (SpcieBaseAddr + CAP_OFF_0C + i*4, &Val);
+    Val = DSP_TX_PRESET0_SET (Val, 0x7);
+    Val = DSP_TX_PRESET1_SET (Val, 0x7);
+    Ac01PcieCfgOut32 (SpcieBaseAddr + CAP_OFF_0C + i*4, Val);
+  }
+}
+
+STATIC BOOLEAN
+RasdpMitigationCheck (
+  AC01_RC *RC,
+  INTN    PcieIndex
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  VOID               *Hob;
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+  if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) {
+    if (AsciiStrCmp ((CONST CHAR8 *)PlatformHob->CpuVer, "A0") == 0) {
+      return ((RC->Type == RCB)||(PcieIndex > 0)) ? TRUE : FALSE;
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+   Setup and initialize the AC01 PCIe Root Complex and underneath PCIe controllers
+
+   @param RC                    Pointer to Root Complex structure
+   @param ReInit                Re-init status
+   @param ReInitPcieIndex       PCIe index
+**/
+INT32
+Ac01PcieCoreSetupRC (
+  IN AC01_RC *RC,
+  IN UINT8   ReInit,
+  IN UINT8   ReInitPcieIndex
+  )
+{
+  VOID              *CsrAddr, *CfgAddr, *SnpsRamAddr, *DlinkBaseAddr;
+  INTN              PcieIndex;
+  INTN              TimeOut;
+  UINT32            Val;
+  PHY_CONTEXT       PhyCtx = { 0 };
+  PHY_PLAT_RESOURCE PhyPlatResource = { 0 };
+  INTN              Ret;
+  UINT16            NextExtendedCapabilityOff;
+  UINT32            VsecVal;
+
+  PCIE_DEBUG ("Initializing Socket%d RC%d\n", RC->Socket, RC->ID);
+
+  if (ReInit == 0) {
+    // Initialize SERDES
+    ZeroMem (&PhyCtx, sizeof (PhyCtx));
+    PhyCtx.SdsAddr = RC->SerdesAddr;
+    PhyCtx.PcieCtrlInfo |= ((RC->Socket & 0x1) << 2);
+    PhyCtx.PcieCtrlInfo |= ((RC->ID & 0x7) << 4);
+    PhyCtx.PcieCtrlInfo |= 0xF << 8;
+    PhyPlatResource.MmioRd = Ac01PcieMmioRd;
+    PhyPlatResource.MmioWr = Ac01PcieMmioWr;
+    PhyPlatResource.UsDelay = Ac01PcieDelay;
+    PhyPlatResource.Puts = Ac01PciePuts;
+    PhyPlatResource.PutInt = Ac01PciePutInt;
+    PhyPlatResource.PutHex = Ac01PciePutInt;
+    PhyPlatResource.PutHex64 = Ac01PciePutHex;
+    PhyPlatResource.DebugPrint = Ac01PcieDebugPrint;
+    PhyCtx.PhyPlatResource = &PhyPlatResource;
+
+    Ret = SerdesInitClkrst (&PhyCtx);
+    if (Ret != PHY_INIT_PASS) {
+      return -1;
+    }
+  }
+
+  // Setup each controller
+  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
+
+    if (ReInit == 1) {
+      PcieIndex = ReInitPcieIndex;
+    }
+
+    if (!RC->Pcie[PcieIndex].Active) {
+      continue;
+    }
+
+    PCIE_DEBUG ("Initializing Controller %d\n", PcieIndex);
+
+    CsrAddr = (VOID *)RC->Pcie[PcieIndex].CsrAddr;
+    SnpsRamAddr = (VOID *)RC->Pcie[PcieIndex].SnpsRamAddr;
+    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+
+    // Put Controller into reset if not in reset already
+    Ac01PcieCsrIn32 (CsrAddr +  RESET, &Val);
+    if (!(Val & RESET_MASK)) {
+      Val = DWCPCIE_SET (Val, 1);
+      Ac01PcieCsrOut32 (CsrAddr + RESET, Val);
+
+      // Delay 50ms to ensure controller finish its reset
+      // FIXME: Is this necessary?
+      MicroSecondDelay (50000);
+    }
+
+    // Clear memory shutdown
+    Ac01PcieCsrIn32 (CsrAddr + RAMSDR, &Val);
+    Val = SD_SET (Val, 0);
+    Ac01PcieCsrOut32 (CsrAddr + RAMSDR, Val);
+
+    // Poll till mem is ready
+    TimeOut = PCIE_MEMRDY_TIMEOUT;
+    do {
+      Ac01PcieCsrIn32 (CsrAddr + MEMRDYR, &Val);
+      if (Val & 1) {
+        break;
+      }
+
+      TimeOut--;
+      MicroSecondDelay (1);
+    } while (TimeOut > 0);
+
+    if (TimeOut <= 0) {
+      PCIE_ERR ("- Pcie[%d] - Mem not ready\n", PcieIndex);
+      return -1;
+    }
+
+    // Hold link training
+    Ac01PcieCsrIn32 (CsrAddr + LINKCTRL, &Val);
+    Val = LTSSMENB_SET (Val, 0);
+    Ac01PcieCsrOut32 (CsrAddr + LINKCTRL, Val);
+
+    // Enable subsystem clock and release reset
+    Ac01PcieCsrIn32 (CsrAddr + CLOCK, &Val);
+    Val = AXIPIPE_SET (Val, 1);
+    Ac01PcieCsrOut32 (CsrAddr + CLOCK, Val);
+    Ac01PcieCsrIn32 (CsrAddr +  RESET, &Val);
+    Val = DWCPCIE_SET (Val, 0);
+    Ac01PcieCsrOut32 (CsrAddr + RESET, Val);
+
+    //
+    // Controller does not provide any indicator for reset released.
+    // Must wait at least 1us as per EAS.
+    //
+    MicroSecondDelay (1);
+
+    // Poll till PIPE clock is stable
+    TimeOut = PCIE_PIPE_CLOCK_TIMEOUT;
+    do {
+      Ac01PcieCsrIn32 (CsrAddr + LINKSTAT, &Val);
+      if (!(Val & PHY_STATUS_MASK)) {
+        break;
+      }
+
+      TimeOut--;
+      MicroSecondDelay (1);
+    } while (TimeOut > 0);
+
+    if (TimeOut <= 0) {
+      PCIE_ERR ("- Pcie[%d] - PIPE clock is not stable\n", PcieIndex);
+      return -1;
+    }
+
+    // Start PERST pulse
+    PcieBoardAssertPerst (RC, PcieIndex, 0, TRUE);
+
+    // Allow programming to config space
+    Ac01PcieCsrIn32 (CfgAddr + MISC_CONTROL_1_OFF, &Val);
+    Val = DBI_RO_WR_EN_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + MISC_CONTROL_1_OFF, Val);
+
+    // In order to detect the NVMe disk for booting without disk,
+    // need to set Hot-Plug Slot Capable during port initialization.
+    // It will help PCI Linux driver to initialize its slot iomem resource,
+    // the one is used for detecting the disk when it is inserted.
+    Ac01PcieCsrIn32 (CfgAddr + SLOT_CAPABILITIES_REG, &Val);
+    Val = SLOT_HPC_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + SLOT_CAPABILITIES_REG, Val);
+
+
+    // Apply RASDP error mitigation for all x8, x4, and x2 controllers
+    // This includes all RCB root ports, and every RCA root port controller
+    // except for index 0 (i.e. x16 controllers are exempted from this WA)
+    if (RasdpMitigationCheck (RC, PcieIndex)) {
+      // Change the Read Margin dual ported RAMs
+      Val = 0x10; // Margin to 0x0 (most conservative setting)
+      Ac01PcieCsrOut32 (SnpsRamAddr + TPSRAM_RMR, Val);
+
+      // Generate the DLINK capability address
+      DlinkBaseAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+      NextExtendedCapabilityOff = 0x100; // This is the 1st extended capability offset
+      do {
+        Ac01PcieCsrIn32 (DlinkBaseAddr + NextExtendedCapabilityOff, &Val);
+        if (Val == 0xFFFFFFFF) {
+          DlinkBaseAddr = 0x0;
+          break;
+        }
+        if ((Val & 0xFFFF) == DLINK_VENDOR_CAP_ID) {
+          Ac01PcieCsrIn32 (DlinkBaseAddr + NextExtendedCapabilityOff + 0x4, &VsecVal);
+          if (VsecVal == DLINK_VSEC) {
+            DlinkBaseAddr = DlinkBaseAddr + NextExtendedCapabilityOff;
+            break;
+          }
+        }
+        NextExtendedCapabilityOff = (Val >> 20);
+      } while (NextExtendedCapabilityOff != 0);
+
+      // Disable the scaled credit mode
+      if (DlinkBaseAddr != 0x0) {
+        Val = 1;
+        Ac01PcieCsrOut32 (DlinkBaseAddr + DATA_LINK_FEATURE_CAP_OFF, Val);
+        Ac01PcieCsrIn32 (DlinkBaseAddr + DATA_LINK_FEATURE_CAP_OFF, &Val);
+        if (Val != 1) {
+          PCIE_ERR ("- Pcie[%d] - Unable to disable scaled credit\n", PcieIndex);
+          return -1;
+        }
+      } else {
+        PCIE_ERR ("- Pcie[%d] - Unable to locate data link feature cap offset\n", PcieIndex);
+        return -1;
+      }
+
+      // Reduce Posted Credits to 1 packet header and data credit for all
+      // impacted controllers.  Also zero credit scale values for both
+      // data and packet headers.
+      Val=0x40201020;
+      Ac01PcieCsrOut32 (CfgAddr + PORT_LOCIG_VC0_P_RX_Q_CTRL_OFF, Val);
+    }
+
+    // Program DTI for ATS support
+    Ac01PcieCsrIn32 (CfgAddr + DTIM_CTRL0_OFF, &Val);
+    Val = DTIM_CTRL0_ROOT_PORT_ID_SET (Val, 0);
+    Ac01PcieCsrOut32 (CfgAddr + DTIM_CTRL0_OFF, Val);
+
+    //
+    // Program number of lanes used
+    // - Reprogram LINK_CAPABLE of PORT_LINK_CTRL_OFF
+    // - Reprogram NUM_OF_LANES of GEN2_CTRL_OFF
+    // - Reprogram PCIE_CAP_MAX_LINK_WIDTH of LINK_CAPABILITIES_REG
+    //
+    Ac01PcieCsrIn32 (CfgAddr + PORT_LINK_CTRL_OFF, &Val);
+    switch (RC->Pcie[PcieIndex].MaxWidth) {
+    case LNKW_X2:
+      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X2);
+      break;
+
+    case LNKW_X4:
+      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X4);
+      break;
+
+    case LNKW_X8:
+      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X8);
+      break;
+
+    case LNKW_X16:
+    default:
+      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X16);
+      break;
+    }
+    Ac01PcieCsrOut32 (CfgAddr + PORT_LINK_CTRL_OFF, Val);
+    Ac01PcieCsrIn32 (CfgAddr + GEN2_CTRL_OFF, &Val);
+    switch (RC->Pcie[PcieIndex].MaxWidth) {
+    case LNKW_X2:
+      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X2);
+      break;
+
+    case LNKW_X4:
+      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X4);
+      break;
+
+    case LNKW_X8:
+      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X8);
+      break;
+
+    case LNKW_X16:
+    default:
+      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X16);
+      break;
+    }
+    Ac01PcieCsrOut32 (CfgAddr + GEN2_CTRL_OFF, Val);
+    Ac01PcieCsrIn32 (CfgAddr + LINK_CAPABILITIES_REG, &Val);
+    switch (RC->Pcie[PcieIndex].MaxWidth) {
+    case LNKW_X2:
+      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X2);
+      break;
+
+    case LNKW_X4:
+      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X4);
+      break;
+
+    case LNKW_X8:
+      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X8);
+      break;
+
+    case LNKW_X16:
+    default:
+      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X16);
+      break;
+    }
+
+    switch (RC->Pcie[PcieIndex].MaxGen) {
+    case SPEED_GEN1:
+      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25);
+      break;
+
+    case SPEED_GEN2:
+      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50);
+      break;
+
+    case SPEED_GEN3:
+      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80);
+      break;
+
+    default:
+      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160);
+      break;
+    }
+    /* Enable ASPM Capability */
+    Val = PCIE_CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET (Val, L0S_L1_SUPPORTED);
+    Ac01PcieCsrOut32 (CfgAddr + LINK_CAPABILITIES_REG, Val);
+
+    Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL2_LINK_STATUS2_REG, &Val);
+    switch (RC->Pcie[PcieIndex].MaxGen) {
+    case SPEED_GEN1:
+      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25);
+      break;
+
+    case SPEED_GEN2:
+      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50);
+      break;
+
+    case SPEED_GEN3:
+      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80);
+      break;
+
+    default:
+      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160);
+      break;
+    }
+    Ac01PcieCsrOut32 (CfgAddr + LINK_CONTROL2_LINK_STATUS2_REG, Val);
+
+    // Set Zero byte request handling
+    Ac01PcieCsrIn32 (CfgAddr + FILTER_MASK_2_OFF, &Val);
+    Val = CX_FLT_MASK_VENMSG0_DROP_SET (Val, 0);
+    Val = CX_FLT_MASK_VENMSG1_DROP_SET (Val, 0);
+    Val = CX_FLT_MASK_DABORT_4UCPL_SET (Val, 0);
+    Ac01PcieCsrOut32 (CfgAddr + FILTER_MASK_2_OFF, Val);
+    Ac01PcieCsrIn32 (CfgAddr + AMBA_ORDERING_CTRL_OFF, &Val);
+    Val = AX_MSTR_ZEROLREAD_FW_SET (Val, 0);
+    Ac01PcieCsrOut32 (CfgAddr + AMBA_ORDERING_CTRL_OFF, Val);
+
+    //
+    // Set Completion with CRS handling for CFG Request
+    // Set Completion with CA/UR handling non-CFG Request
+    //
+    Ac01PcieCsrIn32 (CfgAddr + AMBA_ERROR_RESPONSE_DEFAULT_OFF, &Val);
+    Val = AMBA_ERROR_RESPONSE_CRS_SET (Val, 0x2);
+    Ac01PcieCsrOut32 (CfgAddr + AMBA_ERROR_RESPONSE_DEFAULT_OFF, Val);
+
+    // Set Legacy PCIE interrupt map to INTA
+    Ac01PcieCsrIn32 (CfgAddr + BRIDGE_CTRL_INT_PIN_INT_LINE_REG, &Val);
+    Val = INT_PIN_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + BRIDGE_CTRL_INT_PIN_INT_LINE_REG, Val);
+    Ac01PcieCsrIn32 (CsrAddr + IRQSEL, &Val);
+    Val = INTPIN_SET (Val, 1);
+    Ac01PcieCsrOut32 (CsrAddr + IRQSEL, Val);
+
+    if (RC->Pcie[PcieIndex].MaxGen != SPEED_GEN1) {
+      Ac01PcieConfigureEqualization (RC, PcieIndex);
+      if (RC->Pcie[PcieIndex].MaxGen == SPEED_GEN3) {
+        Ac01PcieConfigurePresetGen3 (RC, PcieIndex);
+      } else if (RC->Pcie[PcieIndex].MaxGen == SPEED_GEN4) {
+        Ac01PcieConfigurePresetGen4 (RC, PcieIndex);
+      }
+    }
+
+    // Mask Completion Timeout
+    Ac01PcieCsrIn32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, &Val);
+    Val = LINK_TIMEOUT_PERIOD_DEFAULT_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, Val);
+    Ac01PcieCsrIn32 (CfgAddr + UNCORR_ERR_MASK_OFF, &Val);
+    Val = CMPLT_TIMEOUT_ERR_MASK_SET (Val, 1);
+    // AER surprise link down error should be masked due to hotplug is enabled
+    // This event must be handled by Hotplug handler, instead of error handler
+    Val = SDES_ERR_MASK_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + UNCORR_ERR_MASK_OFF, Val);
+
+    // Program Class Code
+    Ac01PcieCsrIn32 (CfgAddr + TYPE1_CLASS_CODE_REV_ID_REG, &Val);
+    Val = REVISION_ID_SET (Val, 4);
+    Val = SUBCLASS_CODE_SET (Val, 4);
+    Val = BASE_CLASS_CODE_SET (Val, 6);
+    Ac01PcieCsrOut32 (CfgAddr + TYPE1_CLASS_CODE_REV_ID_REG, Val);
+
+    // Program VendorID and DeviceID
+    Ac01PcieCsrIn32 (CfgAddr + TYPE1_DEV_ID_VEND_ID_REG, &Val);
+    Val = VENDOR_ID_SET (Val, AMPERE_PCIE_VENDORID);
+    if (RCA == RC->Type) {
+      Val = DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICEID_RCA + PcieIndex);
+    } else {
+      Val = DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICEID_RCB + PcieIndex);
+    }
+    Ac01PcieCsrOut32 (CfgAddr + TYPE1_DEV_ID_VEND_ID_REG, Val);
+
+    // Enable common clock for downstream
+    Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, &Val);
+    Val = PCIE_CAP_SLOT_CLK_CONFIG_SET (Val, 1);
+    Val = PCIE_CAP_COMMON_CLK_SET (Val, 1);
+    Ac01PcieCsrOut32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, Val);
+
+    // Assert PERST low to reset endpoint
+    PcieBoardAssertPerst (RC, PcieIndex, 0, FALSE);
+
+    // Start link training
+    Ac01PcieCsrIn32 (CsrAddr + LINKCTRL, &Val);
+    Val = LTSSMENB_SET (Val, 1);
+    Ac01PcieCsrOut32 (CsrAddr + LINKCTRL, Val);
+
+    // Complete the PERST pulse
+    PcieBoardAssertPerst (RC, PcieIndex, 0, TRUE);
+
+    // Match aux_clk to system
+    Ac01PcieCsrIn32 (CfgAddr + AUX_CLK_FREQ_OFF, &Val);
+    Val = AUX_CLK_FREQ_SET (Val, AUX_CLK_500MHZ);
+    Ac01PcieCsrOut32 (CfgAddr + AUX_CLK_FREQ_OFF, Val);
+
+    // Lock programming of config space
+    Ac01PcieCsrIn32 (CfgAddr + MISC_CONTROL_1_OFF, &Val);
+    Val = DBI_RO_WR_EN_SET (Val, 0);
+    Ac01PcieCsrOut32 (CfgAddr + MISC_CONTROL_1_OFF, Val);
+
+    if (ReInit == 1) {
+      break;
+    }
+  }
+
+  // Program VendorID and DeviceId
+  if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr  + HBPDVIDR, &Val))) {
+    Val = PCIVENDID_SET (Val, AMPERE_PCIE_VENDORID);
+    if (RCA == RC->Type) {
+      Val = PCIDEVID_SET (Val, AC01_HOST_BRIDGE_DEVICEID_RCA);
+    } else {
+      Val = PCIDEVID_SET (Val, AC01_HOST_BRIDGE_DEVICEID_RCB);
+    }
+    MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr  + HBPDVIDR, Val);
+  }
+
+  return 0;
+}
+
+STATIC BOOLEAN
+PcieLinkUpCheck (
+  IN  AC01_PCIE *Pcie,
+  OUT UINT32    *LtssmState
+  )
+{
+  VOID   *CsrAddr;
+  UINT32 BlockEvent, LinkStat;
+
+  CsrAddr = (VOID *)Pcie->CsrAddr;
+
+  // Check if card present
+  // smlh_ltssm_state[13:8] = 0
+  // phy_status[2] = 0
+  // smlh_link_up[1] = 0
+  // rdlh_link_up[0] = 0
+  Ac01PcieCsrIn32 (CsrAddr + LINKSTAT, &LinkStat);
+  LinkStat = LinkStat & (SMLH_LTSSM_STATE_MASK | PHY_STATUS_MASK_BIT |
+                         SMLH_LINK_UP_MASK_BIT | RDLH_LINK_UP_MASK_BIT);
+  if (LinkStat == 0x0000) {
+    return 0;
+  }
+
+  Ac01PcieCsrIn32 (CsrAddr +  BLOCKEVENTSTAT, &BlockEvent);
+  Ac01PcieCsrIn32 (CsrAddr +  LINKSTAT, &LinkStat);
+
+  if ((BlockEvent & LINKUP_MASK) != 0) {
+    *LtssmState = SMLH_LTSSM_STATE_GET (LinkStat);
+    PCIE_DEBUG ("%a *LtssmState=%lx Linkup\n", __func__, *LtssmState);
+    return 1;
+  }
+
+  return 0;
+}
+
+VOID
+Ac01PcieCoreUpdateLink (
+  IN  AC01_RC *RC,
+  OUT BOOLEAN *IsNextRoundNeeded,
+  OUT INT8    *FailedPciePtr,
+  OUT INT8    *FailedPcieCount
+  )
+{
+  INTN      PcieIndex;
+  AC01_PCIE *Pcie;
+  UINT32    Ltssm, i;
+  UINT32    Val;
+  VOID      *CfgAddr;
+
+  *IsNextRoundNeeded = FALSE;
+  *FailedPcieCount   = 0;
+  for (i = 0; i < MAX_PCIE_B; i++) {
+    FailedPciePtr[i] = -1;
+  }
+
+  if (!RC->Active) {
+    return;
+  }
+
+  // Loop for all controllers
+  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
+    Pcie = &RC->Pcie[PcieIndex];
+    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
+
+    if (Pcie->Active && !Pcie->LinkUp) {
+      if (PcieLinkUpCheck (Pcie, &Ltssm)) {
+        Pcie->LinkUp = 1;
+        Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, &Val);
+        PCIE_DEBUG (
+          "%a S%d RC%d RP%d NEGO_LINK_WIDTH: 0x%x LINK_SPEED: 0x%x\n",
+          __FUNCTION__,
+          RC->Socket,
+          RC->ID,
+          PcieIndex,
+          PCIE_CAP_NEGO_LINK_WIDTH_GET (Val),
+          PCIE_CAP_LINK_SPEED_GET (Val)
+          );
+
+        // Un-mask Completion Timeout
+        Ac01PcieCsrIn32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, &Val);
+        Val = LINK_TIMEOUT_PERIOD_DEFAULT_SET (Val, 32);
+        Ac01PcieCsrOut32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, Val);
+        Ac01PcieCsrIn32 (CfgAddr + UNCORR_ERR_MASK_OFF, &Val);
+        Val = CMPLT_TIMEOUT_ERR_MASK_SET (Val, 0);
+        Ac01PcieCsrOut32 (CfgAddr + UNCORR_ERR_MASK_OFF, Val);
+      } else {
+        *IsNextRoundNeeded = TRUE;
+        FailedPciePtr[*FailedPcieCount] = PcieIndex;
+        *FailedPcieCount += 1;
+      }
+    }
+  }
+}
+
+VOID
+Ac01PcieCoreEndEnumeration (
+  AC01_RC *RC
+  )
+{
+  //
+  // Reserved for hook from stack ending of enumeration phase processing.
+  // Emptry for now.
+  //
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
new file mode 100644
index 000000000000..5beb59689254
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
@@ -0,0 +1,536 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmGenericTimerCounterLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcieBoardLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+
+#include "PcieCore.h"
+#include "PciePatchAcpi.h"
+
+STATIC UINT64  RCRegBase[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_REGISTER_BASE };
+STATIC UINT64  RCMmioBase[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO_BASE };
+STATIC UINT64  RCMmio32Base[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE };
+STATIC UINT64  RCMmio32Base1P[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE_1P };
+STATIC AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX];
+STATIC INT8    PciList[MAX_AC01_PCIE_ROOT_COMPLEX];
+
+STATIC
+VOID
+SerialPrint (
+  IN CONST CHAR8 *FormatString,
+  ...
+  )
+{
+  UINT8   Buf[64];
+  VA_LIST Marker;
+  UINTN   NumberOfPrinted;
+
+  VA_START (Marker, FormatString);
+  NumberOfPrinted = AsciiVSPrint ((CHAR8 *)Buf, sizeof (Buf), FormatString, Marker);
+  SerialPortWrite (Buf, NumberOfPrinted);
+  VA_END (Marker);
+}
+
+AC01_RC *
+GetRCList (
+  UINT8 Idx
+  )
+{
+  return &RCList[Idx];
+}
+
+/**
+   Map BusDxe Host bridge and Root bridge Indexes to PCIE core BSP driver Root Complex Index.
+
+   @param  HBIndex               Index to identify of PCIE Host bridge.
+   @param  RBIndex               Index to identify of PCIE Root bridge.
+   @retval UINT8                 Index to identify Root Complex instance from global RCList.
+**/
+STATIC
+UINT8
+GetRCIndex (
+  IN UINT8 HBIndex,
+  IN UINT8 RBIndex
+  )
+{
+  //
+  // BusDxe addresses resources based on Host bridge and Root bridge.
+  // Map those to Root Complex index/instance known for Pcie Core BSP driver
+  //
+  return HBIndex * MAX_AC01_PCIE_ROOT_BRIDGE + RBIndex;
+}
+
+/**
+  Prepare to start PCIE core BSP driver.
+
+  @param ImageHandle[in]        Handle for the image.
+  @param SystemTable[in]        Address of the system table.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+**/
+EFI_STATUS
+Ac01PcieSetup (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  AC01_RC *RC;
+  INTN    RCIndex;
+
+  ZeroMem (&RCList, sizeof (AC01_RC) * MAX_AC01_PCIE_ROOT_COMPLEX);
+
+  // Adjust MMIO32 base address 1P vs 2P
+  if (!IsSlaveSocketPresent ()) {
+    CopyMem ((VOID *)&RCMmio32Base, (VOID *)&RCMmio32Base1P, sizeof (UINT64) * MAX_AC01_PCIE_ROOT_COMPLEX);
+  }
+
+  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+    RC = &RCList[RCIndex];
+    RC->Socket = RCIndex / RCS_PER_SOCKET;
+    RC->ID = RCIndex % RCS_PER_SOCKET;
+
+    Ac01PcieCoreBuildRCStruct (RC, RCRegBase[RCIndex], RCMmioBase[RCIndex], RCMmio32Base[RCIndex]);
+  }
+
+  // Build the UEFI menu
+  PcieBoardScreenInitialize (ImageHandle, SystemTable, RCList);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Get Total HostBridge
+
+  @retval UINTN                 Return Total HostBridge.
+**/
+UINT8
+Ac01PcieGetTotalHBs (
+  VOID
+  )
+{
+  return MAX_AC01_PCIE_ROOT_COMPLEX;
+}
+
+/**
+  Get Total RootBridge per HostBridge.
+
+  @param  RCIndex[in]           Index to identify of Root Complex.
+
+  @retval UINTN                 Return Total RootBridge per HostBridge.
+**/
+UINT8
+Ac01PcieGetTotalRBsPerHB (
+  IN UINTN RCIndex
+  )
+{
+  return MAX_AC01_PCIE_ROOT_BRIDGE;
+}
+
+/**
+  Get RootBridge Attribute.
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
+
+  @retval UINTN                 Return RootBridge Attribute.
+**/
+UINTN
+Ac01PcieGetRootBridgeAttribute (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  )
+{
+  return EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+}
+
+/**
+  Get RootBridge Segment number.
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
+
+  @retval UINTN                 Return RootBridge Segment number.
+**/
+UINTN
+Ac01PcieGetRootBridgeSegmentNumber (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  )
+{
+  UINTN   RCIndex;
+  AC01_RC *RC;
+  UINTN   SegmentNumber;
+
+  RCIndex = GetRCIndex (HBIndex, RBIndex);
+  RC = &RCList[RCIndex];
+  SegmentNumber = RCIndex;
+
+  // Get board specific overrides
+  PcieBoardGetRCSegmentNumber (RC, &SegmentNumber);
+  RC->Logical = SegmentNumber;
+
+  return SegmentNumber;
+}
+
+STATIC
+VOID
+SortPciList (
+  INT8 *PciList
+  )
+{
+  INT8 Idx1, Idx2;
+
+  for (Idx2 = 0, Idx1 = 0; Idx2 < MAX_AC01_PCIE_ROOT_COMPLEX; Idx2++) {
+    if (PciList[Idx2] < 0) {
+      continue;
+    }
+    PciList[Idx1] = PciList[Idx2];
+    if (Idx1 != Idx2) {
+      PciList[Idx2] = -1;
+    }
+    Idx1++;
+  }
+
+  for (Idx2 = 0; Idx2 < Idx1; Idx2++) {
+    PCIE_DEBUG (
+      " %a: PciList[%d]=%d TcuAddr=0x%llx\n",
+      __FUNCTION__,
+      Idx2,
+      PciList[Idx2],
+      RCList[PciList[Idx2]].TcuAddr
+      );
+  }
+}
+
+/**
+  Get RootBridge disable status
+
+  @param  HBIndex[In]           Index to identify of PCIE Host bridge.
+  @param  RBIndex[In]           Index to identify of underneath PCIE Root bridge.
+
+  @retval BOOLEAN               Return RootBridge disable status.
+**/
+BOOLEAN
+Ac01PcieCheckRootBridgeDisabled (
+  IN UINTN HBIndex,
+  IN UINTN RBIndex
+  )
+{
+  UINTN RCIndex;
+  INT8  Ret;
+
+  RCIndex = HBIndex;
+  Ret = !RCList[RCIndex].Active;
+  if (Ret) {
+    PciList[HBIndex] = -1;
+  } else {
+    PciList[HBIndex] = HBIndex;
+  }
+  if (HBIndex == (MAX_AC01_PCIE_ROOT_COMPLEX -1)) {
+    SortPciList (PciList);
+    if (!IsSlaveSocketPresent ()) {
+      AcpiPatchPciMem32 (PciList);
+    }
+    AcpiInstallMcfg (PciList);
+    AcpiInstallIort (PciList);
+  }
+  return Ret;
+}
+
+/**
+  Initialize Host bridge.
+
+  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+**/
+EFI_STATUS
+Ac01PcieSetupHostBridge (
+  IN UINTN HBIndex
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Initialize Root bridge.
+
+  @param  HBIndex[in]            Index to identify of PCIE Host bridge.
+  @param  RBIndex[in]            Index to identify of underneath PCIE Root bridge.
+  @param  RootBridgeInstance[in] The pointer of instance of the Root bridge IO.
+
+  @retval EFI_SUCCESS           Initialize successfully.
+  @retval EFI_DEVICE_ERROR      Error when initializing.
+**/
+EFI_STATUS
+Ac01PcieSetupRootBridge (
+  IN UINTN           HBIndex,
+  IN UINTN           RBIndex,
+  IN PCI_ROOT_BRIDGE *RootBridge
+  )
+{
+  UINTN   RCIndex;
+  AC01_RC *RC;
+  UINT32  Result;
+
+  RCIndex = GetRCIndex (HBIndex, RBIndex);
+  RC = &RCList[RCIndex];
+  if (!RC->Active) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  RC->RootBridge = (VOID *)RootBridge;
+
+  // Initialize Root Complex and underneath controllers
+  Result = Ac01PcieCoreSetupRC (RC, 0, 0);
+  if (Result) {
+    PCIE_ERR ("RootComplex[%d]: Init Failed\n", RCIndex);
+
+    goto Error;
+  }
+
+  // Populate resource aperture
+  RootBridge->Bus.Base = 0x0;
+  RootBridge->Bus.Limit = 0xFF;
+  RootBridge->Io.Base = RC->IoAddr;
+  RootBridge->Io.Limit = RC->IoAddr + IO_SPACE - 1;
+  RootBridge->Mem.Base = RC->Mmio32Addr;
+  RootBridge->Mem.Limit = RootBridge->Mem.Base + MMIO32_SPACE - 1;
+  RootBridge->PMem.Base = RootBridge->Mem.Base;
+  RootBridge->PMem.Limit = RootBridge->Mem.Limit;
+  RootBridge->MemAbove4G.Base = 0x0;
+  RootBridge->MemAbove4G.Limit = 0x0;
+  RootBridge->PMemAbove4G.Base = RC->MmioAddr;
+  RootBridge->PMemAbove4G.Limit = RootBridge->PMemAbove4G.Base + MMIO_SPACE - 1;
+
+  PCIE_DEBUG (" +    Bus: 0x%x - 0x%lx\n", RootBridge->Bus.Base, RootBridge->Bus.Limit);
+  PCIE_DEBUG (" +     Io: 0x%x - 0x%lx\n", RootBridge->Io.Base, RootBridge->Io.Limit);
+  PCIE_DEBUG (" +    Mem: 0x%x - 0x%lx\n", RootBridge->Mem.Base, RootBridge->Mem.Limit);
+  PCIE_DEBUG (" +   PMem: 0x%x - 0x%lx\n", RootBridge->PMem.Base, RootBridge->PMem.Limit);
+  PCIE_DEBUG (" +  4GMem: 0x%x - 0x%lx\n", RootBridge->MemAbove4G.Base, RootBridge->MemAbove4G.Limit);
+  PCIE_DEBUG (" + 4GPMem: 0x%x - 0x%lx\n", RootBridge->PMemAbove4G.Base, RootBridge->PMemAbove4G.Limit);
+
+  return EFI_SUCCESS;
+
+Error:
+  RC->Active = FALSE;
+  return EFI_DEVICE_ERROR;
+}
+
+/**
+  Reads/Writes an PCI configuration register.
+
+  @param  RootInstance[in]      Pointer to RootInstance structure.
+  @param  Address[in]           Address which want to read or write to.
+  @param  Write[in]             Indicate that this is a read or write command.
+  @param  Width[in]             Specify the width of the data.
+  @param  Data[in, out]         The buffer to hold the data.
+
+  @retval EFI_SUCCESS           Read/Write successfully.
+**/
+EFI_STATUS
+Ac01PcieConfigRW (
+  IN     VOID    *RootInstance,
+  IN     UINT64  Address,
+  IN     BOOLEAN Write,
+  IN     UINTN   Width,
+  IN OUT VOID    *Data
+  )
+{
+  AC01_RC *RC = NULL;
+  VOID    *CfgBase = NULL;
+  UINTN   RCIndex;
+  UINT32  Reg;
+
+  ASSERT (Address <= 0x0FFFFFFF);
+
+  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+    RC = &RCList[RCIndex];
+    if (RC->RootBridge == RootInstance) {
+      break;
+    }
+  }
+
+  if ((RCIndex == MAX_AC01_PCIE_ROOT_COMPLEX) || (RC == NULL)) {
+    PCIE_ERR ("Can't find Root Bridge instance:%p\n", RootInstance);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Reg = Address & 0xFFF;
+
+  CfgBase = (VOID *)((UINT64)RC->MmcfgAddr + (Address & 0x0FFFF000));
+  if (Write) {
+    switch (Width) {
+    case 1:
+      Ac01PcieCfgOut8 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT8 *)Data));
+      break;
+
+    case 2:
+      Ac01PcieCfgOut16 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT16 *)Data));
+      break;
+
+    case 4:
+      Ac01PcieCfgOut32 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT32 *)Data));
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  } else {
+    switch (Width) {
+    case 1:
+      Ac01PcieCfgIn8 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT8 *)Data);
+      break;
+
+    case 2:
+      Ac01PcieCfgIn16 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT16 *)Data);
+      if (Reg == 0xAE && (*((UINT16 *)Data)) == 0xFFFF) {
+        SerialPrint ("PANIC due to PCIE RC:%d link issue\n", RC->ID);
+        // Loop forever waiting for failsafe/watch dog time out
+        do {
+        } while (1);
+      }
+      break;
+
+    case 4:
+      Ac01PcieCfgIn32 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT32 *)Data);
+      break;
+
+    default:
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+VOID
+Ac01PcieCorePollLinkUp (
+  VOID
+  )
+{
+  INTN    RCIndex, PcieIndex, i;
+  BOOLEAN IsNextRoundNeeded = FALSE, NextRoundNeeded;
+  UINT64  PrevTick, CurrTick, ElapsedCycle;
+  UINT64  TimerTicks64;
+  UINT8   ReInit;
+  INT8    FailedPciePtr[MAX_PCIE_B];
+  INT8    FailedPcieCount;
+
+  ReInit = 0;
+
+_link_polling:
+  NextRoundNeeded = 0;
+  //
+  // It is not guaranteed the timer service is ready prior to PCI Dxe.
+  // Calculate system ticks for link training.
+  //
+  TimerTicks64 = ArmGenericTimerGetTimerFreq (); /* 1 Second */
+  PrevTick = ArmGenericTimerGetSystemCount ();
+  ElapsedCycle = 0;
+
+  do {
+    // Update timer
+    CurrTick = ArmGenericTimerGetSystemCount ();
+    if (CurrTick < PrevTick) {
+      ElapsedCycle += (UINT64)(~0x0ULL) - PrevTick;
+      PrevTick = 0;
+    }
+    ElapsedCycle += (CurrTick - PrevTick);
+    PrevTick = CurrTick;
+  } while (ElapsedCycle < TimerTicks64);
+
+  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+    Ac01PcieCoreUpdateLink (&RCList[RCIndex], &IsNextRoundNeeded, FailedPciePtr, &FailedPcieCount);
+    if (IsNextRoundNeeded) {
+      NextRoundNeeded = 1;
+    }
+  }
+
+  if (NextRoundNeeded && ReInit < MAX_REINIT) {
+    // Timer is up. Give another chance to re-program controller
+    ReInit++;
+    for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+      Ac01PcieCoreUpdateLink (&RCList[RCIndex], &IsNextRoundNeeded, FailedPciePtr, &FailedPcieCount);
+      if (IsNextRoundNeeded) {
+        for (i = 0; i < FailedPcieCount; i++) {
+          PcieIndex = FailedPciePtr[i];
+          if (PcieIndex == -1) {
+            continue;
+          }
+
+          // Some controller still observes link-down. Re-init controller
+          Ac01PcieCoreSetupRC (&RCList[RCIndex], 1, PcieIndex);
+        }
+      }
+    }
+
+    goto _link_polling;
+  }
+}
+
+/**
+  Prepare to end PCIE core BSP driver
+**/
+VOID
+Ac01PcieEnd (
+  VOID
+  )
+{
+  Ac01PcieCorePollLinkUp ();
+}
+
+/**
+  Callback funciton for EndEnumeration notification from PCI stack.
+
+  @param  HBIndex               Index to identify of PCIE Host bridge.
+  @param  RBIndex               Index to identify of underneath PCIE Root bridge.
+  @param  Phase                 The phase of enumeration as informed from PCI stack.
+**/
+VOID
+Ac01PcieHostBridgeNotifyPhase (
+  IN UINTN                                         HBIndex,
+  IN UINTN                                         RBIndex,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
+  )
+{
+  AC01_RC *RC;
+  UINTN   RCIndex;
+
+  RCIndex = GetRCIndex (HBIndex, RBIndex);
+  RC = &RCList[RCIndex];
+
+  switch (Phase) {
+  case EfiPciHostBridgeEndEnumeration:
+    Ac01PcieCoreEndEnumeration (RC);
+    break;
+
+  case EfiPciHostBridgeBeginEnumeration:
+  case EfiPciHostBridgeBeginBusAllocation:
+  case EfiPciHostBridgeEndBusAllocation:
+  case EfiPciHostBridgeBeginResourceAllocation:
+  case EfiPciHostBridgeAllocateResources:
+  case EfiPciHostBridgeSetResources:
+  case EfiPciHostBridgeFreeResources:
+  case EfiPciHostBridgeEndResourceAllocation:
+  case EfiMaxPciHostBridgeEnumerationPhase:
+    break;
+  }
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
new file mode 100644
index 000000000000..dae7ee4fced1
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
@@ -0,0 +1,610 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <AcpiHeader.h>
+#include <IndustryStandard/Acpi30.h>
+#include <IndustryStandard/IoRemappingTable.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PcieBoardLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Platform/Ac01.h>
+#include <Protocol/AcpiTable.h>
+
+#include "Pcie.h"
+#include "PcieCore.h"
+
+#define ACPI_RESOURCE_NAME_ADDRESS16            0x88
+#define ACPI_RESOURCE_NAME_ADDRESS64            0x8A
+
+#define RCA_NUM_TBU_PMU         6
+#define RCB_NUM_TBU_PMU         10
+
+STATIC UINT32 gTbuPmuIrqArray[] = { SMMU_TBU_PMU_IRQ_START_ARRAY };
+STATIC UINT32 gTcuPmuIrqArray[] = { SMMU_TCU_PMU_IRQ_START_ARRAY };
+
+#pragma pack(1)
+typedef struct
+{
+  UINT64 ullBaseAddress;
+  UINT16 usSegGroupNum;
+  UINT8  ucStartBusNum;
+  UINT8  ucEndBusNum;
+  UINT32 Reserved2;
+} EFI_MCFG_CONFIG_STRUCTURE;
+
+typedef struct
+{
+  EFI_ACPI_DESCRIPTION_HEADER Header;
+  UINT64                      Reserved1;
+} EFI_MCFG_TABLE_CONFIG;
+
+typedef struct {
+  UINT64 AddressGranularity;
+  UINT64 AddressMin;
+  UINT64 AddressMax;
+  UINT64 AddressTranslation;
+  UINT64 RangeLength;
+} QWordMemory;
+
+typedef struct ResourceEntry {
+  UINT8  ResourceType;
+  UINT16 ResourceSize;
+  UINT8  Attribute;
+  UINT8  Byte0;
+  UINT8  Byte1;
+  VOID   *ResourcePtr;
+} RESOURCE;
+
+STATIC QWordMemory Qmem[] = {
+  { AC01_PCIE_RCA2_QMEM },
+  { AC01_PCIE_RCA3_QMEM },
+  { AC01_PCIE_RCB0_QMEM },
+  { AC01_PCIE_RCB1_QMEM },
+  { AC01_PCIE_RCB2_QMEM },
+  { AC01_PCIE_RCB3_QMEM }
+};
+
+typedef struct {
+  EFI_ACPI_6_0_IO_REMAPPING_NODE Node;
+  UINT64                         Base;
+  UINT32                         Flags;
+  UINT32                         Reserved;
+  UINT64                         VatosAddress;
+  UINT32                         Model;
+  UINT32                         Event;
+  UINT32                         Pri;
+  UINT32                         Gerr;
+  UINT32                         Sync;
+  UINT32                         ProximityDomain;
+  UINT32                         DeviceIdMapping;
+} EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE;
+
+typedef struct {
+  EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE Node;
+  UINT32                             ItsIdentifier;
+} AC01_ITS_NODE;
+
+
+typedef struct {
+  EFI_ACPI_6_0_IO_REMAPPING_RC_NODE  Node;
+  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE RcIdMapping;
+} AC01_RC_NODE;
+
+typedef struct {
+  EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE Node;
+  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE   InterruptMsiMapping;
+  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE   InterruptMsiMappingSingle;
+} AC01_SMMU_NODE;
+
+typedef struct {
+  EFI_ACPI_6_0_IO_REMAPPING_TABLE Iort;
+  AC01_ITS_NODE                   ItsNode[2];
+  AC01_RC_NODE                    RcNode[2];
+  AC01_SMMU_NODE                  SmmuNode[2];
+} AC01_IO_REMAPPING_STRUCTURE;
+
+#define FIELD_OFFSET(type, name)            __builtin_offsetof (type, name)
+#define __AC01_ID_MAPPING(In, Num, Out, Ref, Flags)    \
+  {                                                    \
+    In,                                                \
+    Num,                                               \
+    Out,                                               \
+    FIELD_OFFSET (AC01_IO_REMAPPING_STRUCTURE, Ref),   \
+    Flags                                              \
+  }
+
+EFI_STATUS
+EFIAPI
+AcpiPatchPciMem32 (
+  INT8 *PciSegEnabled
+  )
+{
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
+  EFI_STATUS            Status;
+  UINTN                 Idx, Ix;
+  EFI_ACPI_HANDLE       TableHandle, SegHandle;
+  CHAR8                 Buffer[MAX_ACPI_NODE_PATH];
+  CHAR8                 *KB, *B;
+  EFI_ACPI_DATA_TYPE    DataType;
+  UINTN                 DataSize, Mem32;
+  RESOURCE              *Rs;
+  QWordMemory           *Qm;
+  UINT8                 Segment;
+
+  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("Unable to locate ACPI table protocol Guid\n");
+    return Status;
+  }
+
+  /* Open DSDT Table */
+  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("Unable to open DSDT table\n");
+    return Status;
+  }
+
+  for (Idx = 0; PciSegEnabled[Idx] != -1; Idx++) {
+    if (PciSegEnabled[Idx] > SOCKET0_LAST_RC) { /* Physical segment */
+      break;
+    }
+    if (PciSegEnabled[Idx] < SOCKET0_FIRST_RC) {
+      continue;
+    }
+
+    /* DSDT PCI devices to use Physical segment */
+    AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.PCI%x.RBUF", PciSegEnabled[Idx]);
+    Status = AcpiTableProtocol->FindPath (TableHandle, (VOID *)Buffer, &SegHandle);
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    for (Ix = 0; Ix < 3; Ix++) {
+      Status = AcpiTableProtocol->GetOption (
+                                    SegHandle,
+                                    Ix,
+                                    &DataType,
+                                    (VOID *)&B,
+                                    &DataSize
+                                    );
+      KB = B;
+      if (EFI_ERROR (Status)) {
+        continue;
+      }
+
+      if (Ix == 0) { /* B[0] == AML_NAME_OP */
+        if (!((DataSize == 1) && (DataType == EFI_ACPI_DATA_TYPE_OPCODE))) {
+          break;
+        }
+      } else if (Ix == 1) { /* *B == "RBUF"  */
+        if (!((DataSize == 4) && (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING))) {
+          break;
+        }
+      } else { /* Ix:2 11 42 07 0A 6E 88 ... */
+        if (DataType != EFI_ACPI_DATA_TYPE_CHILD) {
+          break;
+        }
+
+        KB += 5; /* Point to Resource type */
+        Rs = (RESOURCE *)KB;
+        Mem32 = 0;
+        while ((Mem32 == 0) && ((KB - B) < DataSize)) {
+          if (Rs->ResourceType == ACPI_RESOURCE_NAME_ADDRESS16) {
+            KB += (Rs->ResourceSize + 3); /* Type + Size */
+            Rs = (RESOURCE *)KB;
+          } else if (Rs->ResourceType == ACPI_RESOURCE_NAME_ADDRESS64) {
+
+            if (Rs->Attribute == 0x00) { /* The first QWordMemory */
+              Mem32 = 1;
+              Segment = PciSegEnabled[Idx] - 2;
+              Qm = (QWordMemory *)&(Rs->ResourcePtr);
+              *Qm = Qmem[Segment]; /* Physical segment */
+            }
+            KB += (Rs->ResourceSize + 3); /* Type + Size */
+            Rs = (RESOURCE *)KB;
+          }
+        }
+        if (Mem32 != 0) {
+          Status = AcpiTableProtocol->SetOption (
+                                        SegHandle,
+                                        Ix,
+                                        (VOID *)B,
+                                        DataSize
+                                        );
+        }
+      }
+    }
+  }
+  AcpiTableProtocol->Close (TableHandle);
+  /* Update DSDT Checksum */
+  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
+
+  return Status;
+}
+
+VOID
+ConstructMcfg (
+  VOID   *McfgPtr,
+  INT8   *PciSegEnabled,
+  UINT32 McfgCount
+  )
+{
+  EFI_MCFG_TABLE_CONFIG     McfgHeader = {
+    {
+      EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+      McfgCount,
+      1,
+      0x00,                        // Checksum will be updated at runtime
+      EFI_ACPI_OEM_ID,
+      EFI_ACPI_OEM_TABLE_ID,
+      EFI_ACPI_OEM_REVISION,
+      EFI_ACPI_CREATOR_ID,
+      EFI_ACPI_CREATOR_REVISION
+    },
+    0x0000000000000000,            // Reserved
+  };
+  EFI_MCFG_CONFIG_STRUCTURE TMcfg = {
+    .ullBaseAddress = 0,
+    .usSegGroupNum = 0,
+    .ucStartBusNum = 0,
+    .ucEndBusNum = 255,
+    .Reserved2 = 0,
+  };
+  UINT32                    Idx;
+  VOID                      *TMcfgPtr = McfgPtr;
+  AC01_RC                   *Rc;
+
+  CopyMem (TMcfgPtr, &McfgHeader, sizeof (EFI_MCFG_TABLE_CONFIG));
+  TMcfgPtr += sizeof (EFI_MCFG_TABLE_CONFIG);
+  for (Idx = 0; PciSegEnabled[Idx] != -1; Idx++) {
+    Rc = GetRCList (PciSegEnabled[Idx]); /* Logical */
+    TMcfg.ullBaseAddress = Rc->MmcfgAddr;
+    TMcfg.usSegGroupNum = Rc->Logical;
+    CopyMem (TMcfgPtr, &TMcfg, sizeof (EFI_MCFG_CONFIG_STRUCTURE));
+    TMcfgPtr += sizeof (EFI_MCFG_CONFIG_STRUCTURE);
+  }
+}
+
+EFI_STATUS
+EFIAPI
+AcpiInstallMcfg (
+  INT8 *PciSegEnabled
+  )
+{
+  UINT32                  RcCount, McfgCount;
+  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+  UINTN                   TableKey;
+  EFI_STATUS              Status;
+  VOID                    *McfgPtr;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("MCFG: Unable to locate ACPI table entry\n");
+    return Status;
+  }
+  for (RcCount = 0; PciSegEnabled[RcCount] != -1; RcCount++) {
+  }
+  McfgCount = sizeof (EFI_MCFG_TABLE_CONFIG) + sizeof (EFI_MCFG_CONFIG_STRUCTURE) * RcCount;
+  McfgPtr = AllocateZeroPool (McfgCount);
+  if (McfgPtr == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ConstructMcfg (McfgPtr, PciSegEnabled, McfgCount);
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                McfgPtr,
+                                McfgCount,
+                                &TableKey
+                                );
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("MCFG: Unable to install MCFG table entry\n");
+  }
+  FreePool (McfgPtr);
+  return Status;
+}
+
+STATIC
+VOID
+ConstructIort (
+  VOID   *IortPtr,
+  UINT32 RcCount,
+  UINT32 SmmuPmuAgentCount,
+  UINT32 HeaderCount,
+  INT8   *PciSegEnabled
+  )
+{
+  EFI_ACPI_6_0_IO_REMAPPING_TABLE TIort = {
+    .Header = __ACPI_HEADER (
+                EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE,
+                AC01_IO_REMAPPING_STRUCTURE,
+                EFI_ACPI_IO_REMAPPING_TABLE_REVISION
+                ),
+    .NumNodes = (3 * RcCount) + SmmuPmuAgentCount,
+    .NodeOffset = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE),
+    0
+  };
+
+  AC01_ITS_NODE TItsNode = {
+    .Node = {
+      EFI_ACPI_IORT_TYPE_ITS_GROUP,
+      sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE) + 4,
+      0x0,
+      0x0,
+      0x0,
+      0x0,
+      .NumItsIdentifiers = 1,
+    },
+    .ItsIdentifier = 1,
+  };
+
+  AC01_RC_NODE TRcNode = {
+    {
+      {
+        EFI_ACPI_IORT_TYPE_ROOT_COMPLEX,
+        sizeof (AC01_RC_NODE),
+        0x1,
+        0x0,
+        0x1,
+        FIELD_OFFSET (AC01_RC_NODE, RcIdMapping),
+      },
+      EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
+      0x0,
+      0x0,
+      EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM |
+      EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS,
+      EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
+      .PciSegmentNumber = 0,
+      .MemoryAddressSize = 64,
+    },
+    __AC01_ID_MAPPING (0x0, 0xffff, 0x0, SmmuNode, 0),
+  };
+
+  AC01_SMMU_NODE TSmmuNode = {
+    {
+      {
+        EFI_ACPI_IORT_TYPE_SMMUv3,
+        sizeof (AC01_SMMU_NODE),
+        0x2,  /* Revision */
+        0x0,
+        0x2,  /* Mapping Count */
+        FIELD_OFFSET (AC01_SMMU_NODE, InterruptMsiMapping),
+      },
+      .Base = 0,
+      EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
+      0,
+      0,
+      0,
+      0,
+      0,
+      0x0,
+      0x0,
+      0,
+      .DeviceIdMapping = 1,
+    },
+    __AC01_ID_MAPPING (0x0, 0xffff, 0, SmmuNode, 0),
+    __AC01_ID_MAPPING (0x0, 0x1, 0, SmmuNode, 1),
+  };
+
+  EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE TPmcgNode = {
+    {
+      EFI_ACPI_IORT_TYPE_PMCG,
+      sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE),
+      0x1,
+      0x0,
+      0x0,
+      0x0,
+    },
+    0, /* Page 0 Base. Need to be filled */
+    0, /* GSIV. Need to be filled */
+    0, /* Node reference. Need to be filled */
+    0, /* Page 1 Base. Need to be filled. */
+  };
+
+  UINT32  Idx, Idx1, SmmuNodeOffset[MAX_AC01_PCIE_ROOT_COMPLEX];
+  VOID    *TIortPtr = IortPtr, *SmmuPtr, *PmcgPtr;
+  UINT32  ItsOffset[MAX_AC01_PCIE_ROOT_COMPLEX];
+  AC01_RC *Rc;
+  UINTN   NumTbuPmu;
+
+  TIort.Header.Length = HeaderCount;
+  CopyMem (TIortPtr, &TIort, sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE));
+  TIortPtr += sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE);
+  for (Idx = 0; Idx < RcCount; Idx++) {
+    ItsOffset[Idx] = TIortPtr - IortPtr;
+    TItsNode.ItsIdentifier = PciSegEnabled[Idx]; /* Physical */
+    CopyMem (TIortPtr, &TItsNode, sizeof (AC01_ITS_NODE));
+    TIortPtr += sizeof (AC01_ITS_NODE);
+  }
+
+  SmmuPtr = TIortPtr + RcCount * sizeof (AC01_RC_NODE);
+  PmcgPtr = SmmuPtr + RcCount * sizeof (AC01_SMMU_NODE);
+  for (Idx = 0; Idx < RcCount; Idx++) {
+    SmmuNodeOffset[Idx] = SmmuPtr - IortPtr;
+    Rc = GetRCList (PciSegEnabled[Idx]); /* Physical RC */
+    TSmmuNode.Node.Base = Rc->TcuAddr;
+    TSmmuNode.InterruptMsiMapping.OutputBase = PciSegEnabled[Idx] << 16;
+    TSmmuNode.InterruptMsiMapping.OutputReference = ItsOffset[Idx];
+    TSmmuNode.InterruptMsiMappingSingle.OutputBase = PciSegEnabled[Idx] << 16;
+    TSmmuNode.InterruptMsiMappingSingle.OutputReference = ItsOffset[Idx];
+    CopyMem (SmmuPtr, &TSmmuNode, sizeof (AC01_SMMU_NODE));
+    SmmuPtr += sizeof (AC01_SMMU_NODE);
+
+    if (!SmmuPmuAgentCount) {
+      continue;
+    }
+
+    /* Add PMCG nodes */
+    if (Rc->Type == RCA) {
+      NumTbuPmu = RCA_NUM_TBU_PMU;
+    } else {
+      NumTbuPmu = RCB_NUM_TBU_PMU;
+    }
+    for (Idx1 = 0; Idx1 < NumTbuPmu; Idx1++) {
+      TPmcgNode.Base = Rc->TcuAddr;
+      if (NumTbuPmu == RCA_NUM_TBU_PMU) {
+        switch (Idx1) {
+        case 0:
+          TPmcgNode.Base += 0x40000;
+          break;
+
+        case 1:
+          TPmcgNode.Base += 0x60000;
+          break;
+
+        case 2:
+          TPmcgNode.Base += 0xA0000;
+          break;
+
+        case 3:
+          TPmcgNode.Base += 0xE0000;
+          break;
+
+        case 4:
+          TPmcgNode.Base += 0x100000;
+          break;
+
+        case 5:
+          TPmcgNode.Base += 0x140000;
+          break;
+        }
+      } else {
+       switch (Idx1) {
+        case 0:
+          TPmcgNode.Base += 0x40000;
+          break;
+
+        case 1:
+          TPmcgNode.Base += 0x60000;
+          break;
+
+        case 2:
+          TPmcgNode.Base += 0xA0000;
+          break;
+
+        case 3:
+          TPmcgNode.Base += 0xE0000;
+          break;
+
+        case 4:
+          TPmcgNode.Base += 0x120000;
+          break;
+
+        case 5:
+          TPmcgNode.Base += 0x160000;
+          break;
+
+        case 6:
+          TPmcgNode.Base += 0x180000;
+          break;
+
+        case 7:
+          TPmcgNode.Base += 0x1C0000;
+          break;
+
+        case 8:
+          TPmcgNode.Base += 0x200000;
+          break;
+
+        case 9:
+          TPmcgNode.Base += 0x240000;
+          break;
+        }
+      }
+      TPmcgNode.Page1Base = TPmcgNode.Base + 0x12000;
+      TPmcgNode.Base += 0x2000;
+      TPmcgNode.NodeReference = SmmuNodeOffset[Idx];
+      TPmcgNode.OverflowInterruptGsiv = gTbuPmuIrqArray[PciSegEnabled[Idx]] + Idx1;
+      CopyMem (PmcgPtr, &TPmcgNode, sizeof (TPmcgNode));
+      PmcgPtr += sizeof (TPmcgNode);
+    }
+
+    /* TCU PMCG */
+    TPmcgNode.Base = Rc->TcuAddr;
+    TPmcgNode.Base += 0x2000;
+    TPmcgNode.Page1Base = Rc->TcuAddr + 0x12000;
+    TPmcgNode.NodeReference = SmmuNodeOffset[Idx];
+    TPmcgNode.OverflowInterruptGsiv = gTcuPmuIrqArray[PciSegEnabled[Idx]];
+    CopyMem (PmcgPtr, &TPmcgNode, sizeof (TPmcgNode));
+    PmcgPtr += sizeof (TPmcgNode);
+  }
+
+  for (Idx = 0; Idx < RcCount; Idx++) {
+    TRcNode.Node.PciSegmentNumber = GetRCList (PciSegEnabled[Idx])->Logical; /* Logical */
+    TRcNode.RcIdMapping.OutputReference = SmmuNodeOffset[Idx];
+    CopyMem (TIortPtr, &TRcNode, sizeof (AC01_RC_NODE));
+    TIortPtr += sizeof (AC01_RC_NODE);
+  }
+}
+
+EFI_STATUS
+EFIAPI
+AcpiInstallIort (
+  INT8 *PciSegEnabled
+  )
+{
+  UINT32                  RcCount, SmmuPmuAgentCount, TotalCount;
+  VOID                    *IortPtr;
+  UINTN                   TableKey;
+  EFI_STATUS              Status;
+  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
+
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiTableProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("IORT: Unable to locate ACPI table entry\n");
+    return Status;
+  }
+
+  for (RcCount = 0, SmmuPmuAgentCount = 0; PciSegEnabled[RcCount] != -1; RcCount++) {
+    if ((GetRCList (PciSegEnabled[RcCount]))->Type == RCA) {
+      SmmuPmuAgentCount += RCA_NUM_TBU_PMU;
+    } else {
+      SmmuPmuAgentCount += RCB_NUM_TBU_PMU;
+    }
+    SmmuPmuAgentCount += 1; /* Only 1 TCU */
+  }
+
+  if (!PcieBoardCheckSmmuPmuEnabled ()) {
+    SmmuPmuAgentCount = 0;
+  }
+
+  TotalCount = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE) +
+               RcCount * (sizeof (AC01_ITS_NODE) + sizeof (AC01_RC_NODE) + sizeof (AC01_SMMU_NODE)) +
+               SmmuPmuAgentCount * sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE);
+
+  IortPtr = AllocateZeroPool (TotalCount);
+  if (IortPtr == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  ConstructIort (IortPtr, RcCount, SmmuPmuAgentCount, TotalCount, PciSegEnabled);
+
+  Status = AcpiTableProtocol->InstallAcpiTable (
+                                AcpiTableProtocol,
+                                IortPtr,
+                                TotalCount,
+                                &TableKey
+                                );
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("IORT: Unable to install IORT table entry\n");
+  }
+  FreePool (IortPtr);
+  return Status;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib library instance
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (14 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 22:45   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
                   ` (18 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provides basic features like:
* Screen menu to change bifurcation setting of each Root Complex. Note
  that we can only change the option for Root Complex which doesn't have
  default value in the BoardSetting.
* Parsing the BoardSetting and coordinate with saved setting to enable
  corresponding PCIe controller of each Root Complex.
* Config speed and lane of enabled controller.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                 |    3 +
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf    |   60 ++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h       |   89 ++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h   |  138 +++
 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h     |  102 ++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr             |  212 ++++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c         |  438 ++++++++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c   |  327 ++++++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c   | 1120 ++++++++++++++++++++
 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni |   99 ++
 10 files changed, 2588 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 0d79673ce50a..a372a4e0078b 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -40,6 +40,9 @@ [LibraryClasses]
   ##  @libraryclass  Defines a set of methods to initialize Pcie
   PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h
 
+  ##  @libraryclass  Defines a set of miscellaneous PCIe functions
+  PcieBoardLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
+
   ##  @libraryclass  Defines a set of methods to access flash memory.
   FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
 
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
new file mode 100644
index 000000000000..6be78f8936d7
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
@@ -0,0 +1,60 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PcieBoardLib
+  FILE_GUID                      = 062191A6-E113-4FD6-84C7-E400B4B34759
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PcieBoardLib
+
+[Sources]
+  PcieBoard.c
+  PcieBoardCommon.c
+  PcieBoardScreen.c
+  PcieBoardScreen.h
+  PcieBoardScreen.uni
+  NVDataStruc.h
+  Vfr.vfr
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  DevicePathLib
+  GpioLib
+  HiiLib
+  HobLib
+  MemoryAllocationLib
+  SystemFirmwareInterfaceLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiHiiStringProtocolGuid                     ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+  gEfiHiiDatabaseProtocolGuid                   ## CONSUMES
+  gEfiConfigKeywordHandlerProtocolGuid          ## CONSUMES
+
+[Guids]
+  gEfiIfrTianoGuid                              ## CONSUMES
+  gPlatformManagerFormsetGuid                   ## CONSUMES
+  gPlatformHobGuid                              ## CONSUMES
+
+[Depex]
+  TRUE
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
new file mode 100644
index 000000000000..f94f12d968fd
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
@@ -0,0 +1,89 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVDATASTRUC_H_
+#define NVDATASTRUC_H_
+
+#define MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX 16
+
+#define PCIE_VARSTORE_NAME        L"PcieIfrNVData"
+#define PCIE_VARSTORE_ID          0x1234
+#define PCIE_FORM_ID              0x1235
+#define PCIE_RC0_FORM_ID          0x1236
+#define PCIE_RC1_FORM_ID          0x1237
+#define PCIE_RC2_FORM_ID          0x1238
+#define PCIE_RC3_FORM_ID          0x1239
+#define PCIE_RC4_FORM_ID          0x123A
+#define PCIE_RC5_FORM_ID          0x123B
+#define PCIE_RC6_FORM_ID          0x123C
+#define PCIE_RC7_FORM_ID          0x123D
+#define PCIE_RC8_FORM_ID          0x123E
+#define PCIE_RC9_FORM_ID          0x123F
+#define PCIE_RC10_FORM_ID         0x1240
+#define PCIE_RC11_FORM_ID         0x1241
+#define PCIE_RC12_FORM_ID         0x1242
+#define PCIE_RC13_FORM_ID         0x1243
+#define PCIE_RC14_FORM_ID         0x1244
+#define PCIE_RC15_FORM_ID         0x1245
+#define PCIE_FORM_SET_GUID        { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98,  0x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } }
+
+#define PCIE_GOTO_ID_BASE         0x8040
+
+#pragma pack(1)
+
+//
+// NV data structure definition
+//
+typedef struct {
+  BOOLEAN RCStatus[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
+  UINT8   RCBifurLo[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
+  UINT8   RCBifurHi[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
+  UINT32  SmmuPmu;
+} PCIE_VARSTORE_DATA;
+
+//
+// Labels definition
+//
+#define LABEL_UPDATE             0x2223
+#define LABEL_END                0x2224
+#define LABEL_RC0_UPDATE         0x2225
+#define LABEL_RC0_END            0x2226
+#define LABEL_RC1_UPDATE         0x2227
+#define LABEL_RC1_END            0x2228
+#define LABEL_RC2_UPDATE         0x2229
+#define LABEL_RC2_END            0x222A
+#define LABEL_RC3_UPDATE         0x222B
+#define LABEL_RC3_END            0x222C
+#define LABEL_RC4_UPDATE         0x222D
+#define LABEL_RC4_END            0x222E
+#define LABEL_RC5_UPDATE         0x222F
+#define LABEL_RC5_END            0x2230
+#define LABEL_RC6_UPDATE         0x2231
+#define LABEL_RC6_END            0x2232
+#define LABEL_RC7_UPDATE         0x2233
+#define LABEL_RC7_END            0x2234
+#define LABEL_RC8_UPDATE         0x2235
+#define LABEL_RC8_END            0x2236
+#define LABEL_RC9_UPDATE         0x2237
+#define LABEL_RC9_END            0x2238
+#define LABEL_RC10_UPDATE        0x2239
+#define LABEL_RC10_END           0x223A
+#define LABEL_RC11_UPDATE        0x223B
+#define LABEL_RC11_END           0x223C
+#define LABEL_RC12_UPDATE        0x223D
+#define LABEL_RC12_END           0x223E
+#define LABEL_RC13_UPDATE        0x223F
+#define LABEL_RC13_END           0x2240
+#define LABEL_RC14_UPDATE        0x2241
+#define LABEL_RC14_END           0x2242
+#define LABEL_RC15_UPDATE        0x2243
+#define LABEL_RC15_END           0x2244
+
+#pragma pack()
+
+#endif
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
new file mode 100644
index 000000000000..c5c50060870c
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
@@ -0,0 +1,138 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_SCREEN_H_
+#define PCIE_SCREEN_H_
+
+#include <Guid/MdeModuleHii.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/FormBrowser2.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigKeyword.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+
+#include "NVDataStruc.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 PcieDxeStrings[];
+
+#define MAX_EDITABLE_ELEMENTS 3
+#define PCIE_RC0_STATUS_OFFSET  \
+  OFFSET_OF (PCIE_VARSTORE_DATA, RCStatus[0])
+#define PCIE_RC0_BIFUR_LO_OFFSET  \
+  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurLo[0])
+#define PCIE_RC0_BIFUR_HI_OFFSET  \
+  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurHi[0])
+#define PCIE_SMMU_PMU_OFFSET  \
+  OFFSET_OF (PCIE_VARSTORE_DATA, SmmuPmu)
+
+#define PCIE_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'E')
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE         DriverHandle;
+  EFI_HII_HANDLE     HiiHandle;
+  PCIE_VARSTORE_DATA VarStoreConfig;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
+  EFI_HII_STRING_PROTOCOL             *HiiString;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
+  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} PCIE_SCREEN_PRIVATE_DATA;
+
+typedef union {
+  UINT16 VAR_ID;
+  struct _PCIE_VAR_ID {
+    UINT16 PciDevIndex     : 12;
+    UINT16 DataType        : 3;
+    UINT16 Always1         : 1;
+  } IdField;
+} PCIE_VAR_ID;
+
+typedef struct {
+  UINTN         PciDevIdx;
+  EFI_STRING_ID GotoStringId;
+  EFI_STRING_ID GotoHelpStringId;
+  UINT16        GotoKey;
+  BOOLEAN       ShowItem;
+} PCIE_SETUP_GOTO_DATA;
+
+typedef struct {
+  VOID               *StartOpCodeHandle;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  EFI_IFR_GUID_LABEL *EndLabel;
+
+} PCIE_IFR_INFO;
+
+#define PCIE_SCREEN_PRIVATE_FROM_THIS(a)  \
+  CR (a, PCIE_SCREEN_PRIVATE_DATA, ConfigAccess, PCIE_SCREEN_PRIVATE_DATA_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+UINT8
+PcieRCDevMapLoDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  );
+
+UINT8
+PcieRCDevMapHiDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  );
+
+BOOLEAN
+PcieRCActiveDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  );
+
+#endif /* PCIE_SCREEN_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
new file mode 100644
index 000000000000..bff5b62ba13b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
@@ -0,0 +1,102 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_BOARD_LIB_H_
+#define PCIE_BOARD_LIB_H_
+
+#include "Pcie.h"
+
+/**
+
+  Check if a PCIE port enabled in the board configuration.
+
+  @param  Index                     The port index.
+
+  @retval                           TRUE if the port enabled, otherwise FALSE.
+
+**/
+BOOLEAN
+PcieBoardCheckSysSlotEnabled (
+  IN UINTN Index
+  );
+
+VOID
+PcieBoardGetRCSegmentNumber (
+  IN  AC01_RC *RC,
+  OUT UINTN   *SegmentNumber
+  );
+
+/**
+
+  Check if SMM PMU enabled in board screen
+
+  @retval                           TRUE if the SMMU PMU enabled, otherwise FALSE.
+
+**/
+BOOLEAN
+PcieBoardCheckSmmuPmuEnabled (
+  VOID
+  );
+
+/**
+
+  Build UEFI menu.
+
+  @param  ImageHandle               Handle.
+  @param  SystemTable               Pointer to System Table.
+  @param  RCList                    List of Root Complex with properties.
+
+  @retval                           EFI_SUCCESS if successful, otherwise EFI_ERROR.
+
+**/
+EFI_STATUS
+PcieBoardScreenInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable,
+  IN AC01_RC          *RCList
+  );
+
+BOOLEAN
+IsEmptyRC (
+  IN AC01_RC *RC
+  );
+
+VOID
+PcieBoardSetupDevmap (
+  IN AC01_RC *RC
+  );
+
+VOID
+PcieBoardGetLaneAllocation (
+  IN AC01_RC *RC
+  );
+
+VOID
+PcieBoardGetSpeed (
+  IN AC01_RC *RC
+  );
+
+VOID
+PcieBoardParseRCParams (
+  IN AC01_RC *RC
+  );
+
+VOID
+PcieBoardAssertPerst (
+  AC01_RC *RC,
+  UINT32  PcieIndex,
+  UINT8   Bifurcation,
+  BOOLEAN isPullToHigh
+  );
+
+BOOLEAN
+PcieBoardCheckSmmuPmuEnabled (
+  VOID
+  );
+
+#endif /* PCIE_BOARD_LIB_H_ */
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
new file mode 100644
index 000000000000..a596d5ac9a92
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
@@ -0,0 +1,212 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "NVDataStruc.h"
+
+formset
+  guid    = PCIE_FORM_SET_GUID,
+  title   = STRING_TOKEN(STR_PCIE_FORM),
+  help    = STRING_TOKEN(STR_PCIE_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  //
+  // Define a variable Storage
+  //
+  varstore PCIE_VARSTORE_DATA,
+    varid = PCIE_VARSTORE_ID,
+    name  = PcieIfrNVData,
+    guid  = PCIE_FORM_SET_GUID;
+
+  form
+    formid = PCIE_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_FORM);
+
+    label LABEL_UPDATE;
+    // dynamic content here
+    label LABEL_END;
+  endform;
+
+  form
+    formid = PCIE_RC0_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC0_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC0_FORM);
+
+    label LABEL_RC0_UPDATE;
+    // dynamic content here
+    label LABEL_RC0_END;
+  endform;
+
+  form
+    formid = PCIE_RC1_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC1_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC1_FORM);
+
+    label LABEL_RC1_UPDATE;
+    // dynamic content here
+    label LABEL_RC1_END;
+  endform;
+
+  form
+    formid = PCIE_RC2_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC2_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC2_FORM);
+
+    label LABEL_RC2_UPDATE;
+    // dynamic content here
+    label LABEL_RC2_END;
+  endform;
+
+  form
+    formid = PCIE_RC3_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC3_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC3_FORM);
+
+    label LABEL_RC3_UPDATE;
+    // dynamic content here
+    label LABEL_RC3_END;
+  endform;
+
+  form
+    formid = PCIE_RC4_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC4_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC4_FORM);
+
+    label LABEL_RC4_UPDATE;
+    // dynamic content here
+    label LABEL_RC4_END;
+  endform;
+
+  form
+    formid = PCIE_RC5_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC5_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC5_FORM);
+
+    label LABEL_RC5_UPDATE;
+    // dynamic content here
+    label LABEL_RC5_END;
+  endform;
+
+  form
+    formid = PCIE_RC6_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC6_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC6_FORM);
+
+    label LABEL_RC6_UPDATE;
+    // dynamic content here
+    label LABEL_RC6_END;
+  endform;
+
+  form
+    formid = PCIE_RC7_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC7_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC7_FORM);
+
+    label LABEL_RC7_UPDATE;
+    // dynamic content here
+    label LABEL_RC7_END;
+  endform;
+
+  form
+    formid = PCIE_RC8_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC8_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC8_FORM);
+
+    label LABEL_RC8_UPDATE;
+    // dynamic content here
+    label LABEL_RC8_END;
+  endform;
+
+  form
+    formid = PCIE_RC9_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC9_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC9_FORM);
+
+    label LABEL_RC9_UPDATE;
+    // dynamic content here
+    label LABEL_RC9_END;
+  endform;
+
+  form
+    formid = PCIE_RC10_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC10_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC10_FORM);
+
+    label LABEL_RC10_UPDATE;
+    // dynamic content here
+    label LABEL_RC10_END;
+  endform;
+
+  form
+    formid = PCIE_RC11_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC11_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC11_FORM);
+
+    label LABEL_RC11_UPDATE;
+    // dynamic content here
+    label LABEL_RC11_END;
+  endform;
+
+  form
+    formid = PCIE_RC12_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC12_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC12_FORM);
+
+    label LABEL_RC12_UPDATE;
+    // dynamic content here
+    label LABEL_RC12_END;
+  endform;
+
+  form
+    formid = PCIE_RC13_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC13_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC13_FORM);
+
+    label LABEL_RC13_UPDATE;
+    // dynamic content here
+    label LABEL_RC13_END;
+  endform;
+
+  form
+    formid = PCIE_RC14_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC14_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC14_FORM);
+
+    label LABEL_RC14_UPDATE;
+    // dynamic content here
+    label LABEL_RC14_END;
+  endform;
+
+  form
+    formid = PCIE_RC15_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_RC15_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_RC15_FORM);
+
+    label LABEL_RC15_UPDATE;
+    // dynamic content here
+    label LABEL_RC15_END;
+  endform;
+
+endformset;
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
new file mode 100644
index 000000000000..c0c94d349b5b
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
@@ -0,0 +1,438 @@
+/** @file
+
+  Pcie board specific driver to handle asserting PERST signal to Endpoint
+  card and parsing NVPARAM board settings for bifurcation programming.
+
+  PERST asserting is via group of GPIO pins to CPLD as Platform Specification.
+
+  NVPARAM board settings is spec-ed within Firmware Interface Requirement.
+  Bifuration devmap is programmed before at SCP following the rule
+
+  Root Complex Type-A devmap settings (RP == Root Port)
+  -----------------------------------------
+  | RP0   | RP1  | RP2  | RP3  | Devmap   |
+  | (x16) | (x4) | (x8) | (x4) | (output) |
+  -------------------------------------------
+  |  Y    |  N   |  N   |  N   | 0        |
+  |  Y    |  N   |  Y   |  N   | 1        |
+  |  Y    |  N   |  Y   |  Y   | 2        |
+  |  Y    |  Y   |  Y   |  Y   | 3        |
+  -----------------------------------------
+
+  Root Complex Type-B LO (aka RCBxA) devmap settings (RP == Root Port)
+  ----------------------------------------
+  | RP0  | RP1  | RP2  | RP3  | Devmap   |
+  | (x8) | (x2) | (x4) | (x3) | (output) |
+  ----------------------------------------
+  |  Y   |  N   |  N   |  N   | 0        |
+  |  Y   |  N   |  Y   |  N   | 1        |
+  |  Y   |  N   |  Y   |  Y   | 2        |
+  |  Y   |  Y   |  Y   |  Y   | 3        |
+  ----------------------------------------
+
+  Root Complex Type-B LO (aka RCBxB) devmap settings (RP == Root Port)
+  ----------------------------------------
+  | RP4  | RP5  | RP6  | RP7  | Devmap   |
+  | (x8) | (x2) | (x4) | (x3) | (output) |
+  ----------------------------------------
+  |  Y   |  N   |  N   |  N   | 0        |
+  |  Y   |  N   |  Y   |  N   | 1        |
+  |  Y   |  N   |  Y   |  Y   | 2        |
+  |  Y   |  Y   |  Y   |  Y   | 3        |
+  ----------------------------------------
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PcieBoardLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <NVDataStruc.h>
+#include <NVParamDef.h>
+#include <Pcie.h>
+#include <PlatformInfoHob.h>
+
+#ifndef BIT
+#define BIT(nr)                         (1 << (nr))
+#endif
+
+extern CHAR16   VariableName[];
+extern EFI_GUID gPcieFormSetGuid;
+
+VOID
+EFIAPI
+PcieBoardLoadPreset (
+  IN AC01_RC *RC
+  )
+{
+  UINT32 Nv;
+  INTN   NvParam;
+  INTN   Ret;
+  INTN   i;
+
+  // Load default value
+  for (i = 0; i < MAX_PCIE_B; i++) {
+    RC->PresetGen3[i] = PRESET_INVALID;
+    RC->PresetGen4[i] = PRESET_INVALID;
+  }
+
+  // Load override value
+  if (RC->Socket == 0) {
+    if (RC->Type == RCA) {
+      if (RC->ID < 4) {
+        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NVPARAM_SIZE;
+      } else {
+        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
+      }
+    } else {
+      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
+    }
+  } else if (RC->Type == RCA) {
+    if (RC->ID < 4) {
+      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NVPARAM_SIZE;
+    } else {
+      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
+    }
+  } else {
+    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
+  }
+
+  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
+  if (Ret == EFI_SUCCESS) {
+    for (i = 0; i < 4; i++) {
+      RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
+    }
+  }
+
+  if (RC->Type == RCB) {
+    NvParam += NVPARAM_SIZE;
+    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
+    if (Ret == EFI_SUCCESS) {
+      for (i = 0; i < 4; i++) {
+        RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
+      }
+    }
+  }
+
+  if (RC->Socket == 0) {
+    if (RC->Type == RCA) {
+      if (RC->ID < 4) {
+        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NVPARAM_SIZE;
+      } else {
+        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
+      }
+    } else {
+      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
+    }
+  } else if (RC->Type == RCA) {
+    if (RC->ID < 4) {
+      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NVPARAM_SIZE;
+    } else {
+      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
+    }
+  } else {
+    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
+  }
+
+  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
+  if (Ret == EFI_SUCCESS) {
+    for (i = 0; i < 4; i++) {
+      RC->PresetGen4[i] = (Nv >> (8 * i)) & 0xFF;
+    }
+  }
+
+  if (RC->Type == RCB) {
+    NvParam += NVPARAM_SIZE;
+    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
+    if (Ret == EFI_SUCCESS) {
+      for (i = 0; i < 4; i++) {
+        RC->PresetGen4[i + 4] = (Nv >> (8 * i)) & 0xFF;
+      }
+    }
+  }
+}
+
+VOID
+EFIAPI
+PcieBoardParseRCParams (
+  IN AC01_RC *RC
+  )
+{
+  UINT32             Efuse;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  UINT8              PlatRCId;
+  EFI_STATUS         Status;
+  VOID               *Hob;
+  UINTN              BufferSize;
+  PCIE_VARSTORE_DATA VarStoreConfig = {
+    .RCStatus = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE,
+                 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE},
+    .RCBifurLo = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    .RCBifurHi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    .SmmuPmu = 0
+  };
+
+  PCIE_DEBUG ("%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID);
+
+  PlatRCId = RC->Socket * RCS_PER_SOCKET + RC->ID;
+  // Get RC activation status
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  VariableName,
+                  &gPcieFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &VarStoreConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    PCIE_DEBUG ("%a - Failed to read PCIE variable data from config store.\n", __FUNCTION__);
+  }
+
+  RC->Active = VarStoreConfig.RCStatus[PlatRCId];
+  RC->DevMapLo = VarStoreConfig.RCBifurLo[PlatRCId];
+  RC->DevMapHi = VarStoreConfig.RCBifurHi[PlatRCId];
+
+  PCIE_DEBUG (
+    "%a - Socket%d RC%d is %s\n",
+    __FUNCTION__,
+    RC->Socket,
+    RC->ID,
+    (RC->Active) ? "ACTIVE" : "INACTIVE"
+    );
+
+  if (!IsSlaveSocketActive () && RC->Socket == 1) {
+    RC->Active = FALSE;
+  }
+
+  if (RC->Active) {
+    //
+    // Consolidate with E-fuse
+    //
+    Efuse = 0;
+    Hob = GetFirstGuidHob (&gPlatformHobGuid);
+    if (Hob != NULL) {
+      PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+      Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
+      PCIE_DEBUG (
+        "RcDisableMask[0]: 0x%x [1]: 0x%x\n",
+        PlatformHob->RcDisableMask[0],
+        PlatformHob->RcDisableMask[1]
+        );
+
+      // Update errata flags for Ampere Altra
+      if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) {
+        if (PlatformHob->AHBCId[0] == 0x20100
+            || PlatformHob->AHBCId[0] == 0x21100
+            || (IsSlaveSocketActive ()
+                && (PlatformHob->AHBCId[1] == 0x20100
+                    || PlatformHob->AHBCId[1] == 0x21100)))
+        {
+          RC->Flags |= PCIE_ERRATA_SPEED1;
+          PCIE_DEBUG ("RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags);
+        }
+      }
+    }
+
+    RC->Active = (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALSE;
+  }
+
+  /* Load Gen3/Gen4 preset */
+  PcieBoardLoadPreset (RC);
+  PcieBoardGetLaneAllocation (RC);
+  PcieBoardSetupDevmap (RC);
+  PcieBoardGetSpeed (RC);
+}
+
+VOID
+EFIAPI
+PcieBoardReleaseAllPerst (
+  IN UINT8 SocketId
+  )
+{
+  UINT32 GpioIndex, GpioPin;
+
+  // Write 1 to all GPIO[16..21] to release all PERST
+  GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * SocketId + 16;
+  for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
+    GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
+  }
+}
+
+VOID
+EFIAPI
+PcieBoardAssertPerst (
+  AC01_RC *RC,
+  UINT32  PcieIndex,
+  UINT8   Bifurcation,
+  BOOLEAN isPullToHigh
+  )
+{
+  UINT32 GpioGroupVal, Val, GpioIndex, GpioPin;
+
+  /*
+   * For Post-silicon, Fansipan board is using GPIO combination (GPIO[16..21])
+   * to control CPLD.
+   * It should be follow PCIE RESET TABLE in Fansipan schematic.
+   *
+   * Depend on Bifurcation settings, will active corresponding PERST pin or not
+   */
+
+  if (RC->Type == RCA) {
+    switch (Bifurcation) {
+    case 0:                 // RCA_BIFURCATION_ONE_X16:
+      if (PcieIndex != 0) { // 1,2,3
+      }
+      break;
+
+    case 1:                                       // RCA_BIFURCATION_TWO_X8:
+      if ((PcieIndex == 1) || (PcieIndex == 3)) { // 1,3
+      }
+      break;
+
+    case 2:                 // RCA_BIFURCATION_ONE_X8_TWO_X4:
+      if (PcieIndex == 1) { // 1
+      }
+      break;
+
+    case 3: // RCA_BIFURCATION_FOUR_X4:
+      break;
+
+    default:
+      PCIE_DEBUG ("Invalid Bifurcation setting\n");
+      break;
+    }
+  } else { // RCB
+    switch (Bifurcation) {
+    case 0:                                       // RCB_BIFURCATION_ONE_X8:
+      if ((PcieIndex != 0) && (PcieIndex != 4)) { // 1,2,3,5,6,7
+      }
+      break;
+
+    case 1:                       // RCB_BIFURCATION_TWO_X4:
+      if ((PcieIndex % 2) != 0) { // 1,3,5,7
+      }
+      break;
+
+    case 2: // RCB_BIFURCATION_ONE_X4_TWO_X2:
+      if ((PcieIndex == 1) || (PcieIndex == 5)) {
+      }
+      break;
+
+    case 3: // RCB_BIFURCATION_FOUR_X2:
+      break;
+
+    default:
+      PCIE_DEBUG ("Invalid Bifurcation setting\n");
+      break;
+    }
+  }
+
+  if (!isPullToHigh) { // Pull PERST to Low
+    if (RC->Type == RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3
+      GpioGroupVal = 62 - RC->ID*4 - PcieIndex;
+    }
+    else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7
+      GpioGroupVal = 46 - (RC->ID - 4)*8 - PcieIndex;
+    }
+
+    GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16;
+    for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
+      // 6: Number of GPIO pins to control via CPLD
+      Val = (GpioGroupVal & 0x3F) & (1 << GpioIndex);
+      if (Val == 0) {
+        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_LOW);
+      } else {
+        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
+      }
+    }
+
+    // Keep reset as low as 100 ms as specification
+    MicroSecondDelay (100 * 1000);
+  } else { // Pull PERST to High
+    PcieBoardReleaseAllPerst (RC->Socket);
+  }
+}
+
+/**
+ * Overrride the segment number for a root complex with
+ * a board specific number.
+ **/
+VOID
+EFIAPI
+PcieBoardGetRCSegmentNumber (
+  IN  AC01_RC *RC,
+  OUT UINTN   *SegmentNumber
+  )
+{
+  if (RC->Socket == 0) {
+    if (RC->Type == RCA) {
+      switch (RC->ID) {
+      case 0:
+        *SegmentNumber = 12;
+        break;
+
+      case 1:
+        *SegmentNumber = 13;
+        break;
+
+      case 2:
+        *SegmentNumber = 1;
+        break;
+
+      case 3:
+        *SegmentNumber = 0;
+        break;
+
+        default:
+          *SegmentNumber = 16;
+      }
+    } else { /* Socket0, CCIX: RCA0 and RCA1 */
+      *SegmentNumber = RC->ID - 2;
+    }
+  } else { /* Socket1, CCIX: RCA0 and RCA1 */
+    if (RC->ID == 0 || RC->ID == 1) {
+      *SegmentNumber = 16;
+    } else {
+      *SegmentNumber = 4 + RC->ID;
+    }
+  }
+}
+
+BOOLEAN
+EFIAPI
+PcieBoardCheckSmmuPmuEnabled (
+  VOID
+  )
+{
+  EFI_GUID           PcieFormSetGuid = PCIE_FORM_SET_GUID;
+  PCIE_VARSTORE_DATA VarStoreConfig;
+  UINTN              BufferSize;
+  EFI_STATUS         Status;
+
+  // Get Buffer Storage data from EFI variable
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  PCIE_VARSTORE_NAME,
+                  &PcieFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &VarStoreConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return VarStoreConfig.SmmuPmu;
+}
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
new file mode 100644
index 000000000000..a8accbf53047
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
@@ -0,0 +1,327 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <NVParamDef.h>
+
+#include "Pcie.h"
+
+/* Host bridge registers */
+#define HBRCAPDMR    0x0
+#define HBRCBPDMR    0x4
+
+/* HBRCAPDMR */
+#define RCAPCIDEVMAP_SET(dst, src) \
+  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
+
+/* HBRCBPDMR */
+#define RCBPCIDEVMAPLO_SET(dst, src) \
+  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
+#define RCBPCIDEVMAPHI_SET(dst, src) \
+  (((dst) & ~0x70) | (((UINT32)(src) << 4) & 0x70))
+
+#define PCIE_GET_MAX_WIDTH(Pcie, Max) \
+  !((Pcie).MaxWidth) ? (Max) : MIN((Pcie).MaxWidth, (Max))
+
+BOOLEAN
+IsEmptyRC (
+  IN AC01_RC *RC
+  )
+{
+  INTN Idx;
+
+  for (Idx = PCIE_0; Idx < MAX_PCIE; Idx++) {
+    if (RC->Pcie[Idx].Active) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+VOID
+PcieBoardSetRCBifur (
+  IN AC01_RC *RC,
+  IN UINT8   RPStart,
+  IN UINT8   DevMap
+  )
+{
+  UINT8 MaxWidth;
+
+  if (RPStart != PCIE_0 && RPStart != PCIE_4) {
+    return;
+  }
+
+  if (RC->Type != RCB && RPStart == PCIE_4) {
+    return;
+  }
+
+  if (RC->Type == RCA && RC->Pcie[RPStart].MaxWidth == LNKW_X16) {
+    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X4;
+    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X8;
+    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X4;
+  }
+
+  if (RC->Type == RCB && RC->Pcie[RPStart].MaxWidth == LNKW_X8) {
+    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X2;
+    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X4;
+    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X2;
+  }
+
+  switch (DevMap) {
+  case 1:
+    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
+    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
+    RC->Pcie[RPStart + 1].Active = 0;
+    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
+    RC->Pcie[RPStart + 2].Active = 1;
+    RC->Pcie[RPStart + 3].Active = 0;
+    break;
+
+  case 2:
+    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
+    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
+    RC->Pcie[RPStart + 1].Active = 0;
+    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
+    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
+    RC->Pcie[RPStart + 2].Active = 1;
+    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
+    RC->Pcie[RPStart + 3].Active = 1;
+    break;
+
+  case 3:
+    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
+    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
+    RC->Pcie[RPStart + 1].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 1], MaxWidth);
+    RC->Pcie[RPStart + 1].Active = 1;
+    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
+    RC->Pcie[RPStart + 2].Active = 1;
+    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
+    RC->Pcie[RPStart + 3].Active = 1;
+    break;
+
+  case 0:
+  default:
+    MaxWidth = (RC->Type == RCA) ? LNKW_X16 : LNKW_X8;
+    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
+    RC->Pcie[RPStart + 1].Active = 0;
+    RC->Pcie[RPStart + 2].Active = 0;
+    RC->Pcie[RPStart + 3].Active = 0;
+    break;
+  }
+}
+
+VOID
+PcieBoardGetLaneAllocation (
+  IN AC01_RC *RC
+  )
+{
+  INTN    RPIndex, Ret;
+  UINT32  Nv, Width;
+  NVPARAM NvParam;
+
+  // Retrieve lane allocation and capabilities for each controller
+  if (RC->Type == RCA) {
+    NvParam = NV_SI_RO_BOARD_S0_RCA0_CFG + RC->Socket * 96 +
+                RC->ID * 8;
+  } else {
+    NvParam = NV_SI_RO_BOARD_S0_RCB0_LO_CFG + RC->Socket * 96 +
+              (RC->ID - MAX_RCA) * 16;
+  }
+
+  Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
+  Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
+
+  for (RPIndex = 0; RPIndex < MAX_PCIE_A; RPIndex++) {
+    Width = (Nv >> (RPIndex * 8)) & 0xF;
+    switch (Width) {
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+      RC->Pcie[RPIndex].MaxWidth = 1 << Width;
+      RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
+      RC->Pcie[RPIndex].Active = TRUE;
+      break;
+
+    case 0:
+    default:
+      RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
+      RC->Pcie[RPIndex].MaxGen = 0;
+      RC->Pcie[RPIndex].Active = FALSE;
+      break;
+    }
+  }
+
+  if (RC->Type == RCB) {
+    // Processing Hi
+    NvParam += 8;
+    Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
+    Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
+
+    for (RPIndex = MAX_PCIE_A; RPIndex < MAX_PCIE; RPIndex++) {
+      Width = (Nv >> ((RPIndex - MAX_PCIE_A) * 8)) & 0xF;
+      switch (Width) {
+      case 1:
+      case 2:
+      case 3:
+      case 4:
+        RC->Pcie[RPIndex].MaxWidth = 1 << Width;
+        RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
+        RC->Pcie[RPIndex].Active = TRUE;
+        break;
+
+      case 0:
+      default:
+        RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
+        RC->Pcie[RPIndex].MaxGen = 0;
+        RC->Pcie[RPIndex].Active = FALSE;
+        break;
+      }
+    }
+  }
+
+  // Do not proceed if no Root Port enabled
+  if (IsEmptyRC (RC)) {
+    RC->Active = FALSE;
+  }
+}
+
+VOID
+PcieBoardSetupDevmap (
+  IN AC01_RC *RC
+  )
+{
+  UINT32 Val;
+
+  if (RC->Pcie[PCIE_0].Active
+      && RC->Pcie[PCIE_1].Active
+      && RC->Pcie[PCIE_2].Active
+      && RC->Pcie[PCIE_3].Active)
+  {
+    RC->DefaultDevMapLo = 3;
+  } else if (RC->Pcie[PCIE_0].Active
+             && RC->Pcie[PCIE_2].Active
+             && RC->Pcie[PCIE_3].Active)
+  {
+    RC->DefaultDevMapLo = 2;
+  } else if (RC->Pcie[PCIE_0].Active
+             && RC->Pcie[PCIE_2].Active)
+  {
+    RC->DefaultDevMapLo = 1;
+  } else {
+    RC->DefaultDevMapLo = 0;
+  }
+
+  if (RC->Pcie[PCIE_4].Active
+      && RC->Pcie[PCIE_5].Active
+      && RC->Pcie[PCIE_6].Active
+      && RC->Pcie[PCIE_7].Active)
+  {
+    RC->DefaultDevMapHi = 3;
+  } else if (RC->Pcie[PCIE_4].Active
+             && RC->Pcie[PCIE_6].Active
+             && RC->Pcie[PCIE_7].Active)
+  {
+    RC->DefaultDevMapHi = 2;
+  } else if (RC->Pcie[PCIE_4].Active
+             && RC->Pcie[PCIE_6].Active)
+  {
+    RC->DefaultDevMapHi = 1;
+  } else {
+    RC->DefaultDevMapHi = 0;
+  }
+
+  if (RC->DevMapLo == 0) {
+    RC->DevMapLo = RC->DefaultDevMapLo;
+  }
+
+  if (RC->Type == RCB && RC->DevMapHi == 0) {
+    RC->DevMapHi = RC->DefaultDevMapHi;
+  }
+
+  PcieBoardSetRCBifur (RC, PCIE_0, RC->DevMapLo);
+  if (RC->Type == RCB) {
+    PcieBoardSetRCBifur (RC, PCIE_4, RC->DevMapHi);
+  }
+
+  if (RC->Active) {
+    if (RC->Type == RCA) {
+      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCAPDMR, &Val))) {
+        Val = RCAPCIDEVMAP_SET (Val, RC->DevMapLo & 0x7);
+        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCAPDMR, Val);
+      }
+    } else {
+      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCBPDMR, &Val))) {
+        Val = RCBPCIDEVMAPLO_SET (Val, RC->DevMapLo & 0x7);
+        Val = RCBPCIDEVMAPHI_SET (Val, RC->DevMapHi & 0x7);
+        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCBPDMR, Val);
+      }
+    }
+  }
+}
+
+VOID
+PcieBoardGetSpeed (
+  IN AC01_RC *RC
+  )
+{
+  UINT8 MaxGenTbl[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN4, SPEED_GEN4 };         // Bifurcation 0: RCA x16 / RCB x8
+  UINT8 MaxGenTblX8X4X4[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN1, SPEED_GEN1 };   // Bifurcation 2: x8 x4 x4 (PCIE_ERRATA_SPEED1)
+  UINT8 MaxGenTblX4X4X4X4[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 }; // Bifurcation 3: x4 x4 x4 x4 (PCIE_ERRATA_SPEED1)
+  UINT8 MaxGenTblRCB[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 };      // RCB PCIE_ERRATA_SPEED1
+  INTN  RPIdx;
+  UINT8 *MaxGen;
+
+  ASSERT (MAX_PCIE_A == 4);
+  ASSERT (MAX_PCIE == 8);
+
+  //
+  // Due to hardware errata, for A0/A1*
+  //  RCB is limited to Gen1 speed.
+  //  RCA x16, x8 port supports up to Gen4,
+  //  RCA x4 port only supports Gen1.
+  //
+  MaxGen = MaxGenTbl;
+  if (RC->Type == RCB) {
+    if (RC->Flags & PCIE_ERRATA_SPEED1) {
+      MaxGen = MaxGenTblRCB;
+    }
+  } else {
+    switch (RC->DevMapLo) {
+    case 2: /* x8 x4 x4 */
+      if (RC->Flags & PCIE_ERRATA_SPEED1) {
+        MaxGen = MaxGenTblX8X4X4;
+      }
+      break;
+
+    case 3: /* X4 x4 x4 x4 */
+      if (RC->Flags & PCIE_ERRATA_SPEED1) {
+        MaxGen = MaxGenTblX4X4X4X4;
+      }
+      break;
+
+    case 1: /* x8 x8 */
+    default:
+      break;
+    }
+  }
+
+  for (RPIdx = 0; RPIdx < MAX_PCIE_A; RPIdx++) {
+    RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : 0;
+  }
+
+  if (RC->Type == RCB) {
+    for (RPIdx = MAX_PCIE_A; RPIdx < MAX_PCIE; RPIdx++) {
+      RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ?
+                               MaxGen[RPIdx - MAX_PCIE_A] : 0;
+    }
+  }
+}
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
new file mode 100644
index 000000000000..309cc8857b8c
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
@@ -0,0 +1,1120 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/HobLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PcieBoardLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <NVParamDef.h>
+#include <Pcie.h>
+#include <PlatformInfoHob.h>
+
+#include "PcieBoardScreen.h"
+
+#ifndef BIT
+#define BIT(nr) (1 << (nr))
+#endif
+
+#define MAX_STRING_SIZE     32
+
+CHAR16   VariableName[]     = PCIE_VARSTORE_NAME;
+EFI_GUID gPcieFormSetGuid   = PCIE_FORM_SET_GUID;
+
+EFI_HANDLE               DriverHandle = NULL;
+PCIE_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
+
+AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX];
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    PCIE_FORM_SET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Request,
+  OUT      EFI_STRING                     *Progress,
+  OUT      EFI_STRING                     *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  CHAR16                          *StrPointer;
+  BOOLEAN                         AllocatedRequest;
+  PCIE_VARSTORE_DATA              *VarStoreConfig;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+  ASSERT (VarStoreConfig != NULL);
+
+  //
+  // Get Buffer Storage data from EFI variable.
+  // Try to get the current setting from variable.
+  //
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  VariableName,
+                  &gPcieFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  VarStoreConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (Request == NULL) {
+    //
+    // Request is set to NULL, construct full request string.
+    //
+
+    //
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
+    // Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (
+                         &gPcieFormSetGuid,
+                         VariableName,
+                         PrivateData->DriverHandle
+                         );
+    if (ConfigRequestHdr == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (
+      ConfigRequest,
+      Size,
+      L"%s&OFFSET=0&WIDTH=%016LX",
+      ConfigRequestHdr,
+      (UINT64)BufferSize
+      );
+    FreePool (ConfigRequestHdr);
+    ConfigRequestHdr = NULL;
+  } else {
+    //
+    // Check routing data in <ConfigHdr>.
+    // Note: if only one Storage is used, then this checking could be skipped.
+    //
+    if (!HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, NULL)) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // Set Request to the unified request string.
+    //
+    ConfigRequest = Request;
+
+    //
+    // Check whether Request includes Request Element.
+    //
+    if (StrStr (Request, L"OFFSET") == NULL) {
+      //
+      // Check Request Element does exist in Request String
+      //
+      StrPointer = StrStr (Request, L"PATH");
+      if (StrPointer == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      if (StrStr (StrPointer, L"&") == NULL) {
+        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
+        ConfigRequest    = AllocateZeroPool (Size);
+        ASSERT (ConfigRequest != NULL);
+        AllocatedRequest = TRUE;
+        UnicodeSPrint (
+          ConfigRequest,
+          Size,
+          L"%s&OFFSET=0&WIDTH=%016LX",
+          Request,
+          (UINT64)BufferSize
+          );
+      }
+    }
+  }
+
+  //
+  // Check if requesting Name/Value storage
+  //
+  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    Status = EFI_SUCCESS;
+  } else {
+    //
+    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+    //
+    Status = HiiConfigRouting->BlockToConfig (
+                                 HiiConfigRouting,
+                                 ConfigRequest,
+                                 (UINT8 *)VarStoreConfig,
+                                 BufferSize,
+                                 Results,
+                                 Progress
+                                 );
+  }
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+  }
+
+  if (ConfigRequestHdr != NULL) {
+    FreePool (ConfigRequestHdr);
+  }
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Configuration,
+  OUT      EFI_STRING                     *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  PCIE_VARSTORE_DATA              *VarStoreConfig;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+  ASSERT (VarStoreConfig != NULL);
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, NULL)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get Buffer Storage data from EFI variable
+  //
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  VariableName,
+                  &gPcieFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  VarStoreConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Check if configuring Name/Value storage
+  //
+  if (StrStr (Configuration, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)VarStoreConfig,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store Buffer Storage back to variable
+  //
+  Status = gRT->SetVariable (
+                  VariableName,
+                  &gPcieFormSetGuid,
+                  EFI_VARIABLE_NON_VOLATILE |
+                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                  EFI_VARIABLE_RUNTIME_ACCESS,
+                  sizeof (PCIE_VARSTORE_DATA),
+                  VarStoreConfig
+                  );
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+  @retval EFI_SUCCESS            The callback successfully handled the action.
+  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
+                                 variable and its data.
+  @retval EFI_DEVICE_ERROR       The variable could not be saved.
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
+                                 callback.
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  PCIE_VARSTORE_DATA       *VarStoreConfig;
+  PCIE_SCREEN_PRIVATE_DATA *PrivateData;
+  EFI_STATUS               Status;
+
+  if (((Value == NULL) &&
+       (Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
+       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
+      (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+  ASSERT (VarStoreConfig != NULL);
+
+  Status = EFI_SUCCESS;
+
+  switch (Action) {
+  case EFI_BROWSER_ACTION_FORM_OPEN:
+    break;
+
+  case EFI_BROWSER_ACTION_FORM_CLOSE:
+    break;
+
+  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
+  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
+    if (QuestionId == 0x9000) {
+      /* SMMU PMU */
+      Value->u32 = 0; /* default disable */
+      break;
+    }
+
+    switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) {
+    case 0:
+      Value->u8 = PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
+      break;
+
+    case 1:
+      Value->u8 = PcieRCDevMapLoDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
+      break;
+
+    case 2:
+      Value->u8 = PcieRCDevMapHiDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
+      break;
+    }
+    break;
+
+  case EFI_BROWSER_ACTION_RETRIEVE:
+  case EFI_BROWSER_ACTION_CHANGING:
+  case EFI_BROWSER_ACTION_SUBMITTED:
+    break;
+
+  default:
+    Status = EFI_UNSUPPORTED;
+    break;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+PcieScreenUnload (
+  IN EFI_HANDLE ImageHandle
+  )
+{
+  ASSERT (mPrivateData != NULL);
+
+  if (DriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           DriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    DriverHandle = NULL;
+  }
+
+  if (mPrivateData->HiiHandle != NULL) {
+    HiiRemovePackages (mPrivateData->HiiHandle);
+  }
+
+  FreePool (mPrivateData);
+  mPrivateData = NULL;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function return default settings for Dev Map LO.
+  @param  RC                     Root Complex ID.
+  @param  PrivateData            Private data.
+
+  @retval Default dev settings.
+**/
+UINT8
+PcieRCDevMapLoDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  )
+{
+  AC01_RC *RC = &RCList[RCIndex];
+
+  return RC->DefaultDevMapLo;
+}
+
+/**
+  This function return default settings for Dev Map HI.
+  @param  RC                     Root Complex ID.
+  @param  PrivateData            Private data.
+
+  @retval Default dev settings.
+**/
+UINT8
+PcieRCDevMapHiDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  )
+{
+  AC01_RC *RC = &RCList[RCIndex];
+
+  return RC->DefaultDevMapHi;
+}
+
+BOOLEAN
+PcieRCActiveDefaultSetting (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  )
+{
+  PLATFORM_INFO_HOB  *PlatformHob;
+  VOID               *Hob;
+  UINT32             Efuse;
+
+  // FIXME: Disable Root Complex 6 (USB and VGA) as default
+  if (RCIndex == 6) {
+    return FALSE;
+  }
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob != NULL) {
+    PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+    Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
+    return (!(Efuse & BIT (RCIndex))) ? TRUE : FALSE;
+  }
+
+  return FALSE;
+}
+
+/**
+  This function sets up the first elements of the form.
+  @param  RC                     Root Complex ID.
+  @param  PrivateData            Private data.
+  @retval EFI_SUCCESS            The form is set up successfully.
+**/
+EFI_STATUS
+PcieRCScreenSetup (
+  IN UINTN                    RCIndex,
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  )
+{
+  VOID               *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *EndLabel;
+  VOID               *OptionsOpCodeHandle;
+  VOID               *OptionsHiOpCodeHandle;
+  CHAR16             Str[MAX_STRING_SIZE];
+  UINT16             DisabledStatusVarOffset;
+  UINT16             BifurLoVarOffset;
+  UINT16             BifurHiVarOffset;
+  UINT8              QuestionFlags, QuestionFlagsSubItem;
+  AC01_RC            *RC;
+
+  RC = &RCList[RCIndex];
+
+  // Initialize the container for dynamic opcodes
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  // Create Hii Extend Label OpCode as the start opcode
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_RC0_UPDATE + 2 * RCIndex;
+
+  // Create Hii Extend Label OpCode as the end opcode
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_RC0_END + 2 * RCIndex;
+
+  // Create textbox to tell socket
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_PCIE_SOCKET),
+    STRING_TOKEN (STR_PCIE_SOCKET_HELP),
+    HiiSetString (
+      PrivateData->HiiHandle,
+      0,
+      (RC->Socket) ? L"1" : L"0",
+      NULL
+      )
+    );
+
+  // Create textbox to tell Root Complex type
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_PCIE_RC_TYPE),
+    STRING_TOKEN (STR_PCIE_RC_TYPE_HELP),
+    HiiSetString (
+      PrivateData->HiiHandle,
+      0,
+      (RC->Type == RCA) ? L"Root Complex Type-A" : L"Root Complex Type-B",
+      NULL
+      )
+    );
+
+  UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RCIndex);
+
+  DisabledStatusVarOffset = (UINT16)PCIE_RC0_STATUS_OFFSET +
+                            sizeof (BOOLEAN) * RCIndex;
+  BifurLoVarOffset = (UINT16)PCIE_RC0_BIFUR_LO_OFFSET +
+                     sizeof (UINT8) * RCIndex;
+  BifurHiVarOffset = (UINT16)PCIE_RC0_BIFUR_HI_OFFSET +
+                     sizeof (UINT8) * RCIndex;
+
+  QuestionFlags = EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_CALLBACK;
+  if (IsEmptyRC (RC)
+      || (GetNumberOfActiveSockets () == 1 && RC->Socket == 1))
+  {
+    //
+    // Do not allow changing if none of Root Port underneath enabled
+    // or slave Root Complex on 1P system.
+    //
+    QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
+  }
+  // Create the RC disabled checkbox
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                        // Container for dynamic created opcodes
+    0x8002 + MAX_EDITABLE_ELEMENTS * RCIndex, // QuestionId (or "key")
+    PCIE_VARSTORE_ID,                         // VarStoreId
+    DisabledStatusVarOffset,                  // VarOffset in Buffer Storage
+    HiiSetString (
+      PrivateData->HiiHandle,
+      0,
+      Str,
+      NULL
+      ),                                       // Prompt
+    STRING_TOKEN (STR_PCIE_RC_STATUS_HELP),    // Help
+    QuestionFlags,                             // QuestionFlags
+    0,                                         // CheckBoxFlags
+    NULL                                       // DefaultsOpCodeHandle
+    );
+
+  if (RC->Type == RCA) {
+    // Create Option OpCode to display bifurcation for RCA
+    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+    ASSERT (OptionsOpCodeHandle != NULL);
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE0),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      0 // Devmap=0
+      );
+
+
+    if (RC->DefaultDevMapLo != 0) {
+      QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
+    }
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE1),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      1 // Devmap=1
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE2),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      2 // Devmap=2
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE3),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      3 // Devmap=3
+      );
+
+    HiiCreateOneOfOpCode (
+      StartOpCodeHandle,                        // Container for dynamic created opcodes
+      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key")
+      PCIE_VARSTORE_ID,                         // VarStore ID
+      BifurLoVarOffset,                         // Offset in Buffer Storage
+      STRING_TOKEN (STR_PCIE_RCA_BIFUR),        // Question prompt text
+      STRING_TOKEN (STR_PCIE_RCA_BIFUR_HELP),   // Question help text
+      QuestionFlags,                            // Question flag
+      EFI_IFR_NUMERIC_SIZE_1,                   // Data type of Question Value
+      OptionsOpCodeHandle,                      // Option Opcode list
+      NULL                                      // Default Opcode is NULl
+      );
+  } else {
+    // Create Option OpCode to display bifurcation for RCB-Lo
+    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+    ASSERT (OptionsOpCodeHandle != NULL);
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      0 // Devmap=0
+      );
+
+    QuestionFlagsSubItem = QuestionFlags;
+    if (RC->DefaultDevMapLo != 0) {
+      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
+    }
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      1 // Devmap=1
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      2 // Devmap=2
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      3 // Devmap=3
+      );
+
+    HiiCreateOneOfOpCode (
+      StartOpCodeHandle,                         // Container for dynamic created opcodes
+      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
+      PCIE_VARSTORE_ID,                          // VarStore ID
+      BifurLoVarOffset,                          // Offset in Buffer Storage
+      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR),      // Question prompt text
+      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR_HELP), // Question help text
+      QuestionFlagsSubItem,                      // Question flag
+      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
+      OptionsOpCodeHandle,                       // Option Opcode list
+      NULL                                       // Default Opcode is NULl
+      );
+
+    // Create Option OpCode to display bifurcation for RCB-Hi
+    OptionsHiOpCodeHandle = HiiAllocateOpCodeHandle ();
+    ASSERT (OptionsHiOpCodeHandle != NULL);
+
+    QuestionFlagsSubItem = QuestionFlags;
+    if (RC->DefaultDevMapHi != 0) {
+      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
+    }
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsHiOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      0 // Devmap=0
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsHiOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      1 // Devmap=1
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsHiOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      2 // Devmap=2
+      );
+
+    HiiCreateOneOfOptionOpCode (
+      OptionsHiOpCodeHandle,
+      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      3 // Devmap=3
+      );
+
+    HiiCreateOneOfOpCode (
+      StartOpCodeHandle,                         // Container for dynamic created opcodes
+      0x8004 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
+      PCIE_VARSTORE_ID,                          // VarStore ID
+      BifurHiVarOffset,                          // Offset in Buffer Storage
+      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR),      // Question prompt text
+      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR_HELP), // Question help text
+      QuestionFlagsSubItem,                      // Question flag
+      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
+      OptionsHiOpCodeHandle,                     // Option Opcode list
+      NULL                                       // Default Opcode is NULl
+      );
+  }
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,     // HII handle
+    &gPcieFormSetGuid,          // Formset GUID
+    PCIE_RC0_FORM_ID + RCIndex, // Form ID
+    StartOpCodeHandle,          // Label for where to insert opcodes
+    EndOpCodeHandle             // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function sets up the first elements of the form.
+  @param  PrivateData            Private data.
+  @retval EFI_SUCCESS            The form is set up successfully.
+**/
+EFI_STATUS
+PcieMainScreenSetup (
+  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
+  )
+{
+  VOID                 *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL   *StartLabel;
+  VOID                 *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL   *EndLabel;
+  CHAR16               Str[MAX_STRING_SIZE];
+  UINTN                RC;
+  PCIE_SETUP_GOTO_DATA *GotoItem = NULL;
+  EFI_QUESTION_ID      GotoId;
+
+  // Initialize the container for dynamic opcodes
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  // Create Hii Extend Label OpCode as the start opcode
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  // Create Hii Extend Label OpCode as the end opcode
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                       // Container for dynamic created opcodes
+    0x9000,                                  // Question ID
+    PCIE_VARSTORE_ID,                        // VarStore ID
+    (UINT16)PCIE_SMMU_PMU_OFFSET,            // Offset in Buffer Storage
+    STRING_TOKEN (STR_PCIE_SMMU_PMU_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_PCIE_SMMU_PMU_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  //
+  // Create the a seperated line
+  //
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
+    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
+    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE)
+    );
+
+  // Create Goto form for each RC
+  for (RC = 0; RC < MAX_AC01_PCIE_ROOT_COMPLEX; RC++) {
+
+    GotoItem = AllocateZeroPool (sizeof (PCIE_SETUP_GOTO_DATA));
+    if (GotoItem == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    GotoItem->PciDevIdx = RC;
+
+    GotoId = PCIE_GOTO_ID_BASE + (UINT16)RC;
+
+    // Update HII string
+    UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RC);
+    GotoItem->GotoStringId = HiiSetString (
+                               PrivateData->HiiHandle,
+                               0,
+                               Str,
+                               NULL
+                               );
+    GotoItem->GotoHelpStringId = STRING_TOKEN (STR_PCIE_GOTO_HELP);
+    GotoItem->ShowItem = TRUE;
+
+    // Add goto control
+    HiiCreateGotoOpCode (
+      StartOpCodeHandle,
+      PCIE_RC0_FORM_ID + RC,
+      GotoItem->GotoStringId,
+      GotoItem->GotoHelpStringId,
+      EFI_IFR_FLAG_CALLBACK,
+      GotoId
+      );
+  }
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,  // HII handle
+    &gPcieFormSetGuid,       // Formset GUID
+    PCIE_FORM_ID,            // Form ID
+    StartOpCodeHandle,       // Label for where to insert opcodes
+    EndOpCodeHandle          // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PcieBoardScreenInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable,
+  IN AC01_RC          *NewRCList
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_HII_HANDLE                      HiiHandle;
+  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
+  EFI_HII_STRING_PROTOCOL             *HiiString;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
+  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+  UINTN                               BufferSize;
+  BOOLEAN                             IsUpdated;
+  PCIE_VARSTORE_DATA                  *VarStoreConfig;
+  UINT8                               RCIndex;
+  AC01_RC                             *RC;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (PCIE_SCREEN_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = PCIE_SCREEN_PRIVATE_DATA_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
+  mPrivateData->ConfigAccess.Callback = DriverCallback;
+
+  //
+  // Locate Hii Database protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiDatabaseProtocolGuid,
+                  NULL,
+                  (VOID **)&HiiDatabase
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiDatabase = HiiDatabase;
+
+  //
+  // Locate HiiString protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiStringProtocolGuid,
+                  NULL,
+                  (VOID **)&HiiString
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiString = HiiString;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiConfigRoutingProtocolGuid,
+                  NULL,
+                  (VOID **)&HiiConfigRouting
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  //
+  // Locate keyword handler protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiConfigKeywordHandlerProtocolGuid,
+                  NULL,
+                  (VOID **)&HiiKeywordHandler
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiKeywordHandler = HiiKeywordHandler;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = DriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gPcieFormSetGuid,
+                DriverHandle,
+                PcieBoardLibStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  // Make a shadow copy all Root Complexes' properties
+  CopyMem ((VOID *)RCList, (VOID *)NewRCList, sizeof (RCList));
+
+  //
+  // Initialize efi varstore configuration data
+  //
+  VarStoreConfig = &mPrivateData->VarStoreConfig;
+  ZeroMem (VarStoreConfig, sizeof (PCIE_VARSTORE_DATA));
+
+  // Get Buffer Storage data from EFI variable
+  BufferSize = sizeof (PCIE_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  VariableName,
+                  &gPcieFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  VarStoreConfig
+                  );
+
+  IsUpdated = FALSE;
+
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->SmmuPmu = 0; /* Disable by default */
+    IsUpdated = TRUE;
+  }
+  // Update board settings to menu
+  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+    RC = &RCList[RCIndex];
+
+    if (EFI_ERROR (Status)) {
+      VarStoreConfig->RCBifurLo[RCIndex] = RC->DevMapLo;
+      VarStoreConfig->RCBifurHi[RCIndex] = RC->DevMapHi;
+      VarStoreConfig->RCStatus[RCIndex] = RC->Active;
+      IsUpdated = TRUE;
+    }
+    // FIXME: Disable Root Complex 6 (USB and VGA) as default
+    if (EFI_ERROR (Status) && RCIndex == 6) {
+      VarStoreConfig->RCStatus[RCIndex] = 0;
+    }
+  }
+
+  if (IsUpdated) {
+    // Update Buffer Storage
+    Status = gRT->SetVariable (
+                    VariableName,
+                    &gPcieFormSetGuid,
+                    EFI_VARIABLE_NON_VOLATILE |
+                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
+                    EFI_VARIABLE_RUNTIME_ACCESS,
+                    sizeof (PCIE_VARSTORE_DATA),
+                    VarStoreConfig
+                    );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+  Status = PcieMainScreenSetup (mPrivateData);
+  ASSERT_EFI_ERROR (Status);
+
+  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
+    Status = PcieRCScreenSetup (RCIndex, mPrivateData);
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
new file mode 100644
index 000000000000..776eaa476787
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
@@ -0,0 +1,99 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US "English"
+
+#string STR_PCIE_FORM                   #language en-US "PCIE Root Complex Configuration"
+#string STR_PCIE_FORM_HELP              #language en-US "Configure Root Complex"
+
+#string STR_PCIE_FORM_SEPERATE_LINE     #language en-US ""
+
+/////
+
+#string STR_PCIE_GOTO                   #language en-US ""
+#string STR_PCIE_GOTO_HELP              #language en-US "Change On Board Root Complex Settings."
+
+#string STR_PCIE_RC_STATUS              #language en-US ""
+#string STR_PCIE_RC_STATUS_HELP         #language en-US "Enable / Disable Root Complex"
+
+#string STR_PCIE_RCA_BIFUR              #language en-US "Bifurcation x16"
+#string STR_PCIE_RCA_BIFUR_HELP         #language en-US "Set bifurcation mode for x16 Root Complex Type-A"
+
+#string STR_PCIE_RCB_LO_BIFUR           #language en-US "Bifurcation 1st x8"
+#string STR_PCIE_RCB_LO_BIFUR_HELP      #language en-US "Set bifurcation mode for 1st x8 Root Complex Type-B"
+
+#string STR_PCIE_RCB_HI_BIFUR           #language en-US "Bifurcation 2nd x8"
+#string STR_PCIE_RCB_HI_BIFUR_HELP      #language en-US "Set bifurcation mode for 2nd x8 Root Complex Type-B"
+
+/////
+
+#string STR_PCIE_RC0_FORM               #language en-US "Root Complex 0 Configuration"
+#string STR_PCIE_RC0_FORM_HELP          #language en-US "Root Complex 0 Configuration"
+
+#string STR_PCIE_RC1_FORM               #language en-US "Root Complex 1 Configuration"
+#string STR_PCIE_RC1_FORM_HELP          #language en-US "Root Complex 1 Configuration"
+
+#string STR_PCIE_RC2_FORM               #language en-US "Root Complex 2 Configuration"
+#string STR_PCIE_RC2_FORM_HELP          #language en-US "Root Complex 2 Configuration"
+
+#string STR_PCIE_RC3_FORM               #language en-US "Root Complex 3 Configuration"
+#string STR_PCIE_RC3_FORM_HELP          #language en-US "Root Complex 3 Configuration"
+
+#string STR_PCIE_RC4_FORM               #language en-US "Root Complex 4 Configuration"
+#string STR_PCIE_RC4_FORM_HELP          #language en-US "Root Complex 4 Configuration"
+
+#string STR_PCIE_RC5_FORM               #language en-US "Root Complex 5 Configuration"
+#string STR_PCIE_RC5_FORM_HELP          #language en-US "Root Complex 5 Configuration"
+
+#string STR_PCIE_RC6_FORM               #language en-US "Root Complex 6 Configuration"
+#string STR_PCIE_RC6_FORM_HELP          #language en-US "Root Complex 6 Configuration"
+
+#string STR_PCIE_RC7_FORM               #language en-US "Root Complex 7 Configuration"
+#string STR_PCIE_RC7_FORM_HELP          #language en-US "Root Complex 7 Configuration"
+
+#string STR_PCIE_RC8_FORM               #language en-US "Root Complex 8 Configuration"
+#string STR_PCIE_RC8_FORM_HELP          #language en-US "Root Complex 8 Configuration"
+
+#string STR_PCIE_RC9_FORM               #language en-US "Root Complex 9 Configuration"
+#string STR_PCIE_RC9_FORM_HELP          #language en-US "Root Complex 9 Configuration"
+
+#string STR_PCIE_RC10_FORM              #language en-US "Root Complex 10 Configuration"
+#string STR_PCIE_RC10_FORM_HELP         #language en-US "Root Complex 10 Configuration"
+
+#string STR_PCIE_RC11_FORM              #language en-US "Root Complex 11 Configuration"
+#string STR_PCIE_RC11_FORM_HELP         #language en-US "Root Complex 11 Configuration"
+
+#string STR_PCIE_RC12_FORM              #language en-US "Root Complex 12 Configuration"
+#string STR_PCIE_RC12_FORM_HELP         #language en-US "Root Complex 12 Configuration"
+
+#string STR_PCIE_RC13_FORM              #language en-US "Root Complex 13 Configuration"
+#string STR_PCIE_RC13_FORM_HELP         #language en-US "Root Complex 13 Configuration"
+
+#string STR_PCIE_RC14_FORM              #language en-US "Root Complex 14 Configuration"
+#string STR_PCIE_RC14_FORM_HELP         #language en-US "Root Complex 14 Configuration"
+
+#string STR_PCIE_RC15_FORM              #language en-US "Root Complex 15 Configuration"
+#string STR_PCIE_RC15_FORM_HELP         #language en-US "Root Complex 15 Configuration"
+
+#string STR_PCIE_BIFUR_SELECT_VALUE0    #language en-US "x16"
+#string STR_PCIE_BIFUR_SELECT_VALUE1    #language en-US "x8+x8"
+#string STR_PCIE_BIFUR_SELECT_VALUE2    #language en-US "x8+x4+x4"
+#string STR_PCIE_BIFUR_SELECT_VALUE3    #language en-US "x4+x4+x4+x4"
+#string STR_PCIE_BIFUR_SELECT_VALUE4    #language en-US "x8"
+#string STR_PCIE_BIFUR_SELECT_VALUE5    #language en-US "x4+x4"
+#string STR_PCIE_BIFUR_SELECT_VALUE6    #language en-US "x4+x2+x2"
+#string STR_PCIE_BIFUR_SELECT_VALUE7    #language en-US "x2+x2+x2+x2"
+
+#string STR_PCIE_SOCKET                 #language en-US "Socket"
+#string STR_PCIE_SOCKET_HELP            #language en-US "Socket 0 - Master; Socket 1 - Slave"
+#string STR_PCIE_SOCKET_VALUE           #language en-US ""
+
+#string STR_PCIE_RC_TYPE                #language en-US "Type"
+#string STR_PCIE_RC_TYPE_HELP           #language en-US "Type-A: x16 lanes bifurcated down to x4; Type-B: 2 of x8 lanes, each bifurcated down to x2"
+#string STR_PCIE_RC_TYPE_VALUE          #language en-US ""
+
+#string STR_PCIE_SMMU_PMU_PROMPT        #language en-US "SMMU Pmu"
+#string STR_PCIE_SMMU_PMU_HELP          #language en-US "Enable/Disable PMU feature for SMMU"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (15 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-08 22:26   ` Leif Lindholm
  2021-06-09  5:29   ` Ard Biesheuvel
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
                   ` (17 subsequent siblings)
  34 siblings, 2 replies; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

The roles of this driver:
* Consume PcieCoreLib to initialize all enable PCIe controllers.
* Produce neccessary protocols like RootBridgeIo an ResourceAllocation
  which will be used later by PciBus.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   56 +
 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h      |  451 ++++++
 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h    |  554 +++++++
 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c      | 1419 ++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 1582 ++++++++++++++++++++
 5 files changed, 4062 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
new file mode 100755
index 000000000000..5b67d61926c7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PciHostBridgeDxe
+  FILE_GUID                      = D7ABBD62-2E03-11E8-B467-0ED5F89F718B
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = InitializePciHostBridge
+
+[Sources]
+  PciHostBridge.c
+  PciHostBridge.h
+  PciRootBridgeIo.c
+  PciRootBridgeIo.h
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AcpiHelperLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DxeServicesTableLib
+  IoLib
+  MemoryAllocationLib
+  PcdLib
+  PcieCoreLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiPciHostBridgeResourceAllocationProtocolGuid
+  gEfiPciRootBridgeIoProtocolGuid
+  gEfiMetronomeArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+
+[FixedPcd]
+  gArmTokenSpaceGuid.PcdSystemMemoryBase
+
+[Depex]
+  gEfiMetronomeArchProtocolGuid
diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
new file mode 100644
index 000000000000..ab62ebf3c3ef
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
@@ -0,0 +1,451 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_HOST_BRIDGE_H_
+#define PCI_HOST_BRIDGE_H_
+
+#include <IndustryStandard/Acpi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DxeServicesTableLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/Metronome.h>
+#include <Protocol/PciHostBridgeResourceAllocation.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#undef PCIE_PLATFORM_DEBUG
+#undef PCIE_MMIO_DEBUG
+
+#ifdef PCIE_PLATFORM_DEBUG
+#define PCIE_DEBUG(arg...)       DEBUG((DEBUG_INFO,"PCIHostBridge: "));DEBUG((DEBUG_INFO,## arg))
+#else
+#define PCIE_DEBUG(arg...)
+#endif
+
+#ifdef PCIE_MMIO_DEBUG
+#define PCIE_MMIO_DEBUG(arg...)       DEBUG((DEBUG_INFO,"PCIRootBridge: "));DEBUG((DEBUG_INFO,## arg))
+#else
+#define PCIE_MMIO_DEBUG(arg...)
+#endif
+
+#define PCIE_WARN(arg...)        DEBUG((DEBUG_WARN,"PCIHostBridge (WARN): "));DEBUG((DEBUG_WARN,## arg))
+#define PCIE_ERR(arg...)         DEBUG((DEBUG_ERROR,"PCIHostBridge (ERROR): "));DEBUG((DEBUG_ERROR,## arg))
+
+#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')
+#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')
+
+#define PCI_HOST_BRIDGE_FROM_THIS(a) \
+  CR (a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
+
+#define PCI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL
+
+//
+// Driver Instance Data Macros
+//
+#define ROOT_BRIDGE_FROM_THIS(a) \
+  CR (a, PCI_ROOT_BRIDGE_INSTANCE, RbIo, PCI_ROOT_BRIDGE_SIGNATURE)
+
+#define ROOT_BRIDGE_FROM_LINK(a) \
+  CR (a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
+
+//
+// PCI Resource Type
+//
+typedef enum {
+  TypeIo    = 0,
+  TypeMem32,
+  TypePMem32,
+  TypeMem64,
+  TypePMem64,
+  TypeBus,
+  TypeMax
+} PCI_RESOURCE_TYPE;
+
+//
+// Type of Resource status
+//
+typedef enum {
+  ResNone = 0,
+  ResSubmitted,
+  ResAllocated,
+  ResStatusMax
+} RES_STATUS;
+
+//
+// Struct of Resource Node
+//
+typedef struct {
+  PCI_RESOURCE_TYPE  Type;
+  UINT64             Base;
+  UINT64             Length;
+  UINT64             Alignment;
+  RES_STATUS         Status;
+} PCI_RES_NODE;
+
+//
+// Type of PCIE operation
+//
+typedef enum {
+  IoOperation,
+  MemOperation,
+  PciOperation
+} OPERATION_TYPE;
+
+//
+// Struct of Device Mapping
+//
+typedef struct {
+  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
+} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
+
+//
+// Struct of Root Bridge Instance
+//
+typedef struct {
+  UINT32                          Signature;
+  LIST_ENTRY                      Link;
+  EFI_HANDLE                      RootBridgeHandle;
+  UINT64                          RootBridgeAttrib;
+  VOID                            *ConfigBuffer;
+  PCI_RES_NODE                    ResAllocNode[TypeMax];
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL RbIo;
+  PCI_ROOT_BRIDGE                 RootBridge;
+} PCI_ROOT_BRIDGE_INSTANCE;
+
+//
+// Struct of Mapping Info
+//
+typedef struct {
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
+  UINTN                                     NumberOfBytes;
+  UINTN                                     NumberOfPages;
+  EFI_PHYSICAL_ADDRESS                      HostAddress;
+  EFI_PHYSICAL_ADDRESS                      MappedHostAddress;
+} MAP_INFO;
+
+//
+// Struct of Host Bridge Instance
+//
+typedef struct {
+  UINTN                                            Signature;
+  EFI_HANDLE                                       HostBridgeHandle;
+  UINTN                                            RootBridgeNumber;
+  LIST_ENTRY                                       Head;
+  BOOLEAN                                          ResourceSubmited;
+  BOOLEAN                                          CanRestarted;
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc;
+} PCI_HOST_BRIDGE_INSTANCE;
+
+/**
+   These are the notifications from the PCI bus driver that it is about to enter a certain
+   phase of the PCI enumeration process.
+
+   This member function can be used to notify the host bridge driver to perform specific actions,
+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
+   Eight notification points are defined at this time. See belows:
+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
+                                          structures. The PCI enumerator should issue this notification
+                                          before starting a fresh enumeration process. Enumeration cannot
+                                          be restarted after sending any other notification such as
+                                          EfiPciHostBridgeBeginBusAllocation.
+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
+                                          required here. This notification can be used to perform any
+                                          chipset-specific programming.
+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
+                                          specific action is required here. This notification can be used to
+                                          perform any chipset-specific programming.
+   EfiPciHostBridgeBeginResourceAllocation
+                                          The resource allocation phase is about to begin. No specific
+                                          action is required here. This notification can be used to perform
+                                          any chipset-specific programming.
+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
+                                          root bridges. These resource settings are returned on the next call to
+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
+                                          for gathering I/O and memory requests for
+                                          all the PCI root bridges and submitting these requests using
+                                          SubmitResources(). This function pads the resource amount
+                                          to suit the root bridge hardware, takes care of dependencies between
+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
+                                          with the allocation request. In the case of padding, the allocated range
+                                          could be bigger than what was requested.
+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
+                                          resources (proposed resources) for all the PCI root bridges. After the
+                                          hardware is programmed, reassigning resources will not be supported.
+                                          The bus settings are not affected.
+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
+                                          root bridges and resets the I/O and memory apertures to their initial
+                                          state. The bus settings are not affected. If the request to allocate
+                                          resources fails, the PCI enumerator can use this notification to
+                                          deallocate previous resources, adjust the requests, and retry
+                                          allocation.
+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
+                                          required here. This notification can be used to perform any chipsetspecific
+                                          programming.
+
+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in] Phase               The phase during enumeration
+
+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
+                                  SubmitResources() has not been called for one or more
+                                  PCI root bridges before this call
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
+                                  for a Phase of EfiPciHostBridgeSetResources.
+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
+                                  previously submitted resource requests cannot be fulfilled or
+                                  were only partially fulfilled.
+   @retval EFI_SUCCESS            The notification was accepted without any errors.
+
+**/
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
+  );
+
+/**
+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
+
+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
+   root bridges. On each call, the handle that was returned by the previous call is passed into the
+   interface, and on output the interface returns the device handle of the next PCI root bridge. The
+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+   for that root bridge. When there are no more PCI root bridges to report, the interface returns
+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
+   are returned by this function.
+   For D945 implementation, there is only one root bridge in PCI host bridge.
+
+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
+
+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
+                                  specific Host bridge and return EFI_SUCCESS.
+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
+                                  returned on a previous call to GetNextRootBridge().
+**/
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT EFI_HANDLE                                       *RootBridgeHandle
+  );
+
+/**
+   Returns the allocation attributes of a PCI root bridge.
+
+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
+   from one PCI root bridge to another. These attributes are different from the decode-related
+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
+   handles of all the root bridges that are associated with this host bridge must be obtained by calling
+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
+   after the enumeration process. The hardware may provide mechanisms to change the attributes on
+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
+   prefetchable memory.
+      Attribute                                 Description
+   ------------------------------------         ----------------------------------------------------------------------
+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
+                                                windows for nonprefetchable and prefetchable memory. A PCI bus
+                                                driver needs to include requests for prefetchable memory in the
+                                                nonprefetchable memory pool.
+
+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
+                                                windows. If this bit is not set, the PCI bus driver needs to include
+                                                requests for a 64-bit memory address in the corresponding 32-bit
+                                                memory pool.
+
+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
+
+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAttributes (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  );
+
+/**
+   Sets up the specified PCI root bridge for the bus enumeration process.
+
+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
+   over which the search should be performed in ACPI 2.0 resource descriptor format.
+
+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
+
+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  );
+
+/**
+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
+
+   This member function programs the specified PCI root bridge to decode the bus range that is
+   specified by the input parameter Configuration.
+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
+
+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
+   @param[in] Configuration     The pointer to the PCI bus resource descriptor
+
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
+                                  bus descriptors.
+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  );
+
+/**
+   Submits the I/O and memory resource requirements for the specified PCI root bridge.
+
+   This function is used to submit all the I/O and memory resources that are required by the specified
+   PCI root bridge. The input parameter Configuration is used to specify the following:
+   - The various types of resources that are required
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
+
+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
+                                  not supported by this PCI root bridge. This error will happen if the caller
+                                  did not combine resources according to Attributes that were returned by
+                                  GetAllocAttributes().
+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+SubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  );
+
+/**
+   Returns the proposed resource settings for the specified PCI root bridge.
+
+   This member function returns the proposed resource settings for the specified PCI root bridge. The
+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+   EfiPciHostBridgeAllocateResources. The output parameter Configuration
+   specifies the following:
+   - The various types of resources, excluding bus resources, that are allocated
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+   @retval EFI_SUCCESS            The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  );
+
+/**
+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
+   PCI controllers before enumeration.
+
+   This function is called during the PCI enumeration process. No specific action is expected from this
+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
+   enumeration.
+
+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
+                            InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
+   @param Phase             The phase of the PCI device enumeration.
+
+   @retval EFI_SUCCESS              The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
+                                    bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS      PciAddress,
+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase
+  );
+
+#endif /* PCI_HOST_BRIDGE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
new file mode 100644
index 000000000000..9f09e8f4d7bc
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
@@ -0,0 +1,554 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCI_ROOT_BRIDGE_IO_H_
+#define PCI_ROOT_BRIDGE_IO_H_
+
+#include <IndustryStandard/Pci.h>
+#include <Library/PciLib.h>
+
+/**
+   Polls an address in memory mapped I/O space until an exit condition is met, or
+   a timeout occurs.
+
+   This function provides a standard way to poll a PCI memory location. A PCI memory read
+   operation is performed at the PCI memory address specified by Address for the width specified
+   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
+   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
+   Mask) is equal to Value.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The base address of the memory operations. The caller is
+   responsible for aligning Address if required.
+   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
+   are ignored. The bits in the bytes below Width which are zero in
+   Mask are ignored when polling the memory address.
+   @param[in]   Value     The comparison value used for the polling exit criteria.
+   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
+   be of poorer granularity.
+   @param[out]  Result    Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINT64                                Mask,
+  IN  UINT64                                Value,
+  IN  UINT64                                Delay,
+  OUT UINT64                                *Result
+  );
+
+/**
+   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
+   satisfied or after a defined duration.
+
+   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
+   performed at the PCI I/O address specified by Address for the width specified by Width.
+   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
+   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
+   to Value.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Width     Signifies the width of the I/O operations.
+   @param[in] Address   The base address of the I/O operations. The caller is responsible
+   for aligning Address if required.
+   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
+   are ignored. The bits in the bytes below Width which are zero in
+   Mask are ignored when polling the I/O address.
+   @param[in] Value     The comparison value used for the polling exit criteria.
+   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
+   be of poorer granularity.
+   @param[out] Result   Pointer to the last value read from the memory location.
+
+   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
+   @retval EFI_INVALID_PARAMETER  Width is invalid.
+   @retval EFI_INVALID_PARAMETER  Result is NULL.
+   @retval EFI_TIMEOUT            Delay expired before a match occurred.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINT64                                Mask,
+  IN  UINT64                                Value,
+  IN  UINT64                                Delay,
+  OUT UINT64                                *Result
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+   responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+   Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
+
+   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
+   registers in the PCI root bridge memory space.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operation.
+   @param[in]   Address   The base address of the memory operation. The caller is
+   responsible for aligning the Address if required.
+   @param[in]   Count     The number of memory operations to perform. Bytes moved is
+   Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                Address,
+  IN UINTN                                 Count,
+  IN VOID                                  *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
+   aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+   size * Count, starting at Address.
+   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                UserAddress,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *UserBuffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width       Signifies the width of the memory operations.
+   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
+   aligning the Address if required.
+   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
+   size * Count, starting at Address.
+   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                UserAddress,
+  IN UINTN                                 Count,
+  IN VOID                                  *UserBuffer
+  );
+
+/**
+   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
+   root bridge memory space.
+
+   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
+   space to another region of PCI root bridge memory space. This is especially useful for video scroll
+   operation on a memory mapped video buffer.
+   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
+   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
+
+   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
+   @param[in] Width       Signifies the width of the memory operations.
+   @param[in] DestAddress The destination address of the memory operation. The caller is
+   responsible for aligning the DestAddress if required.
+   @param[in] SrcAddress  The source address of the memory operation. The caller is
+   responsible for aligning the SrcAddress if required.
+   @param[in] Count       The number of memory operations to perform. Bytes moved is
+   Width size * Count, starting at DestAddress and SrcAddress.
+
+   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
+   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
+   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                DestAddress,
+  IN UINT64                                SrcAddress,
+  IN UINTN                                 Count
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+   moved is Width size * Count, starting at Address.
+   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *Buffer
+  );
+
+/**
+   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
+
+   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
+   registers for a PCI controller.
+   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
+   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
+   require.
+
+   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Width     Signifies the width of the memory operations.
+   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
+   moved is Width size * Count, starting at Address.
+   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
+   write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                Address,
+  IN UINTN                                 Count,
+  IN VOID                                  *Buffer
+  );
+
+/**
+   Provides the PCI controller-specific addresses required to access system memory from a
+   DMA bus master.
+
+   The Map() function provides the PCI controller specific addresses needed to access system
+   memory. This function is used to map system memory for PCI bus master DMA accesses.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
+   @param[in]       HostAddress     The system memory address to map to the PCI controller.
+   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
+   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
+   to access the system memory's HostAddress.
+   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
+
+   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
+   @retval EFI_INVALID_PARAMETER  Operation is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
+   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
+   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
+   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
+   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+  IN     VOID                                      *HostAddress,
+  IN OUT UINTN                                     *NumberOfBytes,
+  OUT    EFI_PHYSICAL_ADDRESS                      *DeviceAddress,
+  OUT    VOID                                      **Mapping
+  );
+
+/**
+   Completes the Map() operation and releases any corresponding resources.
+
+   The Unmap() function completes the Map() operation and releases any corresponding resources.
+   If the operation was an EfiPciOperationBusMasterWrite or
+   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
+   Any resources used for the mapping are freed.
+
+   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in] Mapping   The mapping value returned from Map().
+
+   @retval EFI_SUCCESS            The range was unmapped.
+   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
+   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN VOID                            *Mapping
+  );
+
+/**
+   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
+   EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Type        This parameter is not used and must be ignored.
+   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
+   @param Pages       The number of pages to allocate.
+   @param HostAddress A pointer to store the base system memory address of the allocated range.
+   @param Attributes  The requested bit mask of attributes for the allocated range. Only
+   the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
+   and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
+
+   @retval EFI_SUCCESS            The requested memory pages were allocated.
+   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
+   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
+   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN  EFI_ALLOCATE_TYPE               Type,
+  IN  EFI_MEMORY_TYPE                 MemoryType,
+  IN  UINTN                           Pages,
+  OUT VOID                            **HostAddress,
+  IN  UINT64                          Attributes
+  );
+
+/**
+   Frees memory that was allocated with AllocateBuffer().
+
+   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Pages       The number of pages to free.
+   @param HostAddress The base system memory address of the allocated range.
+
+   @retval EFI_SUCCESS            The requested memory pages were freed.
+   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
+   was not allocated with AllocateBuffer().
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN  UINTN                           Pages,
+  OUT VOID                            *HostAddress
+  );
+
+/**
+   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
+
+   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
+   memory. Posted write transactions are generated by PCI bus masters when they perform write
+   transactions to target addresses in system memory.
+   This function does not flush posted write transactions from any PCI bridges. A PCI controller
+   specific action must be taken to guarantee that the posted write transactions have been flushed from
+   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
+   a PCI read transaction from the PCI controller prior to calling Flush().
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
+   bridge to system memory.
+   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
+   host bridge due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+  );
+
+/**
+   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
+   attributes that a PCI root bridge is currently using.
+
+   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
+   and the mask of attributes that the PCI root bridge is currently using.
+
+   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param Supported   A pointer to the mask of attributes that this PCI root bridge
+   supports setting with SetAttributes().
+   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
+   currently using.
+
+   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
+   bridge supports is returned in Supports. If Attributes is
+   not NULL, then the attributes that the PCI root bridge is currently
+   using is returned in Attributes.
+   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  OUT UINT64                          *Supported,
+  OUT UINT64                          *Attributes
+  );
+
+/**
+   Sets attributes for a resource range on a PCI root bridge.
+
+   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
+   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
+   granularity of setting these attributes may vary from resource type to resource type, and from
+   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
+   result, this function may set the attributes specified by Attributes on a larger resource range
+   than the caller requested. The actual range is returned in ResourceBase and
+   ResourceLength. The caller is responsible for verifying that the actual range for which the
+   attributes were set is acceptable.
+
+   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
+   MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
+   MEMORY_DISABLE is set, then the resource range is specified by
+   ResourceBase and ResourceLength. If
+   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+   MEMORY_DISABLE are not set, then ResourceBase and
+   ResourceLength are ignored, and may be NULL.
+   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
+   by the attributes specified by Attributes.
+   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
+   attributes specified by Attributes.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN     UINT64                          Attributes,
+  IN OUT UINT64                          *ResourceBase,
+  IN OUT UINT64                          *ResourceLength
+  );
+
+/**
+   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
+   resource descriptors.
+
+   There are only two resource descriptor types from the ACPI Specification that may be used to
+   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
+   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
+   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
+   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
+   Address Space Descriptors followed by an End Tag.
+
+   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
+   current configuration of this PCI root bridge. The storage for the
+   ACPI 2.0 resource descriptors is allocated by this function. The
+   caller must treat the return buffer as read-only data, and the buffer
+   must not be freed by the caller.
+
+   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
+   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
+   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  OUT VOID                            **Resources
+  );
+
+#endif /* PCI_ROOT_BRIDGE_IO_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
new file mode 100644
index 000000000000..2e0876128158
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -0,0 +1,1419 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/EventGroup.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcieCoreLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+
+#include "PciHostBridge.h"
+#include "PciRootBridgeIo.h"
+
+EFI_HANDLE mDriverImageHandle;
+
+PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
+  PCI_HOST_BRIDGE_SIGNATURE,  // Signature
+  NULL,                       // HostBridgeHandle
+  0,                          // RootBridgeNumber
+  {NULL, NULL},               // Head
+  FALSE,                      // ResourceSubiteed
+  TRUE,                       // CanRestarted
+  {
+    NotifyPhase,
+    GetNextRootBridge,
+    GetAttributes,
+    StartBusEnumeration,
+    SetBusNumbers,
+    SubmitResources,
+    GetProposedResources,
+    PreprocessController
+  }
+};
+
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciDevicePathTemplate =
+{
+  {
+    {
+      ACPI_DEVICE_PATH,
+      ACPI_DP,
+      {
+        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
+        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
+      }
+    },
+    EISA_PNP_ID (0x0A08),
+    0
+  },
+
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      END_DEVICE_PATH_LENGTH,
+      0
+    }
+  }
+};
+
+STATIC
+EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *
+EFIAPI
+GenerateRootBridgeDevicePath (
+  UINTN HostBridgeIdx,
+  UINTN RootBridgeIdx
+  )
+{
+
+  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *RootBridgeDevPath = NULL;
+
+  RootBridgeDevPath = AllocateCopyPool (
+                        sizeof (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH),
+                        (VOID *)&mPciDevicePathTemplate
+                        );
+  if (RootBridgeDevPath == NULL) {
+    return NULL;
+  }
+
+  /* We don't expect to have more than 65536 root ports on the same root bridge */
+  RootBridgeDevPath->AcpiDevicePath.UID = (UINT32)((HostBridgeIdx << 16) + RootBridgeIdx);
+
+  return RootBridgeDevPath;
+}
+
+/**
+  This function will be called when ReadyToBoot event will be signaled.
+
+  @param Event signaled event
+  @param Context calling context
+
+  @retval VOID
+**/
+VOID
+EFIAPI
+PciHostBridgeReadyToBootEvent (
+  EFI_EVENT Event,
+  VOID      *Context
+  )
+{
+  UINTN Idx1, Idx2, Count = 0;
+  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
+
+  for (Idx1 = 0; Idx1 < Ac01PcieGetTotalHBs (); Idx1++) {
+    for (Idx2 = 0; Idx2 < Ac01PcieGetTotalRBsPerHB (Idx1); Idx2++) {
+      AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._STA", Count);
+      if (Ac01PcieCheckRootBridgeDisabled (Idx1, Idx2)) {
+        AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
+      } else {
+        AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
+      }
+      Count++;
+    }
+  }
+
+  //
+  // Close the event, so it will not be signalled again.
+  //
+  gBS->CloseEvent (Event);
+}
+
+/**
+   Construct the Pci Root Bridge Io protocol
+
+   @param Protocol         Point to protocol instance
+   @param HostBridgeHandle Handle of host bridge
+   @param Attri            Attribute of host bridge
+   @param ResAppeture      ResourceAppeture for host bridge
+
+   @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
+
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+RootBridgeConstructor (
+  IN PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance,
+  IN EFI_HANDLE               HostBridgeHandle,
+  IN UINT64                   Attri,
+  IN UINT32                   Seg
+  )
+{
+  PCI_RESOURCE_TYPE Index;
+
+  //
+  // The host to pci bridge, the host memory and io addresses are
+  // integrated as PCIe controller subsystem resource. We move forward to mark
+  // resource as ResAllocated.
+  //
+  for (Index = TypeIo; Index < TypeMax; Index++) {
+    RootBridgeInstance->ResAllocNode[Index].Type      = Index;
+    RootBridgeInstance->ResAllocNode[Index].Base      = 0;
+    RootBridgeInstance->ResAllocNode[Index].Length    = 0;
+    RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
+  }
+
+  RootBridgeInstance->RootBridgeAttrib                 = Attri;
+  RootBridgeInstance->RootBridge.Supports              = EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+  // Support Extended (4096-byte) Configuration Space
+  RootBridgeInstance->RootBridge.NoExtendedConfigSpace = FALSE;
+  RootBridgeInstance->RootBridge.Attributes            = RootBridgeInstance->RootBridge.Supports;
+
+  RootBridgeInstance->RbIo.ParentHandle   = HostBridgeHandle;
+
+  RootBridgeInstance->RbIo.PollMem        = RootBridgeIoPollMem;
+  RootBridgeInstance->RbIo.PollIo         = RootBridgeIoPollIo;
+
+  RootBridgeInstance->RbIo.Mem.Read       = RootBridgeIoMemRead;
+  RootBridgeInstance->RbIo.Mem.Write      = RootBridgeIoMemWrite;
+
+  RootBridgeInstance->RbIo.Io.Read        = RootBridgeIoIoRead;
+  RootBridgeInstance->RbIo.Io.Write       = RootBridgeIoIoWrite;
+
+  RootBridgeInstance->RbIo.CopyMem        = RootBridgeIoCopyMem;
+
+  RootBridgeInstance->RbIo.Pci.Read       = RootBridgeIoPciRead;
+  RootBridgeInstance->RbIo.Pci.Write      = RootBridgeIoPciWrite;
+
+  RootBridgeInstance->RbIo.Map            = RootBridgeIoMap;
+  RootBridgeInstance->RbIo.Unmap          = RootBridgeIoUnmap;
+
+  RootBridgeInstance->RbIo.AllocateBuffer = RootBridgeIoAllocateBuffer;
+  RootBridgeInstance->RbIo.FreeBuffer     = RootBridgeIoFreeBuffer;
+
+  RootBridgeInstance->RbIo.Flush          = RootBridgeIoFlush;
+
+  RootBridgeInstance->RbIo.GetAttributes  = RootBridgeIoGetAttributes;
+  RootBridgeInstance->RbIo.SetAttributes  = RootBridgeIoSetAttributes;
+
+  RootBridgeInstance->RbIo.Configuration  = RootBridgeIoConfiguration;
+
+  RootBridgeInstance->RbIo.SegmentNumber  = Seg;
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Entry point of this driver
+
+   @param ImageHandle     Handle of driver image
+   @param SystemTable     Point to EFI_SYSTEM_TABLE
+
+   @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
+   @retval EFI_DEVICE_ERROR      Can not install the protocol instance
+   @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
+**/
+EFI_STATUS
+EFIAPI
+InitializePciHostBridge (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  STATIC EFI_GUID          guidReadyToBoot = EFI_EVENT_GROUP_READY_TO_BOOT;
+  EFI_EVENT                EvtReadyToBoot;
+  EFI_STATUS               Status;
+  UINTN                    Idx1;
+  UINTN                    Idx2;
+  UINTN                    Count = 0;
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance = NULL;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance = NULL;
+  UINTN                    NumberRootPortInstalled = FALSE;
+  LIST_ENTRY               *List;
+  UINTN                    SegmentNumber;
+
+  if (( Ac01PcieCheckRootBridgeDisabled == NULL)
+      || (Ac01PcieSetup == NULL)
+      || (Ac01PcieEnd == NULL)
+      || (Ac01PcieSetupHostBridge == NULL)
+      || (Ac01PcieSetupRootBridge == NULL)
+      || (Ac01PcieConfigRW == NULL)
+      || (Ac01PcieGetTotalHBs == NULL)
+      || (Ac01PcieGetTotalRBsPerHB == NULL)
+      || (Ac01PcieGetRootBridgeAttribute == NULL ))
+  {
+    PCIE_ERR ("PciHostBridge: Invalid Parameters\n");
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PCIE_DEBUG ("%a: START\n", __FUNCTION__);
+
+  mDriverImageHandle = ImageHandle;
+
+  // Inform Pcie Core BSP Driver to start setup phase
+  Status = Ac01PcieSetup (ImageHandle, SystemTable);
+  if (EFI_ERROR (Status)) {
+    PCIE_ERR ("  PCIe Core Setup failed!\n");
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //
+  // Create Host Bridge Device Handle
+  //
+  for (Idx1 = 0; Idx1 < Ac01PcieGetTotalHBs (); Idx1++) {
+    HostBridgeInstance = AllocateCopyPool (
+                           sizeof (PCI_HOST_BRIDGE_INSTANCE),
+                           (VOID *)&mPciHostBridgeInstanceTemplate
+                           );
+    if (HostBridgeInstance == NULL) {
+      PCIE_ERR ("  HB%d allocation failed!\n", Idx1);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    Status = Ac01PcieSetupHostBridge (Idx1);
+    if (EFI_ERROR (Status)) {
+      FreePool (HostBridgeInstance);
+      PCIE_ERR ("  HB%d setup failed!\n", Idx1);
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    HostBridgeInstance->RootBridgeNumber = Ac01PcieGetTotalRBsPerHB (Idx1);
+
+    InitializeListHead (&HostBridgeInstance->Head);
+
+    Status = gBS->InstallMultipleProtocolInterfaces (
+                    &HostBridgeInstance->HostBridgeHandle,
+                    &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+                    &HostBridgeInstance->ResAlloc,
+                    NULL
+                    );
+    if (EFI_ERROR (Status)) {
+      FreePool (HostBridgeInstance);
+      PCIE_ERR ("  HB%d instance installation failed\n", Idx1);
+      return EFI_DEVICE_ERROR;
+    }
+
+    NumberRootPortInstalled = 0;
+
+    //
+    // Create Root Bridge Device Handle in this Host Bridge
+    //
+    for (Idx2 = 0; Idx2 < HostBridgeInstance->RootBridgeNumber; Idx2++, Count++) {
+      RootBridgeInstance = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));
+      if (RootBridgeInstance == NULL) {
+        gBS->UninstallMultipleProtocolInterfaces (
+               HostBridgeInstance->HostBridgeHandle,
+               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+               &HostBridgeInstance->ResAlloc,
+               NULL
+               );
+        PCIE_ERR ("    HB%d-RB%d allocation failed!\n", Idx1, Idx2);
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      // Initialize Hardware
+      Status = Ac01PcieSetupRootBridge (Idx1, Idx2, (VOID *)&RootBridgeInstance->RootBridge);
+      if (EFI_ERROR (Status)) {
+        FreePool (RootBridgeInstance);
+        PCIE_ERR ("    HB%d-RB%d setup failed!\n", Idx1, Idx2);
+        continue;
+      }
+
+      NumberRootPortInstalled++;
+
+      RootBridgeInstance->ConfigBuffer = AllocateZeroPool (
+                                           TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)
+                                           + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
+                                           );
+      if (RootBridgeInstance->ConfigBuffer == NULL) {
+        gBS->UninstallMultipleProtocolInterfaces (
+               HostBridgeInstance->HostBridgeHandle,
+               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+               &HostBridgeInstance->ResAlloc,
+               NULL
+               );
+        FreePool (RootBridgeInstance);
+        PCIE_ERR ("    HB%d-RB%d Descriptor allocation failed!\n", Idx1, Idx2);
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      RootBridgeInstance->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
+      RootBridgeInstance->RootBridge.DevicePath =
+        (EFI_DEVICE_PATH_PROTOCOL *)GenerateRootBridgeDevicePath (Idx1, Idx2);
+
+      SegmentNumber = Count;
+      if (Ac01PcieGetRootBridgeSegmentNumber) {
+        SegmentNumber = Ac01PcieGetRootBridgeSegmentNumber (Idx1, Idx2);
+      }
+
+      RootBridgeConstructor (
+        RootBridgeInstance,
+        HostBridgeInstance->HostBridgeHandle,
+        Ac01PcieGetRootBridgeAttribute (Idx1, Idx2),
+        SegmentNumber
+        );
+
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &RootBridgeInstance->RootBridgeHandle,
+                      &gEfiDevicePathProtocolGuid,
+                      RootBridgeInstance->RootBridge.DevicePath,
+                      &gEfiPciRootBridgeIoProtocolGuid,
+                      &RootBridgeInstance->RbIo,
+                      NULL
+                      );
+      if (EFI_ERROR (Status)) {
+        // Uninstall all root ports of this bridge
+        List = HostBridgeInstance->Head.ForwardLink;
+        while (List != &HostBridgeInstance->Head) {
+          RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+          gBS->UninstallMultipleProtocolInterfaces (
+                 RootBridgeInstance->RootBridgeHandle,
+                 &gEfiDevicePathProtocolGuid,
+                 RootBridgeInstance->RootBridge.DevicePath,
+                 &gEfiPciRootBridgeIoProtocolGuid,
+                 &RootBridgeInstance->RbIo,
+                 NULL
+                 );
+          FreePool (RootBridgeInstance->ConfigBuffer);
+          FreePool (RootBridgeInstance);
+          List = List->ForwardLink;
+        }
+
+        gBS->UninstallMultipleProtocolInterfaces (
+               HostBridgeInstance->HostBridgeHandle,
+               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+               &HostBridgeInstance->ResAlloc,
+               NULL
+               );
+        FreePool (HostBridgeInstance);
+        PCIE_ERR ("    HB%d-RB%d instance installation failed\n", Idx1, Idx2);
+        return EFI_DEVICE_ERROR;
+      }
+
+      InsertTailList (&HostBridgeInstance->Head, &RootBridgeInstance->Link);
+    }
+
+    if (NumberRootPortInstalled == 0) {
+      PCIE_WARN ("  No Root Port! Uninstalling HB%d\n", Idx1);
+      gBS->UninstallMultipleProtocolInterfaces (
+             HostBridgeInstance->HostBridgeHandle,
+             &gEfiPciHostBridgeResourceAllocationProtocolGuid,
+             &HostBridgeInstance->ResAlloc,
+             NULL
+             );
+      FreePool (HostBridgeInstance);
+    }
+  }
+
+  // Inform BSP Pcie Driver to end setup phase
+  Ac01PcieEnd ();
+
+  /* Event for ACPI Menu configuration */
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,                 // Type,
+                  TPL_NOTIFY,                        // NotifyTpl
+                  PciHostBridgeReadyToBootEvent,     // NotifyFunction
+                  NULL,                              // NotifyContext
+                  &guidReadyToBoot,                  // EventGroup
+                  &EvtReadyToBoot                    // Event
+                  );
+
+  PCIE_DEBUG ("%a: END\n", __FUNCTION__);
+
+  return Status;
+}
+
+/**
+   These are the notifications from the PCI bus driver that it is about to enter a certain
+   phase of the PCI enumeration process.
+
+   This member function can be used to notify the host bridge driver to perform specific actions,
+   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
+   Eight notification points are defined at this time. See belows:
+   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
+                                          structures. The PCI enumerator should issue this notification
+                                          before starting a fresh enumeration process. Enumeration cannot
+                                          be restarted after sending any other notification such as
+                                          EfiPciHostBridgeBeginBusAllocation.
+   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
+                                          required here. This notification can be used to perform any
+                                          chipset-specific programming.
+   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
+                                          specific action is required here. This notification can be used to
+                                          perform any chipset-specific programming.
+   EfiPciHostBridgeBeginResourceAllocation
+                                          The resource allocation phase is about to begin. No specific
+                                          action is required here. This notification can be used to perform
+                                          any chipset-specific programming.
+   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
+                                          root bridges. These resource settings are returned on the next call to
+                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
+                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
+                                          for gathering I/O and memory requests for
+                                          all the PCI root bridges and submitting these requests using
+                                          SubmitResources(). This function pads the resource amount
+                                          to suit the root bridge hardware, takes care of dependencies between
+                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
+                                          with the allocation request. In the case of padding, the allocated range
+                                          could be bigger than what was requested.
+   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
+                                          resources (proposed resources) for all the PCI root bridges. After the
+                                          hardware is programmed, reassigning resources will not be supported.
+                                          The bus settings are not affected.
+   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
+                                          root bridges and resets the I/O and memory apertures to their initial
+                                          state. The bus settings are not affected. If the request to allocate
+                                          resources fails, the PCI enumerator can use this notification to
+                                          deallocate previous resources, adjust the requests, and retry
+                                          allocation.
+   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
+                                          required here. This notification can be used to perform any chipsetspecific
+                                          programming.
+
+   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in] Phase               The phase during enumeration
+
+   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
+                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
+                                  SubmitResources() has not been called for one or more
+                                  PCI root bridges before this call
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
+                                  for a Phase of EfiPciHostBridgeSetResources.
+   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
+                                  previously submitted resource requests cannot be fulfilled or
+                                  were only partially fulfilled.
+   @retval EFI_SUCCESS            The notification was accepted without any errors.
+
+**/
+EFI_STATUS
+EFIAPI
+NotifyPhase (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE        *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE        *RootBridgeInstance;
+  PCI_RESOURCE_TYPE               Index;
+  PCI_RES_NODE                    *ResNode;
+  LIST_ENTRY                      *List;
+  EFI_PHYSICAL_ADDRESS            AddrBase;
+  EFI_PHYSICAL_ADDRESS            AddrLimit;
+  UINT64                          AddrLen;
+  UINTN                           BitsOfAlignment;
+  EFI_STATUS                      Status;
+  EFI_STATUS                      ReturnStatus;
+  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevPath;
+  UINTN                           HostBridgeIdx, RootBridgeIdx;
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  ReturnStatus = EFI_SUCCESS;
+
+  switch (Phase) {
+
+  case EfiPciHostBridgeBeginEnumeration:
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginEnumeration)\n");
+
+    if (!HostBridgeInstance->CanRestarted) {
+      return EFI_NOT_READY;
+    }
+
+    //
+    // Reset each Root Bridge
+    //
+    List = HostBridgeInstance->Head.ForwardLink;
+    while (List != &HostBridgeInstance->Head) {
+      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+      for (Index = TypeIo; Index < TypeMax; Index++) {
+        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
+
+        ResNode->Type      = Index;
+        ResNode->Base      = 0;
+        ResNode->Length    = 0;
+        ResNode->Status    = ResNone;
+      }
+
+      List = List->ForwardLink;
+    }
+
+    HostBridgeInstance->ResourceSubmited = FALSE;
+    HostBridgeInstance->CanRestarted     = TRUE;
+    break;
+
+  case EfiPciHostBridgeEndEnumeration:
+    //
+    // The Host Bridge Enumeration is completed. No specific action is required here.
+    // This notification can be used to perform any chipset specific programming.
+    //
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndEnumeration)\n");
+    break;
+
+  case EfiPciHostBridgeBeginBusAllocation:
+    // No specific action is required here, can perform any chipset specific programing
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginBusAllocation)\n");
+    HostBridgeInstance->CanRestarted = FALSE;
+    break;
+
+  case EfiPciHostBridgeEndBusAllocation:
+    // No specific action is required here, can perform any chipset specific programing
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndBusAllocation)\n");
+    break;
+
+  case EfiPciHostBridgeBeginResourceAllocation:
+    // No specific action is required here, can perform any chipset specific programing
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginResourceAllocation)\n");
+    break;
+
+  case EfiPciHostBridgeAllocateResources:
+
+    // Make sure the resource for all root bridges has been submitted.
+    if (!HostBridgeInstance->ResourceSubmited) {
+      return EFI_NOT_READY;
+    }
+
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (AllocateResources)\n");
+
+    //
+    // Take care of the resource dependencies between the root bridges
+    //
+    List = HostBridgeInstance->Head.ForwardLink;
+    while (List != &HostBridgeInstance->Head) {
+
+      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+      for (Index = TypeIo; Index < TypeMax; Index++) {
+        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
+
+        if (ResNode->Status == ResNone) {
+          continue;
+        }
+
+        switch (Index) {
+        case TypeIo:
+          AddrBase = RootBridgeInstance->RootBridge.Io.Base;
+          AddrLimit = RootBridgeInstance->RootBridge.Io.Limit;
+          break;
+
+        case TypeMem32:
+          AddrBase = RootBridgeInstance->RootBridge.Mem.Base;
+          AddrLimit = RootBridgeInstance->RootBridge.Mem.Limit;
+          break;
+
+        case TypePMem32:
+          AddrBase = RootBridgeInstance->RootBridge.PMem.Base;
+          AddrLimit = RootBridgeInstance->RootBridge.PMem.Limit;
+          break;
+
+        case TypeMem64:
+          AddrBase = RootBridgeInstance->RootBridge.MemAbove4G.Base;
+          AddrLimit = RootBridgeInstance->RootBridge.MemAbove4G.Limit;
+          break;
+
+        case TypePMem64:
+          AddrBase = RootBridgeInstance->RootBridge.PMemAbove4G.Base;
+          AddrLimit = RootBridgeInstance->RootBridge.PMemAbove4G.Limit;
+          break;
+
+        default:
+          continue;
+        } // end switch (Index)
+
+        AddrLen = ResNode->Length;
+
+        if ((AddrBase + AddrLen - 1) > AddrLimit) {
+          ReturnStatus = EFI_OUT_OF_RESOURCES;
+          ResNode->Length = 0;
+        } else {
+          // Get the number of '1' in Alignment.
+          BitsOfAlignment = (UINTN)(HighBitSet64 (ResNode->Alignment) + 1);
+
+          Status = gDS->AllocateMemorySpace (
+                          EfiGcdAllocateAddress,
+                          EfiGcdMemoryTypeMemoryMappedIo,
+                          BitsOfAlignment,
+                          AddrLen,
+                          &AddrBase,
+                          mDriverImageHandle,
+                          NULL
+                          );
+
+          if (!EFI_ERROR (Status)) {
+            ResNode->Base   = (UINTN)AddrBase;
+            ResNode->Status = ResAllocated;
+          } else {
+            ReturnStatus = EFI_OUT_OF_RESOURCES;
+            ResNode->Length = 0;
+          }
+        }
+      } // end for
+      List = List->ForwardLink;
+    } // end while
+
+    break;
+
+  case EfiPciHostBridgeSetResources:
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (SetResources)\n");
+    break;
+
+  case EfiPciHostBridgeFreeResources:
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (FreeResources)\n");
+
+    List = HostBridgeInstance->Head.ForwardLink;
+
+    while (List != &HostBridgeInstance->Head) {
+      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+      for (Index = TypeIo; Index < TypeMax; Index++) {
+        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
+
+        if (ResNode->Status == ResAllocated) {
+          AddrLen = ResNode->Length;
+          AddrBase = ResNode->Base;
+
+          switch (Index) {
+          case TypeIo:
+          case TypeMem32:
+          case TypePMem32:
+          case TypeMem64:
+          case TypePMem64:
+            Status = gDS->FreeMemorySpace (AddrBase, AddrLen);
+            if (EFI_ERROR (Status)) {
+              ReturnStatus = Status;
+            }
+            break;
+
+          default:
+            continue;
+          } // end switch (Index)
+
+          ResNode->Type      = Index;
+          ResNode->Base      = 0;
+          ResNode->Length    = 0;
+          ResNode->Status    = ResNone;
+        }
+      }
+
+      List = List->ForwardLink;
+    }
+
+    HostBridgeInstance->ResourceSubmited = FALSE;
+    HostBridgeInstance->CanRestarted     = TRUE;
+    break;
+
+  case EfiPciHostBridgeEndResourceAllocation:
+    //
+    // The resource allocation phase is completed.  No specific action is required
+    // here. This notification can be used to perform any chipset specific programming.
+    //
+    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndResourceAllocation)\n");
+    HostBridgeInstance->CanRestarted = FALSE;
+    break;
+
+  default:
+    return EFI_INVALID_PARAMETER;
+  }
+
+  // Notify BSP Driver the phase we are being
+  List = HostBridgeInstance->Head.ForwardLink;
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+    // Retrieve the HostBridgeIdx and RootBridgeIdx from UID
+    // UID = (UINT32)((HostBridgeIdx << 16) + RootBridgeIdx);
+    DevPath = (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *)RootBridgeInstance->RootBridge.DevicePath;
+    HostBridgeIdx = DevPath->AcpiDevicePath.UID / (1<<16);
+    RootBridgeIdx = DevPath->AcpiDevicePath.UID % (1<<16);
+
+    // Notify BSP Driver
+    if (Ac01PcieHostBridgeNotifyPhase != NULL) {
+      Ac01PcieHostBridgeNotifyPhase (HostBridgeIdx, RootBridgeIdx, Phase);
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return ReturnStatus;
+}
+
+/**
+   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
+
+   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
+   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
+   root bridges. On each call, the handle that was returned by the previous call is passed into the
+   interface, and on output the interface returns the device handle of the next PCI root bridge. The
+   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+   for that root bridge. When there are no more PCI root bridges to report, the interface returns
+   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
+   are returned by this function.
+   For D945 implementation, there is only one root bridge in PCI host bridge.
+
+   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
+
+   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
+                                  specific Host bridge and return EFI_SUCCESS.
+   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
+                                  returned on a previous call to GetNextRootBridge().
+**/
+EFI_STATUS
+EFIAPI
+GetNextRootBridge (
+  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN OUT EFI_HANDLE                                       *RootBridgeHandle
+  )
+{
+  BOOLEAN                  NoRootBridge;
+  LIST_ENTRY               *List;
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+  NoRootBridge = TRUE;
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    NoRootBridge = FALSE;
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+    if (*RootBridgeHandle == NULL) {
+      //
+      // Return the first Root Bridge Handle of the Host Bridge
+      //
+      *RootBridgeHandle = RootBridgeInstance->RootBridgeHandle;
+
+      return EFI_SUCCESS;
+    } else {
+      if (*RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+        //
+        // Get next if have
+        //
+        List = List->ForwardLink;
+
+        if (List != &HostBridgeInstance->Head) {
+          RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+          *RootBridgeHandle = RootBridgeInstance->RootBridgeHandle;
+
+          return EFI_SUCCESS;
+        }
+
+        return EFI_NOT_FOUND;
+      }
+    }
+
+    List = List->ForwardLink;
+  } // end while
+
+  return NoRootBridge ? EFI_NOT_FOUND : EFI_INVALID_PARAMETER;
+}
+
+/**
+   Returns the allocation attributes of a PCI root bridge.
+
+   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
+   from one PCI root bridge to another. These attributes are different from the decode-related
+   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
+   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
+   handles of all the root bridges that are associated with this host bridge must be obtained by calling
+   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
+   after the enumeration process. The hardware may provide mechanisms to change the attributes on
+   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
+   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
+   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
+   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
+   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
+   prefetchable memory.
+      Attribute                                 Description
+   ------------------------------------         ----------------------------------------------------------------------
+   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
+                                                windows for nonprefetchable and prefetchable memory. A PCI bus
+                                                driver needs to include requests for prefetchable memory in the
+                                                nonprefetchable memory pool.
+
+   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
+                                                windows. If this bit is not set, the PCI bus driver needs to include
+                                                requests for a 64-bit memory address in the corresponding 32-bit
+                                                memory pool.
+
+   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
+   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
+                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
+
+   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
+   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
+   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+GetAttributes (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                           *Attributes
+  )
+{
+  LIST_ENTRY               *List;
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+  if (Attributes == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      *Attributes = RootBridgeInstance->RootBridgeAttrib;
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  //
+  // RootBridgeHandle is not an EFI_HANDLE
+  // that was returned on a previous call to GetNextRootBridge()
+  //
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Sets up the specified PCI root bridge for the bus enumeration process.
+
+   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
+   over which the search should be performed in ACPI 2.0 resource descriptor format.
+
+   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
+   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
+   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
+
+   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
+   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
+   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
+
+**/
+EFI_STATUS
+EFIAPI
+StartBusEnumeration (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+{
+  LIST_ENTRY               *List;
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+  VOID                     *Buffer;
+  UINT8                    *Temp;
+  UINT64                   BusStart;
+  UINT64                   BusEnd;
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      //
+      // Set up the Root Bridge for Bus Enumeration
+      //
+      BusStart = RootBridgeInstance->RootBridge.Bus.Base;
+      BusEnd   = RootBridgeInstance->RootBridge.Bus.Limit;
+
+      Buffer = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
+      if (Buffer == NULL) {
+        return EFI_OUT_OF_RESOURCES;
+      }
+
+      Temp = (UINT8 *)Buffer;
+
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = BusEnd;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
+      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
+
+      Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = ACPI_END_TAG_DESCRIPTOR;
+      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
+
+      *Configuration = Buffer;
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
+
+   This member function programs the specified PCI root bridge to decode the bus range that is
+   specified by the input parameter Configuration.
+   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
+
+   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
+   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
+   @param[in] Configuration     The pointer to the PCI bus resource descriptor
+
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
+                                  bus descriptors.
+   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
+   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+SetBusNumbers (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+{
+  LIST_ENTRY               *List;
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+  PCI_RES_NODE             *ResNode;
+  UINT8                    *Ptr;
+  UINTN                    BusStart;
+  UINTN                    BusEnd;
+  UINTN                    BusLen;
+
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr = Configuration;
+
+  //
+  // Check the Configuration is valid
+  //
+  if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  Ptr = Configuration;
+
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
+      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
+      BusEnd = BusStart + BusLen - 1;
+
+      if (BusStart > BusEnd) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if ((BusStart < RootBridgeInstance->RootBridge.Bus.Base) ||
+          (BusEnd > RootBridgeInstance->RootBridge.Bus.Limit))
+      {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      //
+      // Update the Bus Range
+      //
+      ResNode = &(RootBridgeInstance->ResAllocNode[TypeBus]);
+      ResNode->Base   = BusStart;
+      ResNode->Length = BusLen;
+      ResNode->Status = ResAllocated;
+
+      return EFI_SUCCESS;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  return EFI_INVALID_PARAMETER;
+}
+
+/**
+   Submits the I/O and memory resource requirements for the specified PCI root bridge.
+
+   This function is used to submit all the I/O and memory resources that are required by the specified
+   PCI root bridge. The input parameter Configuration is used to specify the following:
+   - The various types of resources that are required
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
+   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
+
+   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
+   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
+                                  not supported by this PCI root bridge. This error will happen if the caller
+                                  did not combine resources according to Attributes that were returned by
+                                  GetAllocAttributes().
+   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
+   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+SubmitResources (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN VOID                                             *Configuration
+  )
+{
+  LIST_ENTRY                        *List;
+  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance = NULL;
+  PCI_RES_NODE                      *ResNode;
+  UINT8                             *Temp;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
+  UINTN                             Index = 0;
+  UINTN                             AddrSpaceCnt = 0;
+  UINTN                             i;
+
+  //
+  // Check the input parameter: Configuration
+  //
+  if (Configuration == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Input resource descriptor must end properly
+  //
+  Temp = (UINT8 *)Configuration;
+  AddrSpaceCnt = 0;
+  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+    AddrSpaceCnt++;
+  }
+  if (*Temp != ACPI_END_TAG_DESCRIPTOR) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Get the corresponding Root Bridge Instance
+  //
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      break;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  if (RootBridgeHandle != RootBridgeInstance->RootBridgeHandle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PCIE_DEBUG ("%a: \n", __FUNCTION__);
+
+  Temp = (UINT8 *)Configuration;
+  for (i = 0; i < AddrSpaceCnt; i++) {
+    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;
+
+    PCIE_DEBUG ("Ptr->ResType:%d\n", Ptr->ResType);
+    PCIE_DEBUG ("Ptr->Addrlen:0x%llx\n", Ptr->AddrLen);
+    PCIE_DEBUG ("Ptr->AddrRangeMax:0x%llx\n", Ptr->AddrRangeMax);
+    PCIE_DEBUG ("Ptr->AddrRangeMin:0x%llx\n", Ptr->AddrRangeMin);
+    PCIE_DEBUG ("Ptr->SpecificFlag:0x%llx\n", Ptr->SpecificFlag);
+    PCIE_DEBUG ("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
+    PCIE_DEBUG ("RootBridgeInstance->RootBridgeAttrib:0x%llx\n", RootBridgeInstance->RootBridgeAttrib);
+
+    switch (Ptr->ResType) {
+    case ACPI_ADDRESS_SPACE_TYPE_MEM:
+
+      if (Ptr->AddrSpaceGranularity != 32 && Ptr->AddrSpaceGranularity != 64) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      if (Ptr->AddrSpaceGranularity == 32) {
+        if (Ptr->AddrLen >= SIZE_4GB) {
+          return EFI_INVALID_PARAMETER;
+        }
+
+        Index = (Ptr->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) ?
+                TypePMem32 : TypeMem32;
+      }
+
+      if (Ptr->AddrSpaceGranularity == 64) {
+        Index = (Ptr->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) ?
+                TypePMem64 : TypeMem64;
+      }
+
+      break;
+
+    case ACPI_ADDRESS_SPACE_TYPE_IO:
+      //
+      // Check address range alignment
+      //
+      if (Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
+        return EFI_INVALID_PARAMETER;
+      }
+
+      Index = TypeIo;
+      break;
+
+    case ACPI_ADDRESS_SPACE_TYPE_BUS:
+    default:
+      ASSERT (FALSE);
+      break;
+    }
+
+    ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
+    ResNode->Length  = Ptr->AddrLen;
+    ResNode->Alignment = Ptr->AddrRangeMax;
+    ResNode->Status  = ResSubmitted;
+
+    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
+  }
+
+  HostBridgeInstance->ResourceSubmited = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+   Returns the proposed resource settings for the specified PCI root bridge.
+
+   This member function returns the proposed resource settings for the specified PCI root bridge. The
+   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
+   EfiPciHostBridgeAllocateResources. The output parameter Configuration
+   specifies the following:
+   - The various types of resources, excluding bus resources, that are allocated
+   - The associated lengths in terms of ACPI 2.0 resource descriptor format
+
+   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
+
+   @retval EFI_SUCCESS            The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+GetProposedResources (
+  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN  EFI_HANDLE                                       RootBridgeHandle,
+  OUT VOID                                             **Configuration
+  )
+{
+  LIST_ENTRY                        *List = NULL;
+  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance = NULL;
+  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance = NULL;
+  UINTN                             Index = 0;
+  VOID                              *Buffer = NULL;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor = NULL;
+  EFI_ACPI_END_TAG_DESCRIPTOR       *End = NULL;
+  UINT64                            ResStatus;
+
+  Buffer = NULL;
+
+  PCIE_DEBUG ("%a: \n", __FUNCTION__);
+
+  //
+  // Get the Host Bridge Instance from the resource allocation protocol
+  //
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Get the corresponding Root Bridge Instance
+  //
+  while (List != &HostBridgeInstance->Head) {
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      break;
+    }
+
+    List = List->ForwardLink;
+  }
+
+  if (RootBridgeHandle != RootBridgeInstance->RootBridgeHandle) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Buffer = AllocateZeroPool (
+             (TypeMax - 1) * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +
+             sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
+             );
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Buffer;
+  for (Index = TypeIo; Index < TypeMax; Index++) {
+    ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
+
+    switch (Index) {
+    case TypeIo:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_IO;
+      Descriptor->SpecificFlag         = 0;
+      Descriptor->AddrSpaceGranularity = 32;
+      break;
+
+    case TypeMem32:
+    case TypePMem32:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Descriptor->SpecificFlag         = (Index == TypeMem32) ? 0 :
+                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
+      Descriptor->AddrSpaceGranularity = 32;
+      break;
+
+    case TypeMem64:
+    case TypePMem64:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Descriptor->SpecificFlag         = (Index == TypeMem64) ? 0 :
+                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
+      Descriptor->AddrSpaceGranularity = 64;
+      break;
+
+    default:
+      continue;
+    }
+
+    Descriptor->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+    Descriptor->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+    Descriptor->GenFlag               = 0;
+    Descriptor->AddrRangeMin          = RootBridgeInstance->ResAllocNode[Index].Base;
+    Descriptor->AddrLen               = RootBridgeInstance->ResAllocNode[Index].Length;
+    Descriptor->AddrRangeMax          = Descriptor->AddrRangeMin + Descriptor->AddrLen - 1;
+    Descriptor->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : PCI_RESOURCE_LESS;
+
+    PCIE_DEBUG ("Descriptor->ResType:%d\n", Descriptor->ResType);
+    PCIE_DEBUG ("Descriptor->Addrlen:%llx\n", Descriptor->AddrLen);
+    PCIE_DEBUG ("Descriptor->AddrRangeMax:%llx\n", Descriptor->AddrRangeMax);
+    PCIE_DEBUG ("Descriptor->AddrRangeMin:%llx\n", Descriptor->AddrRangeMin);
+    PCIE_DEBUG ("Descriptor->SpecificFlag:%llx\n", Descriptor->SpecificFlag);
+    PCIE_DEBUG ("Descriptor->AddrTranslationOffset:%d\n", Descriptor->AddrTranslationOffset);
+    PCIE_DEBUG ("Descriptor->AddrSpaceGranularity:%d\n", Descriptor->AddrSpaceGranularity);
+
+    Descriptor++;
+  }
+
+  //
+  // Terminate the entries.
+  //
+  End = (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor;
+  End->Desc      = ACPI_END_TAG_DESCRIPTOR;
+  End->Checksum  = 0x0;
+
+  *Configuration = Buffer;
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
+   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
+   PCI controllers before enumeration.
+
+   This function is called during the PCI enumeration process. No specific action is expected from this
+   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
+   enumeration.
+
+   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
+                            InstallProtocolInterface() in the UEFI 2.0 Specification.
+   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
+                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
+                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
+                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
+   @param Phase             The phase of the PCI device enumeration.
+
+   @retval EFI_SUCCESS              The requested parameters were returned.
+   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
+   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
+                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
+   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
+                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
+                                    bridge.
+
+**/
+EFI_STATUS
+EFIAPI
+PreprocessController (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS      PciAddress,
+  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+  LIST_ENTRY               *List;
+
+  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
+  List = HostBridgeInstance->Head.ForwardLink;
+
+  //
+  // Enumerate the root bridges in this host bridge
+  //
+  while (List != &HostBridgeInstance->Head) {
+
+    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
+    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
+      break;
+    }
+    List = List->ForwardLink;
+  }
+
+  if (List == &HostBridgeInstance->Head) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
new file mode 100644
index 000000000000..552a5f6de4c6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
@@ -0,0 +1,1582 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <IndustryStandard/Pci.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcieCoreLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PciHostBridgeLib.h>
+#include <Library/PciLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiLib.h>
+
+#include "PciHostBridge.h"
+#include "PciRootBridgeIo.h"
+
+//
+// Memory Controller Pci Root Bridge Io Module Variables
+//
+EFI_METRONOME_ARCH_PROTOCOL *mMetronome = NULL;
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mInStride[] = {
+  1, // EfiPciWidthUint8
+  2, // EfiPciWidthUint16
+  4, // EfiPciWidthUint32
+  8, // EfiPciWidthUint64
+  0, // EfiPciWidthFifoUint8
+  0, // EfiPciWidthFifoUint16
+  0, // EfiPciWidthFifoUint32
+  0, // EfiPciWidthFifoUint64
+  1, // EfiPciWidthFillUint8
+  2, // EfiPciWidthFillUint16
+  4, // EfiPciWidthFillUint32
+  8  // EfiPciWidthFillUint64
+};
+
+//
+// Lookup table for increment values based on transfer widths
+//
+UINT8 mOutStride[] = {
+  1, // EfiPciWidthUint8
+  2, // EfiPciWidthUint16
+  4, // EfiPciWidthUint32
+  8, // EfiPciWidthUint64
+  1, // EfiPciWidthFifoUint8
+  2, // EfiPciWidthFifoUint16
+  4, // EfiPciWidthFifoUint32
+  8, // EfiPciWidthFifoUint64
+  0, // EfiPciWidthFillUint8
+  0, // EfiPciWidthFillUint16
+  0, // EfiPciWidthFillUint32
+  0  // EfiPciWidthFillUint64
+};
+
+/**
+  Check parameters for IO, MMIO, PCI read/write services of PCI Root Bridge IO.
+
+  The I/O operations are carried out exactly as requested. The caller is
+  responsible for satisfying any alignment and I/O width restrictions that a PI
+  System on a platform might require. For example on some platforms, width
+  requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other
+  hand, will be handled by the driver.
+
+  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.
+
+  @param[in] Width          Signifies the width of the I/O or Memory operation.
+
+  @param[in] Address        The base address of the I/O operation.
+
+  @param[in] Count          The number of I/O operations to perform. The number
+                            of bytes moved is Width size * Count, starting at
+                            Address.
+
+  @param[in] Buffer         For read operations, the destination buffer to
+                            store the results. For write operations, the source
+                            buffer from which to write data.
+
+  @retval EFI_SUCCESS            The parameters for this request pass the
+                                 checks.
+
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
+
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+
+  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
+
+  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
+                                 and Count is not valid for this PI system.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCheckParameter (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN OPERATION_TYPE                        OperationType,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                Address,
+  IN UINTN                                 Count,
+  IN VOID                                  *Buffer
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE                    *RootBridgeInstance;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
+  UINT64                                      MaxCount;
+  UINT64                                      Base = 0;
+  UINT64                                      Limit = 0;
+  UINT32                                      Size;
+
+  //
+  // Check to see if Buffer is NULL
+  //
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Check to see if Width is in the valid range
+  //
+  if ((UINT32)Width >= EfiPciWidthMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // For FIFO type, the target address won't increase during the access,
+  // so treat Count as 1
+  //
+  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
+    Count = 1;
+  }
+
+  //
+  // Check to see if Width is in the valid range for I/O Port operations
+  //
+  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  Size  = 1 << Width;
+
+  //
+  // Config space accessing does not support 64-bit width
+  //
+  if ((OperationType == PciOperation) && (Width == EfiPciWidthUint64)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
+
+  //
+  // Check to see if any address associated with this transfer exceeds the
+  // maximum allowed address.  The maximum address implied by the parameters
+  // passed in is Address + Size * Count.  If the following condition is met,
+  // then the transfer is not supported.
+  //
+  //    Address + Size * Count > Limit + 1
+  //
+  // Since Limit can be the maximum integer value supported by the CPU and
+  // Count can also be the maximum integer value supported by the CPU, this
+  // range check must be adjusted to avoid all oveflow conditions.
+  //
+  if (OperationType == IoOperation) {
+    if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.Io.Limit + 1) {
+      Base = RootBridgeInstance->RootBridge.Io.Base;
+      Limit = RootBridgeInstance->RootBridge.Io.Limit;
+    }
+  } else if (OperationType == MemOperation) {
+    if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.Mem.Limit + 1) {
+      Base = RootBridgeInstance->RootBridge.Mem.Base;
+      Limit = RootBridgeInstance->RootBridge.Mem.Limit;
+    } else if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.PMem.Limit + 1) {
+      Base = RootBridgeInstance->RootBridge.PMem.Base;
+      Limit = RootBridgeInstance->RootBridge.PMem.Limit;
+    } else if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.MemAbove4G.Limit + 1) {
+      Base = RootBridgeInstance->RootBridge.MemAbove4G.Base;
+      Limit = RootBridgeInstance->RootBridge.MemAbove4G.Limit;
+    } else {
+      Base = RootBridgeInstance->RootBridge.PMemAbove4G.Base;
+      Limit = RootBridgeInstance->RootBridge.PMemAbove4G.Limit;
+    }
+  } else {
+    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;
+    if (PciRbAddr->Bus < RootBridgeInstance->RootBridge.Bus.Base ||
+        PciRbAddr->Bus > RootBridgeInstance->RootBridge.Bus.Limit)
+    {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    if (PciRbAddr->Device > PCI_MAX_DEVICE ||
+        PciRbAddr->Function > PCI_MAX_FUNC)
+    {
+      return EFI_INVALID_PARAMETER;
+    }
+
+    Address = (PciRbAddr->ExtendedRegister != 0) ?
+              PciRbAddr->ExtendedRegister :
+              PciRbAddr->Register;
+
+    Base = 0;
+    Limit = RootBridgeInstance->RootBridge.NoExtendedConfigSpace ? 0xFF : 0xFFF;
+  }
+
+  //
+  // Check to see if Address is aligned
+  // ( Address is derived from  Extended register/Register.
+  //   Now we can safely check the alignments )
+  //
+  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (Address < Base) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Count == 0) {
+    if (Address > Limit) {
+      return EFI_UNSUPPORTED;
+    }
+  } else {
+    MaxCount = RShiftU64 (Limit, Width);
+    if (MaxCount < (Count - 1)) {
+      return EFI_UNSUPPORTED;
+    }
+    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Internal help function for read and write memory space.
+
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Write         Switch value for Read or Write.
+   @param[in]   Width         Signifies the width of the memory operations.
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
+                              moved is Width size * Count, starting at Address.
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+                              write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN     BOOLEAN                               Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN     UINT64                                Address,
+  IN     UINTN                                 Count,
+  IN OUT VOID                                  *Buffer
+  )
+{
+  EFI_STATUS                            Status;
+  UINT8                                 InStride;
+  UINT8                                 OutStride;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
+  UINT8                                 *Uint8Buffer;
+
+  PCIE_MMIO_DEBUG (
+    "%a: W: %d, Width: %d, Addr: 0x%lx, Count: %d\n",
+    __FUNCTION__,
+    Write,
+    Width,
+    Address,
+    Count
+    );
+
+  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (Write) {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint16:
+        MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+        break;
+
+      case EfiPciWidthUint32:
+        MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+        break;
+
+      case EfiPciWidthUint64:
+        MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    } else {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        *Uint8Buffer = MmioRead8 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint16:
+        *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint32:
+        *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint64:
+        *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Internal help function for read and write IO space.
+
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Write         Switch value for Read or Write.
+   @param[in]   Width         Signifies the width of the memory operations.
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
+                              moved is Width size * Count, starting at Address.
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+                              write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN     BOOLEAN                               Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN     UINT64                                Address,
+  IN     UINTN                                 Count,
+  IN OUT VOID                                  *Buffer
+  )
+{
+  EFI_STATUS                            Status;
+  UINT8                                 InStride;
+  UINT8                                 OutStride;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
+  UINT8                                 *Uint8Buffer;
+
+  PCIE_MMIO_DEBUG (
+    "%a: W: %d, Width: %d, Addr: 0x%lx, Count: %d\n",
+    __FUNCTION__,
+    Write,
+    Width,
+    Address,
+    Count
+    );
+
+  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  InStride = mInStride[Width];
+  OutStride = mOutStride[Width];
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+
+  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
+    if (Write) {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        MmioWrite8 ((UINTN)Address, *Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint16:
+        MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
+        break;
+
+      case EfiPciWidthUint32:
+        MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
+        break;
+
+      case EfiPciWidthUint64:
+        MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    } else {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        *Uint8Buffer = MmioRead8 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint16:
+        *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint32:
+        *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
+        break;
+
+      case EfiPciWidthUint64:
+        *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Internal help function for read and write PCI configuration space.
+
+   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+   @param[in]   Write         Switch value for Read or Write.
+   @param[in]   Width         Signifies the width of the memory operations.
+   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
+   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
+                              moved is Width size * Count, starting at Address.
+   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
+                              write operations, the source buffer to write data from.
+
+   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
+
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRW (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN     BOOLEAN                               Write,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN     UINT64                                Address,
+  IN     UINTN                                 Count,
+  IN OUT VOID                                  *Buffer
+  )
+{
+  EFI_STATUS                                  Status;
+  UINT8                                       InStride;
+  UINT8                                       OutStride;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH       OperationWidth;
+  UINT8                                       *Uint8Buffer;
+  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
+  UINTN                                       PcieRegAddr;
+  PCI_ROOT_BRIDGE_INSTANCE                    *RootBridgeInstance;
+
+  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;
+
+  Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
+
+  PcieRegAddr = (UINTN)PCI_LIB_ADDRESS (
+                         PciRbAddr->Bus,
+                         PciRbAddr->Device,
+                         PciRbAddr->Function,
+                         (PciRbAddr->ExtendedRegister != 0) ? PciRbAddr->ExtendedRegister : PciRbAddr->Register
+                         );
+
+  //
+  // Select loop based on the width of the transfer
+  //
+  InStride  = mInStride[Width];
+  OutStride = mOutStride[Width];
+
+  for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {
+    if (Write) {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 1, Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint16:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 2, Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint32:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 4, Uint8Buffer);
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    } else {
+      switch (OperationWidth) {
+      case EfiPciWidthUint8:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 1, Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint16:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 2, Uint8Buffer);
+        break;
+
+      case EfiPciWidthUint32:
+        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 4, Uint8Buffer);
+        break;
+
+      default:
+        //
+        // The RootBridgeIoCheckParameter call above will ensure that this
+        // path is not taken.
+        //
+        ASSERT (FALSE);
+        break;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Polls an address in memory mapped I/O space until an exit condition is met,
+  or a timeout occurs.
+
+  This function provides a standard way to poll a PCI memory location. A PCI
+  memory read operation is performed at the PCI memory address specified by
+  Address for the width specified by Width. The result of this PCI memory read
+  operation is stored in Result. This PCI memory read operation is repeated
+  until either a timeout of Delay 100 ns units has expired, or (Result & Mask)
+  is equal to Value.
+
+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in]   Width     Signifies the width of the memory operations.
+  @param[in]   Address   The base address of the memory operations. The caller
+                         is responsible for aligning Address if required.
+  @param[in]   Mask      Mask used for the polling criteria. Bytes above Width
+                         in Mask are ignored. The bits in the bytes below Width
+                         which are zero in Mask are ignored when polling the
+                         memory address.
+  @param[in]   Value     The comparison value used for the polling exit
+                         criteria.
+  @param[in]   Delay     The number of 100 ns units to poll. Note that timer
+                         available may be of poorer granularity.
+  @param[out]  Result    Pointer to the last value read from the memory
+                         location.
+
+  @retval EFI_SUCCESS            The last data returned from the access matched
+                                 the poll exit criteria.
+  @retval EFI_INVALID_PARAMETER  Width is invalid.
+  @retval EFI_INVALID_PARAMETER  Result is NULL.
+  @retval EFI_TIMEOUT            Delay expired before a match occurred.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollMem (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINT64                                Mask,
+  IN  UINT64                                Value,
+  IN  UINT64                                Delay,
+  OUT UINT64                                *Result
+  )
+{
+  EFI_STATUS Status;
+  UINT64     NumberOfTicks;
+  UINT32     Remainder;
+
+  if (Result == NULL || (UINT32)Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // No matter what, always do a single poll.
+  //
+  Status = This->Mem.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_SUCCESS;
+  }
+
+  if (mMetronome == NULL) {
+    Status = gBS->LocateProtocol (
+                    &gEfiMetronomeArchProtocolGuid,
+                    NULL,
+                    (VOID **)&mMetronome
+                    );
+    if (EFI_ERROR (Status)) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+  }
+
+  //
+  // Determine the proper # of metronome ticks to wait for polling the
+  // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+  // The "+1" to account for the possibility of the first tick being short
+  // because we started in the middle of a tick.
+  //
+  // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
+  // protocol definition is updated.
+  //
+  NumberOfTicks = DivU64x32Remainder (
+                    Delay,
+                    (UINT32)mMetronome->TickPeriod,
+                    &Remainder
+                    );
+  if (Remainder != 0) {
+    NumberOfTicks += 1;
+  }
+  NumberOfTicks += 1;
+
+  while (NumberOfTicks != 0) {
+
+    mMetronome->WaitForTick (mMetronome, 1);
+
+    Status = This->Mem.Read (This, Width, Address, 1, Result);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if ((*Result & Mask) == Value) {
+      return EFI_SUCCESS;
+    }
+
+    NumberOfTicks -= 1;
+  }
+
+  return EFI_TIMEOUT;
+}
+
+/**
+  Reads from the I/O space of a PCI Root Bridge. Returns when either the
+  polling exit criteria is satisfied or after a defined duration.
+
+  This function provides a standard way to poll a PCI I/O location. A PCI I/O
+  read operation is performed at the PCI I/O address specified by Address for
+  the width specified by Width.
+  The result of this PCI I/O read operation is stored in Result. This PCI I/O
+  read operation is repeated until either a timeout of Delay 100 ns units has
+  expired, or (Result & Mask) is equal to Value.
+
+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in] Width     Signifies the width of the I/O operations.
+  @param[in] Address   The base address of the I/O operations. The caller is
+                       responsible for aligning Address if required.
+  @param[in] Mask      Mask used for the polling criteria. Bytes above Width in
+                       Mask are ignored. The bits in the bytes below Width
+                       which are zero in Mask are ignored when polling the I/O
+                       address.
+  @param[in] Value     The comparison value used for the polling exit criteria.
+  @param[in] Delay     The number of 100 ns units to poll. Note that timer
+                       available may be of poorer granularity.
+  @param[out] Result   Pointer to the last value read from the memory location.
+
+  @retval EFI_SUCCESS            The last data returned from the access matched
+                                 the poll exit criteria.
+  @retval EFI_INVALID_PARAMETER  Width is invalid.
+  @retval EFI_INVALID_PARAMETER  Result is NULL.
+  @retval EFI_TIMEOUT            Delay expired before a match occurred.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPollIo (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINT64                                Mask,
+  IN  UINT64                                Value,
+  IN  UINT64                                Delay,
+  OUT UINT64                                *Result
+  )
+{
+  EFI_STATUS Status;
+  UINT64     NumberOfTicks;
+  UINT32     Remainder;
+
+  //
+  // No matter what, always do a single poll.
+  //
+
+  if (Result == NULL || (UINT32)Width > EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  Status = This->Io.Read (This, Width, Address, 1, Result);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  if ((*Result & Mask) == Value) {
+    return EFI_SUCCESS;
+  }
+
+  if (Delay == 0) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Determine the proper # of metronome ticks to wait for polling the
+  // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
+  // The "+1" to account for the possibility of the first tick being short
+  // because we started in the middle of a tick.
+  //
+  NumberOfTicks = DivU64x32Remainder (
+                    Delay,
+                    (UINT32)mMetronome->TickPeriod,
+                    &Remainder
+                    );
+  if (Remainder != 0) {
+    NumberOfTicks += 1;
+  }
+  NumberOfTicks += 1;
+
+  while (NumberOfTicks != 0) {
+
+    mMetronome->WaitForTick (mMetronome, 1);
+
+    Status = This->Io.Read (This, Width, Address, 1, Result);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if ((*Result & Mask) == Value) {
+      return EFI_SUCCESS;
+    }
+
+    NumberOfTicks -= 1;
+  }
+  return EFI_TIMEOUT;
+}
+
+/**
+  Enables a PCI driver to access PCI controller registers in the PCI root
+  bridge memory space.
+
+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
+  controller registers in the PCI root bridge memory space.
+  The memory operations are carried out exactly as requested. The caller is
+  responsible for satisfying any alignment and memory width restrictions that a
+  PCI Root Bridge on a platform might require.
+
+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in]   Width     Signifies the width of the memory operation.
+  @param[in]   Address   The base address of the memory operation. The caller
+                         is responsible for aligning the Address if required.
+  @param[in]   Count     The number of memory operations to perform. Bytes
+                         moved is Width size * Count, starting at Address.
+  @param[out]  Buffer    For read operations, the destination buffer to store
+                         the results. For write operations, the source buffer
+                         to write data from.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PCI
+                                 root bridge.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+  Enables a PCI driver to access PCI controller registers in the PCI root
+  bridge memory space.
+
+  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
+  controller registers in the PCI root bridge memory space.
+  The memory operations are carried out exactly as requested. The caller is
+  responsible for satisfying any alignment and memory width restrictions that a
+  PCI Root Bridge on a platform might require.
+
+  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in]   Width     Signifies the width of the memory operation.
+  @param[in]   Address   The base address of the memory operation. The caller
+                         is responsible for aligning the Address if required.
+  @param[in]   Count     The number of memory operations to perform. Bytes
+                         moved is Width size * Count, starting at Address.
+  @param[in]   Buffer    For read operations, the destination buffer to store
+                         the results. For write operations, the source buffer
+                         to write data from.
+
+  @retval EFI_SUCCESS            The data was read from or written to the PCI
+                                 root bridge.
+  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
+  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
+                                 lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMemWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                Address,
+  IN UINTN                                 Count,
+  IN VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+  Enables a PCI driver to access PCI controller registers in the PCI root
+  bridge I/O space.
+
+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in]   Width       Signifies the width of the memory operations.
+  @param[in]   Address     The base address of the I/O operation. The caller is
+                           responsible for aligning the Address if required.
+  @param[in]   Count       The number of I/O operations to perform. Bytes moved
+                           is Width size * Count, starting at Address.
+  @param[out]  Buffer      For read operations, the destination buffer to store
+                           the results. For write operations, the source buffer
+                           to write data from.
+
+  @retval EFI_SUCCESS              The data was read from or written to the PCI
+                                   root bridge.
+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a
+                                   lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+  Enables a PCI driver to access PCI controller registers in the PCI root
+  bridge I/O space.
+
+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in]   Width       Signifies the width of the memory operations.
+  @param[in]   Address     The base address of the I/O operation. The caller is
+                           responsible for aligning the Address if required.
+  @param[in]   Count       The number of I/O operations to perform. Bytes moved
+                           is Width size * Count, starting at Address.
+  @param[in]   Buffer      For read operations, the destination buffer to store
+                           the results. For write operations, the source buffer
+                           to write data from.
+
+  @retval EFI_SUCCESS              The data was read from or written to the PCI
+                                   root bridge.
+  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
+  @retval EFI_INVALID_PARAMETER    Buffer is NULL.
+  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a
+                                   lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoIoWrite (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                Address,
+  IN UINTN                                 Count,
+  IN VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+  Enables a PCI driver to copy one region of PCI root bridge memory space to
+  another region of PCI root bridge memory space.
+
+  The CopyMem() function enables a PCI driver to copy one region of PCI root
+  bridge memory space to another region of PCI root bridge memory space. This
+  is especially useful for video scroll operation on a memory mapped video
+  buffer.
+  The memory operations are carried out exactly as requested. The caller is
+  responsible for satisfying any alignment and memory width restrictions that a
+  PCI root bridge on a platform might require.
+
+  @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+                         instance.
+  @param[in] Width       Signifies the width of the memory operations.
+  @param[in] DestAddress The destination address of the memory operation. The
+                         caller is responsible for aligning the DestAddress if
+                         required.
+  @param[in] SrcAddress  The source address of the memory operation. The caller
+                         is responsible for aligning the SrcAddress if
+                         required.
+  @param[in] Count       The number of memory operations to perform. Bytes
+                         moved is Width size * Count, starting at DestAddress
+                         and SrcAddress.
+
+  @retval  EFI_SUCCESS             The data was copied from one memory region
+                                   to another memory region.
+  @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
+  @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a
+                                   lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoCopyMem (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN UINT64                                DestAddress,
+  IN UINT64                                SrcAddress,
+  IN UINTN                                 Count
+  )
+{
+  EFI_STATUS Status;
+  BOOLEAN    Direction;
+  UINTN      Stride;
+  UINTN      Index;
+  UINT64     Result;
+
+  if ((UINTN)Width > (UINTN)EfiPciWidthUint64) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (DestAddress == SrcAddress) {
+    return EFI_SUCCESS;
+  }
+
+  Stride = (UINTN)(1 << Width);
+
+  Direction = TRUE;
+  if ((DestAddress > SrcAddress) &&
+      (DestAddress < (SrcAddress + Count * Stride)))
+  {
+    Direction   = FALSE;
+    SrcAddress  = SrcAddress  + (Count - 1) * Stride;
+    DestAddress = DestAddress + (Count - 1) * Stride;
+  }
+
+  for (Index = 0; Index < Count; Index++) {
+
+    Status = RootBridgeIoMemRead (This, Width, SrcAddress, 1, &Result);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    Status = RootBridgeIoMemWrite (This, Width, DestAddress, 1, &Result);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+
+    if (Direction) {
+      SrcAddress  += Stride;
+      DestAddress += Stride;
+    } else {
+      SrcAddress  -= Stride;
+      DestAddress -= Stride;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Allows read from PCI configuration space.
+
+  @param This     A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  @param Width    Signifies the width of the memory operation.
+  @param Address  The address within the PCI configuration space
+                  for the PCI controller.
+  @param Count    The number of PCI configuration operations
+                  to perform.
+  @param Buffer   The destination buffer to store the results.
+
+  @retval EFI_SUCCESS           The data was read from the PCI root bridge.
+  @retval EFI_INVALID_PARAMETER Invalid parameters found.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciRead (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN  UINT64                                Address,
+  IN  UINTN                                 Count,
+  OUT VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
+}
+
+/**
+  Allows write to PCI configuration space.
+
+  @param This     A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
+  @param Width    Signifies the width of the memory operation.
+  @param Address  The address within the PCI configuration space
+                  for the PCI controller.
+  @param Count    The number of PCI configuration operations
+                  to perform.
+  @param Buffer   The source buffer to get the results.
+
+  @retval EFI_SUCCESS            The data was written to the PCI root bridge.
+  @retval EFI_INVALID_PARAMETER  Invalid parameters found.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoPciWrite (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+  IN     UINT64                                Address,
+  IN     UINTN                                 Count,
+  IN OUT VOID                                  *Buffer
+  )
+{
+  return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
+}
+
+/**
+  Provides the PCI controller-specific address needed to access
+  system memory for DMA.
+
+  @param This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param Operation      Indicate if the bus master is going to read or write
+                        to system memory.
+  @param HostAddress    The system memory address to map on the PCI controller.
+  @param NumberOfBytes  On input the number of bytes to map.
+                        On output the number of bytes that were mapped.
+  @param DeviceAddress  The resulting map address for the bus master PCI
+                        controller to use to access the system memory's HostAddress.
+  @param Mapping        The value to pass to Unmap() when the bus master DMA
+                        operation is complete.
+
+  @retval EFI_SUCCESS            Success.
+  @retval EFI_INVALID_PARAMETER  Invalid parameters found.
+  @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
+  @retval EFI_DEVICE_ERROR       The System hardware could not map the requested address.
+  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to lack of resources.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoMap (
+  IN      EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
+  IN      EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+  IN      VOID                                      *HostAddress,
+  IN  OUT UINTN                                     *NumberOfBytes,
+  OUT     EFI_PHYSICAL_ADDRESS                      *DeviceAddress,
+  OUT     VOID                                      **Mapping
+  )
+{
+  EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+  if (HostAddress == NULL || NumberOfBytes == NULL ||
+      DeviceAddress == NULL || Mapping == NULL)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the return values to their defaults
+  //
+  *Mapping = NULL;
+
+  //
+  // Make sure that Operation is valid
+  //
+  if ((UINT32)Operation >= EfiPciOperationMaximum) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
+  //
+  // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
+  //
+  *DeviceAddress = PhysicalAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Completes the Map() operation and releases any corresponding resources.
+
+  The Unmap() function completes the Map() operation and releases any
+  corresponding resources.
+  If the operation was an EfiPciOperationBusMasterWrite or
+  EfiPciOperationBusMasterWrite64, the data is committed to the target system
+  memory.
+  Any resources used for the mapping are freed.
+
+  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[in] Mapping   The mapping value returned from Map().
+
+  @retval EFI_SUCCESS            The range was unmapped.
+  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
+  @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoUnmap (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN VOID                            *Mapping
+  )
+{
+  MAP_INFO *MapInfo;
+
+  //
+  // See if the Map() operation associated with this Unmap() required a mapping buffer.
+  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
+  //
+  if (Mapping != NULL) {
+    //
+    // Get the MAP_INFO structure from Mapping
+    //
+    MapInfo = (MAP_INFO *)Mapping;
+
+    //
+    // If this is a write operation from the Bus Master's point of view,
+    // then copy the contents of the mapped buffer into the real buffer
+    // so the processor can read the contents of the real buffer.
+    //
+    if (MapInfo->Operation == EfiPciOperationBusMasterWrite ||
+        MapInfo->Operation == EfiPciOperationBusMasterWrite64)
+    {
+      CopyMem (
+        (VOID *)(UINTN)MapInfo->HostAddress,
+        (VOID *)(UINTN)MapInfo->MappedHostAddress,
+        MapInfo->NumberOfBytes
+        );
+    }
+
+    //
+    // Free the mapped buffer and the MAP_INFO structure.
+    //
+    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
+    gBS->FreePool (Mapping);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer
+  or EfiPciOperationBusMasterCommonBuffer64 mapping.
+
+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param Type        This parameter is not used and must be ignored.
+  @param MemoryType  The type of memory to allocate, EfiBootServicesData or
+                     EfiRuntimeServicesData.
+  @param Pages       The number of pages to allocate.
+  @param HostAddress A pointer to store the base system memory address of the
+                     allocated range.
+  @param Attributes  The requested bit mask of attributes for the allocated
+                     range. Only the attributes
+                     EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,
+                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and
+                     EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this
+                     function.
+
+  @retval EFI_SUCCESS            The requested memory pages were allocated.
+  @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
+  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
+  @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal
+                                 attribute bits are MEMORY_WRITE_COMBINE,
+                                 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
+  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoAllocateBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN  EFI_ALLOCATE_TYPE               Type,
+  IN  EFI_MEMORY_TYPE                 MemoryType,
+  IN  UINTN                           Pages,
+  OUT VOID                            **HostAddress,
+  IN  UINT64                          Attributes
+  )
+{
+  EFI_STATUS           Status;
+  EFI_PHYSICAL_ADDRESS PhysicalAddress;
+
+  //
+  // Validate Attributes
+  //
+  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //
+  // Check for invalid inputs
+  //
+  if (HostAddress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+  //
+  if (MemoryType != EfiBootServicesData &&
+      MemoryType != EfiRuntimeServicesData)
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xFFFFFFFFFFFFFFFFULL);
+
+  Status = gBS->AllocatePages (
+                  AllocateMaxAddress,
+                  MemoryType,
+                  Pages,
+                  &PhysicalAddress
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  *HostAddress = (VOID *)(UINTN)PhysicalAddress;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Frees memory that was allocated with AllocateBuffer().
+
+  The FreeBuffer() function frees memory that was allocated with
+  AllocateBuffer().
+
+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param Pages       The number of pages to free.
+  @param HostAddress The base system memory address of the allocated range.
+
+  @retval EFI_SUCCESS            The requested memory pages were freed.
+  @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and
+                                 Pages was not allocated with AllocateBuffer().
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFreeBuffer (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN  UINTN                           Pages,
+  OUT VOID                            *HostAddress
+  )
+{
+  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages);
+}
+
+/**
+  Flushes all PCI posted write transactions from a PCI host bridge to system
+  memory.
+
+  The Flush() function flushes any PCI posted write transactions from a PCI
+  host bridge to system memory. Posted write transactions are generated by PCI
+  bus masters when they perform write transactions to target addresses in
+  system memory.
+  This function does not flush posted write transactions from any PCI bridges.
+  A PCI controller specific action must be taken to guarantee that the posted
+  write transactions have been flushed from the PCI controller and from all the
+  PCI bridges into the PCI host bridge. This is typically done with a PCI read
+  transaction from the PCI controller prior to calling Flush().
+
+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+
+  @retval EFI_SUCCESS        The PCI posted write transactions were flushed
+                             from the PCI host bridge to system memory.
+  @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed
+                             from the PCI host bridge due to a hardware error.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoFlush (
+  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+/**
+  Gets the attributes that a PCI root bridge supports setting with
+  SetAttributes(), and the attributes that a PCI root bridge is currently
+  using.
+
+  The GetAttributes() function returns the mask of attributes that this PCI
+  root bridge supports and the mask of attributes that the PCI root bridge is
+  currently using.
+
+  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param Supported   A pointer to the mask of attributes that this PCI root
+                     bridge supports setting with SetAttributes().
+  @param Attributes  A pointer to the mask of attributes that this PCI root
+                     bridge is currently using.
+
+  @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes
+                                 that the PCI root bridge supports is returned
+                                 in Supports. If Attributes is not NULL, then
+                                 the attributes that the PCI root bridge is
+                                 currently using is returned in Attributes.
+  @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoGetAttributes (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  OUT UINT64                          *Supported,
+  OUT UINT64                          *Attributes
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
+
+  if (Attributes == NULL && Supported == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Set the return value for Supported and Attributes
+  //
+  if (Supported != NULL) {
+    *Supported  = RootBridgeInstance->RootBridge.Supports;
+  }
+
+  if (Attributes != NULL) {
+    *Attributes = RootBridgeInstance->RootBridge.Attributes;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Sets attributes for a resource range on a PCI root bridge.
+
+  The SetAttributes() function sets the attributes specified in Attributes for
+  the PCI root bridge on the resource range specified by ResourceBase and
+  ResourceLength. Since the granularity of setting these attributes may vary
+  from resource type to resource type, and from platform to platform, the
+  actual resource range and the one passed in by the caller may differ. As a
+  result, this function may set the attributes specified by Attributes on a
+  larger resource range than the caller requested. The actual range is returned
+  in ResourceBase and ResourceLength. The caller is responsible for verifying
+  that the actual range for which the attributes were set is acceptable.
+
+  @param This            A pointer to the
+                         EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param Attributes      The mask of attributes to set. If the
+                         attribute bit MEMORY_WRITE_COMBINE,
+                         MEMORY_CACHED, or MEMORY_DISABLE is set,
+                         then the resource range is specified by
+                         ResourceBase and ResourceLength. If
+                         MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
+                         MEMORY_DISABLE are not set, then
+                         ResourceBase and ResourceLength are ignored,
+                         and may be NULL.
+  @param ResourceBase    A pointer to the base address of the
+                         resource range to be modified by the
+                         attributes specified by Attributes.
+  @param ResourceLength  A pointer to the length of the resource
+                                   range to be modified by the attributes
+                                   specified by Attributes.
+
+  @retval  EFI_SUCCESS           The current configuration of this PCI root bridge
+                                 was returned in Resources.
+  @retval  EFI_UNSUPPORTED       The current configuration of this PCI root bridge
+                                 could not be retrieved.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoSetAttributes (
+  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  IN     UINT64                          Attributes,
+  IN OUT UINT64                          *ResourceBase,
+  IN OUT UINT64                          *ResourceLength
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
+
+  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
+
+  // Then check optional parameters if eligible
+  if ((Attributes & (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |
+                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED |
+                     EFI_PCI_ATTRIBUTE_MEMORY_DISABLE)) != 0)
+  {
+    if (ResourceBase == NULL || ResourceLength == NULL) {
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+
+  if (Attributes != 0) {
+    if ((Attributes & (~(RootBridgeInstance->RootBridge.Supports))) != 0) {
+      return EFI_UNSUPPORTED;
+    }
+  }
+
+  //
+  // This is a generic driver for a PC-AT class system.  It does not have any
+  // chipset specific knowlegde, so none of the attributes can be set or
+  // cleared.  Any attempt to set attribute that are already set will succeed,
+  // and any attempt to set an attribute that is not supported will fail.
+  //
+  if (Attributes & (~RootBridgeInstance->RootBridge.Attributes)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Retrieves the current resource settings of this PCI root bridge in the form
+  of a set of ACPI resource descriptors.
+
+  There are only two resource descriptor types from the ACPI Specification that
+  may be used to describe the current resources allocated to a PCI root bridge.
+  These are the QWORD Address Space Descriptor, and the End Tag. The QWORD
+  Address Space Descriptor can describe memory, I/O, and bus number ranges for
+  dynamic or fixed resources. The configuration of a PCI root bridge is described
+  with one or more QWORD Address Space Descriptors followed by an End Tag.
+
+  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+  @param[out]  Resources   A pointer to the resource descriptors that
+                           describe the current configuration of this PCI root
+                           bridge. The storage for the resource
+                           descriptors is allocated by this function. The
+                           caller must treat the return buffer as read-only
+                           data, and the buffer must not be freed by the
+                          caller.
+
+  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge
+                           was returned in Resources.
+  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge
+                           could not be retrieved.
+**/
+EFI_STATUS
+EFIAPI
+RootBridgeIoConfiguration (
+  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+  OUT VOID                            **Resources
+  )
+{
+  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance;
+  PCI_RES_NODE                      *ResAllocNode;
+  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
+  EFI_ACPI_END_TAG_DESCRIPTOR       *End;
+  UINTN                             Index;
+
+  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
+  ZeroMem (
+    RootBridgeInstance->ConfigBuffer,
+    TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
+    );
+
+  Descriptor = RootBridgeInstance->ConfigBuffer;
+  for (Index = TypeIo; Index < TypeMax; Index++) {
+
+    ResAllocNode = &RootBridgeInstance->ResAllocNode[Index];
+
+    if (ResAllocNode->Status != ResAllocated) {
+      continue;
+    }
+
+    switch (ResAllocNode->Type) {
+
+    case TypeBus:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_BUS;
+      break;
+
+    case TypeIo:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_IO;
+      Descriptor->AddrSpaceGranularity = 32;
+      break;
+
+    case TypeMem32:
+    case TypePMem32:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Descriptor->SpecificFlag         = (Index == TypeMem32) ? 0 :
+                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
+      Descriptor->AddrSpaceGranularity = 32;
+      break;
+
+    case TypeMem64:
+    case TypePMem64:
+      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
+      Descriptor->SpecificFlag         = (Index == TypeMem64) ? 0 :
+                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
+      Descriptor->AddrSpaceGranularity = 64;
+      break;
+
+    default:
+      continue;
+    }
+
+    Descriptor->Desc          = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+    Descriptor->Len           = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
+    Descriptor->AddrRangeMin  = ResAllocNode->Base;
+    Descriptor->AddrRangeMax  = ResAllocNode->Base + ResAllocNode->Length - 1;
+    Descriptor->AddrLen       = ResAllocNode->Length;
+
+    Descriptor++;
+  }
+
+  //
+  // Terminate the entries.
+  //
+  End = (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor;
+  End->Desc     = ACPI_END_TAG_DESCRIPTOR;
+  End->Checksum = 0x0;
+
+  *Resources = RootBridgeInstance->ConfigBuffer;
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (16 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 22:51   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
                   ` (16 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This change also enables the support for SCSI, NVMe, USB keyboard, and
USB storage devices.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 34 ++++++++++++++++++++
 Platform/Ampere/JadePkg/Jade.dsc                     |  5 +++
 Platform/Ampere/JadePkg/Jade.fdf                     | 33 +++++++++++++++++++
 3 files changed, 72 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index fc8e0b40ee19..33f5fe7af544 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -83,6 +83,7 @@ [LibraryClasses.common]
   NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
   MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
   SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
+  PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf
   PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
   AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
   TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
@@ -648,6 +649,39 @@ [Components.common]
   MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
   FatPkg/EnhancedFatDxe/Fat.inf
 
+  #
+  # SCSI Bus and Disk Driver
+  #
+  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  #
+  # SATA Support
+  #
+  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+  MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+  #
+  # NVME Support
+  #
+  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # USB Support
+  #
+  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # PCIe Support
+  #
+  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
   #
   # Bds
   #
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 0f9d0adbd34e..576e1c3ab663 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -88,6 +88,11 @@ [LibraryClasses]
   AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
   AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
 
+  #
+  # Pcie Board
+  #
+  PcieBoardLib|Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
+
 ################################################################################
 #
 # Specific Platform Pcds
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 2c6f9fac76fd..fc47556b072b 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -266,6 +266,39 @@ [FV.FvMain]
   INF FatPkg/EnhancedFatDxe/Fat.inf
   INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
 
+  #
+  # SCSI Bus and Disk Driver
+  #
+  INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
+  INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
+
+  #
+  # SATA Support
+  #
+  INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
+  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
+  INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
+  INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
+
+  #
+  # NVME Support
+  #
+  INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
+
+  #
+  # USB Support
+  #
+  INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
+  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
+
+  #
+  # PCIe Support
+  #
+  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
   #
   # UEFI application (Shell Embedded Boot Loader)
   #
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (17 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 22:51   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
                   ` (15 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

This wires up the pre-built binary placed in the edk2-non-osi
repository for PCIe VGA Controller support.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Platform/Ampere/JadePkg/Jade.dsc | 12 ++++++++++++
 Platform/Ampere/JadePkg/Jade.fdf |  5 +++++
 2 files changed, 17 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 576e1c3ab663..6aaa644ad298 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -115,6 +115,13 @@ [PcdsFixedAtBuild.common]
 !endif
 
 
+[PcdsPatchableInModule]
+  #
+  # Console Resolution (HD mode)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|768
+
 ################################################################################
 #
 # Specific Platform Component
@@ -136,3 +143,8 @@ [Components.common]
   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
   Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
+
+  #
+  # VGA Aspeed
+  #
+  Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index fc47556b072b..6820a197568b 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -299,6 +299,11 @@ [FV.FvMain]
   INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
 
+  #
+  # VGA Aspeed
+  #
+  INF Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
+
   #
   # UEFI application (Shell Embedded Boot Loader)
   #
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (18 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-08 11:13   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
                   ` (14 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This change is to produce RNG protocol which is required by several
modules.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc         |   5 +
 Platform/Ampere/JadePkg/Jade.fdf                             |   5 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf      |  43 +++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c        | 164 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni      |  10 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni |   9 ++
 6 files changed, 236 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 33f5fe7af544..930bbb5d385b 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -682,6 +682,11 @@ [Components.common]
   MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
 
+  #
+  # Random Number Generator Support
+  #
+  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
+
   #
   # Bds
   #
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 6820a197568b..ef24e6f1f8e0 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -304,6 +304,11 @@ [FV.FvMain]
   #
   INF Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
 
+  #
+  # Random Number Generator Support
+  #
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
+
   #
   # UEFI application (Shell Embedded Boot Loader)
   #
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
new file mode 100644
index 000000000000..d3d2c20436a0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
@@ -0,0 +1,43 @@
+## @file
+#
+# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = RngDxe
+  FILE_GUID                      = 4FCC006E-C740-4027-BC97-787907C8D286
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = RngDriverEntry
+  MODULE_UNI_FILE                = RngDxe.uni
+
+[Sources.common]
+  RngDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  TrngLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gEfiRngAlgorithmRaw                 ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
+
+[Protocols]
+  gEfiRngProtocolGuid                ## PRODUCES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  RngDxeExtra.uni
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
new file mode 100644
index 000000000000..bb8140cfeb2f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
@@ -0,0 +1,164 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TrngLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/Rng.h>
+
+/**
+  Returns information about the random number generation implementation.
+
+  @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
+                                      On output with a return code of EFI_SUCCESS, the size
+                                      in bytes of the data returned in RNGAlgorithmList. On output
+                                      with a return code of EFI_BUFFER_TOO_SMALL,
+                                      the size of RNGAlgorithmList required to obtain the list.
+  @param[out] RNGAlgorithmList        A caller-allocated memory buffer filled by the driver
+                                      with one EFI_RNG_ALGORITHM element for each supported
+                                      RNG algorithm. The list must not change across multiple
+                                      calls to the same driver. The first algorithm in the list
+                                      is the default algorithm for the driver.
+
+  @retval EFI_SUCCESS                 The RNG algorithm list was returned successfully.
+  @retval EFI_INVALID_PARAMETER       One or more of the parameters are incorrect.
+  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too small to hold the result.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetInfo (
+  IN     EFI_RNG_PROTOCOL  *This,
+  IN OUT UINTN             *RNGAlgorithmListSize,
+  OUT    EFI_RNG_ALGORITHM *RNGAlgorithmList
+  )
+{
+  if (This == NULL || RNGAlgorithmListSize == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
+    *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  if (RNGAlgorithmList == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
+  CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Produces and returns an RNG value using either the default or specified RNG algorithm.
+
+  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
+  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
+                                      algorithm to use. May be NULL in which case the function will
+                                      use its default RNG algorithm.
+  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
+                                      RNGValue. The driver shall return exactly this numbers of bytes.
+  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
+                                      resulting RNG value.
+
+  @retval EFI_SUCCESS                 The RNG value was returned successfully.
+  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
+                                      this driver.
+  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
+                                      firmware error.
+  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
+
+**/
+EFI_STATUS
+EFIAPI
+RngGetRNG (
+  IN  EFI_RNG_PROTOCOL  *This,
+  IN  EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
+  IN  UINTN             RNGValueLength,
+  OUT UINT8             *RNGValue
+  )
+{
+  EFI_STATUS Status;
+
+  if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // We only support the raw algorithm, so reject requests for anything else
+  //
+  if (RNGAlgorithm != NULL &&
+      !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw))
+  {
+    return EFI_UNSUPPORTED;
+  }
+
+  Status = GenerateRandomNumbers (RNGValue, RNGValueLength);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a:%d Failed to generate a random number. \n",
+      __FUNCTION__,
+      __LINE__
+      ));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/*
+ * The Random Number Generator (RNG) protocol
+ */
+EFI_RNG_PROTOCOL mRng = {
+  RngGetInfo,
+  RngGetRNG
+};
+
+/**
+  The user Entry Point for the Random Number Generator (RNG) driver.
+
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
+  @param[in] SystemTable    A pointer to the EFI System Table.
+
+  @retval EFI_SUCCESS       The entry point is executed successfully.
+  @retval EFI_NOT_SUPPORTED Platform does not support RNG.
+  @retval Other             Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+RngDriverEntry (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_HANDLE Handle;
+
+  //
+  // Install UEFI RNG (Random Number Generator) Protocol
+  //
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiRngProtocolGuid,
+                  &mRng,
+                  NULL
+                  );
+
+  return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
new file mode 100644
index 000000000000..cd9dde97a236
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
@@ -0,0 +1,10 @@
+//
+// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+
+#string STR_MODULE_ABSTRACT             #language en-US "Produces UEFI Random Number Generator protocol"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This module will produce UEFI Random Number Generator protocol."
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
new file mode 100644
index 000000000000..9a3696b25442
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Ampere UEFI Random Number Generator DXE"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (19 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:00   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
                   ` (13 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Quan Nguyen <quan@os.amperecomputing.com>

This supports various SMBIOS tables type 0, 1, 2, 3, 4, 7, 8, 9, 11,
13, 16, 17, 19, 24 and 32.

SMBIOS Type 1, 2 and 3 are hardcoded as Host-BMC communication is not
supported yet. And, this module does not support fixup tables to reflect
changes of the system at booting time.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                    |   12 +
 Platform/Ampere/JadePkg/Jade.dsc                                        |   26 +
 Platform/Ampere/JadePkg/Jade.fdf                                        |    8 +
 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf           |   45 +
 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf   |   45 +
 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   52 +
 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c             |  709 +++++++++++++
 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c     |  705 +++++++++++++
 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c   | 1049 ++++++++++++++++++++
 9 files changed, 2651 insertions(+)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
index 0ac075047276..368136b5342f 100755
--- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
@@ -63,11 +63,23 @@ [PcdsFixedAtBuild]
   gAmpereTokenSpaceGuid.PcdSmproNsMailboxIndex|0x1|UINT32|0x00000003
   gAmpereTokenSpaceGuid.PcdPmproDbBaseReg|0x100001540000|UINT64|0x00000004
 
+  #
+  # SMBIOS Type 1 Pcd
+  #
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|0|UINT8|0x00000005
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|0|UINT8|0x00000006
+
 [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
   #
   # Firmware Volume Pcds
   #
   gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
 
+  #
+  # SMBIOS, default or template values
+  #
+  # SMBIOS Type 0 - BIOS Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"|VOID*|0xB0000002 # Must follow this MM/DD/YYYY SMBIOS date format
+
   # NVRam Pcds
   gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 6aaa644ad298..9c7d7cad4915 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -104,7 +104,22 @@ [PcdsFeatureFlag.common]
   #
   gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
 
+[PcdsFixedAtBuild]
+!ifdef $(FIRMWARE_VER)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
+!endif
+
 [PcdsFixedAtBuild.common]
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|$(MAJOR_VER)
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|$(MINOR_VER)
+
+  # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
+  # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
+  # presence of the 32-bit entry point anyway (because many AARCH64 systems
+  # don't have 32-bit addressable physical RAM), and the additional allocations
+  # below 4 GB needlessly fragment the memory map. So expose the 64-bit entry
+  # point only, for entry point versions >= 3.0.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
 
 !if $(SECURE_BOOT_ENABLE) == TRUE
   # Override the default values from SecurityPkg to ensure images
@@ -114,6 +129,9 @@ [PcdsFixedAtBuild.common]
   gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
 !endif
 
+[PcdsDynamicDefault.common.DEFAULT]
+  # SMBIOS Type 0 - BIOS Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
 
 [PcdsPatchableInModule]
   #
@@ -148,3 +166,11 @@ [Components.common]
   # VGA Aspeed
   #
   Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index ef24e6f1f8e0..3d5d857178b3 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -340,4 +340,12 @@ [FV.FvMain]
   INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
   INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
 
+  #
+  # SMBIOS
+  #
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
+
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
new file mode 100644
index 000000000000..f723ad612a52
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosCpuDxe
+  FILE_GUID                      = 4DD7C2E4-E6A6-11EA-8736-D3C56ABBB5C4
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosCpuDxeEntry
+
+[Sources]
+  SmbiosCpuDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
new file mode 100644
index 000000000000..87b9123df856
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
@@ -0,0 +1,45 @@
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosMemInfoDxe
+  FILE_GUID                      = ECF38190-EBF8-11EA-B646-830715BDF83A
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosMemInfoDxeEntry
+
+[Sources]
+  SmbiosMemInfoDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  ArmLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
new file mode 100755
index 000000000000..73a601b0df08
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
@@ -0,0 +1,52 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = SmbiosPlatformDxe
+  FILE_GUID                      = F0CC7D0B-CD83-4DDA-A5D4-613AB02D4E52
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = SmbiosPlatformDxeEntry
+
+[Sources]
+  SmbiosPlatformDxe.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  HobLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Protocols]
+  gEfiSmbiosProtocolGuid                     ## CONSUMED
+
+[Pcd]
+  # Type 0
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion
+  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion
+
+  gArmTokenSpaceGuid.PcdFdSize
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  gEfiSmbiosProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
new file mode 100644
index 000000000000..659212a2cc90
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
@@ -0,0 +1,709 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Guid/SmBios.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmLib.h>
+#include <Library/ArmLib/ArmLibPrivate.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/Smbios.h>
+
+#define CPU_CACHE_LEVEL_MAX 3
+
+#define MHZ_SCALE_FACTOR 1000000
+
+#define CACHE_SIZE(x)   (UINT16) (0x8000 | (x) >> 16)
+#define CACHE_SIZE_2(x) (0x80000000 | (x) >> 16)
+
+#define TYPE4_ADDITIONAL_STRINGS                                  \
+  "SOCKET 0\0"                       /* socket type */            \
+  "Ampere(R)\0"                      /* manufacturer */           \
+  "Ampere(R) Altra(R) Processor\0"   /* processor description */  \
+  "NotSet\0"                         /* part number */
+
+#define TYPE7_ADDITIONAL_STRINGS                                  \
+  "L1 Cache\0" /* L1 Cache  */
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE4 Base;
+  CHAR8              Strings[sizeof (TYPE4_ADDITIONAL_STRINGS)];
+} ARM_TYPE4;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE7 Base;
+  CHAR8              Strings[sizeof (TYPE7_ADDITIONAL_STRINGS)];
+} ARM_TYPE7;
+
+#pragma pack()
+//-------------------------------------
+//        SMBIOS Platform Common
+//-------------------------------------
+enum {
+  ADDITIONAL_STR_INDEX_1 = 1,
+  ADDITIONAL_STR_INDEX_2,
+  ADDITIONAL_STR_INDEX_3,
+  ADDITIONAL_STR_INDEX_4,
+  ADDITIONAL_STR_INDEX_5,
+  ADDITIONAL_STR_INDEX_6,
+  ADDITIONAL_STR_INDEX_7,
+  ADDITIONAL_STR_INDEX_8,
+  ADDITIONAL_STR_INDEX_9,
+  ADDITIONAL_STR_INDEX_MAX
+};
+
+// Type 4 Processor Socket 0
+STATIC ARM_TYPE4 mArmDefaultType4Sk0 = {
+  {
+    {                                        // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,          // socket type
+    3,                               // processor type CPU
+    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
+    ADDITIONAL_STR_INDEX_2,          // manufacturer
+    {{0,},{0.}},                     // processor id
+    ADDITIONAL_STR_INDEX_3,          // version
+    {0,0,0,0,0,1},                   // voltage
+    0,                               // external clock
+    3000,                            // max speed
+    3000,                            // current speed
+    0x41,                            // status
+    ProcessorUpgradeOther,
+    0xFFFF,                 // l1 cache handle
+    0xFFFF,                 // l2 cache handle
+    0xFFFF,                 // l3 cache handle
+    0,                      // serial not set
+    0,                      // asset not set
+    ADDITIONAL_STR_INDEX_4, // part number
+    80,                     // core count in socket
+    80,                     // enabled core count in socket
+    0,                      // threads per socket
+    0xEC,                   // processor characteristics
+    ProcessorFamilyARMv8,   // ARM core
+  },
+  TYPE4_ADDITIONAL_STRINGS
+};
+
+// Type 4 Processor Socket 1
+STATIC ARM_TYPE4 mArmDefaultType4Sk1 = {
+  {
+    {                                        // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,          // socket type
+    3,                               // processor type CPU
+    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
+    ADDITIONAL_STR_INDEX_2,          // manufacturer
+    {{0,},{0.}},                     // processor id
+    ADDITIONAL_STR_INDEX_3,          // version
+    {0,0,0,0,0,1},                   // voltage
+    0,                               // external clock
+    3000,                            // max speed
+    3000,                            // current speed
+    0x41,                            // status
+    ProcessorUpgradeOther,
+    0xFFFF,                 // l1 cache handle
+    0xFFFF,                 // l2 cache handle
+    0xFFFF,                 // l3 cache handle
+    0,                      // serial not set
+    0,                      // asset not set
+    ADDITIONAL_STR_INDEX_4, // part number
+    80,                     // core count in socket
+    80,                     // enabled core count in socket
+    0,                      // threads per socket
+    0xEC,                   // processor characteristics
+    ProcessorFamilyARMv8,   // ARM core
+  },
+  TYPE4_ADDITIONAL_STRINGS
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L1 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x180,                  // L1 enabled, Write Back
+    0x8001,                 // 64k i cache max
+    0x8001,                 // 64k installed
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    0,                      // unkown speed
+    CacheErrorParity,       // parity checking
+    CacheTypeUnified,       // Unified cache
+    CacheAssociativity4Way, // 4-way
+  },
+  "L1 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L2 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x181,                  // L2 enabled, Write Back
+    0x8010,                 // 1M cache max
+    0x8010,                 // 1M installed
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    0,                      // unkown speed
+    CacheErrorSingleBit,    // single bit ECC
+    CacheTypeUnified,       // Unified cache
+    CacheAssociativity8Way, // 8-way
+  },
+  "L2 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk0L3 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x182,                   // L3 enabled, Write Back
+    0x8200,                  // 32M cache max
+    0x8200,                  // 32M installed
+    {0, 0, 0, 0, 0, 1},      // SRAM type
+    {0, 0, 0, 0, 0, 1},      // SRAM type
+    0,                       // unkown speed
+    CacheErrorParity,        // parity checking
+    CacheTypeUnified,        // Unified cache
+    CacheAssociativity16Way, // 16-way
+  },
+  "L3 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L1 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x180,                  // L1 enabled, Write Back
+    0x8001,                 // 64k i cache max
+    0x8001,                 // 64k installed
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    0,                      // unkown speed
+    CacheErrorParity,       // parity checking
+    CacheTypeUnified,       // Unified cache
+    CacheAssociativity4Way, // 4-way
+  },
+  "L1 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L2 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x181,                  // L2 enabled, Write Back
+    0x8010,                 // 1M cache max
+    0x8010,                 // 1M installed
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    {0, 0, 0, 0, 0, 1},     // SRAM type
+    0,                      // unkown speed
+    CacheErrorSingleBit,    // single bit ECC
+    CacheTypeUnified,       // Unified cache
+    CacheAssociativity8Way, // 8-way
+  },
+  "L2 Cache\0"
+};
+
+// Type 7 Cache Information
+STATIC ARM_TYPE7 mArmDefaultType7Sk1L3 = {
+  {
+    {                                    // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    0x182,                   // L3 enabled, Write Back
+    0x8200,                  // 32M cache max
+    0x8200,                  // 32M installed
+    {0, 0, 0, 0, 0, 1},      // SRAM type
+    {0, 0, 0, 0, 0, 1},      // SRAM type
+    0,                       // unkown speed
+    CacheErrorParity,        // parity checking
+    CacheTypeUnified,        // Unified cache
+    CacheAssociativity16Way, // 16-way
+  },
+  "L3 Cache\0"
+};
+
+STATIC CONST VOID *DefaultCommonTables[] =
+{
+  &mArmDefaultType4Sk0,
+  &mArmDefaultType4Sk1,
+  NULL
+};
+
+STATIC CONST VOID *DefaultType7Sk0Tables[] =
+{
+  &mArmDefaultType7Sk0L1,
+  &mArmDefaultType7Sk0L2,
+  &mArmDefaultType7Sk0L3,
+  NULL
+};
+
+STATIC CONST VOID *DefaultType7Sk1Tables[] =
+{
+  &mArmDefaultType7Sk1L1,
+  &mArmDefaultType7Sk1L2,
+  &mArmDefaultType7Sk1L3,
+  NULL
+};
+
+STATIC
+UINT32
+GetCacheConfig (
+  UINT32 Level
+  )
+{
+  UINT64  Val;
+  BOOLEAN SupportWB;
+  BOOLEAN SupportWT;
+
+  Val = ReadCCSIDR (Level);
+  SupportWT = (Val & (1 << 31)) ? TRUE : FALSE;
+  SupportWB = (Val & (1 << 30)) ? TRUE : FALSE;
+  if (SupportWT && SupportWB) {
+    return 2; /* Varies with Memory Address */
+  }
+
+  if (SupportWT) {
+    return 0;
+  }
+
+  return 1; /* WB */
+}
+
+STATIC
+UINTN
+GetStringPackSize (
+  CHAR8 *StringPack
+  )
+{
+  UINTN StrCount;
+  CHAR8 *StrStart;
+
+  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
+    return 0;
+  }
+
+  // String section ends in double-null (0000h)
+  for (StrCount = 0, StrStart = StringPack;
+       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
+  {
+  }
+
+  return StrCount + 2; // Included the double NULL
+}
+
+// Update String at String number to String Pack
+EFI_STATUS
+UpdateStringPack (
+  CHAR8 *StringPack,
+  CHAR8 *String,
+  UINTN StringNumber
+  )
+{
+  CHAR8 *StrStart;
+  UINTN StrIndex;
+  UINTN InputStrLen;
+  UINTN TargetStrLen;
+  UINTN BufferSize;
+  CHAR8 *Buffer;
+
+  StrStart = StringPack;
+  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
+    // A string ends in 00h
+    if (*StrStart == 0) {
+      StrIndex++;
+    }
+    // String section ends in double-null (0000h)
+    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (*StrStart == 0) {
+    StrStart++;
+  }
+
+  InputStrLen = AsciiStrLen (String);
+  TargetStrLen = AsciiStrLen (StrStart);
+  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
+
+  // Replace the String if length matched
+  // OR this is the last string
+  if (InputStrLen == TargetStrLen || (BufferSize == 0)) {
+    CopyMem (StrStart, String, InputStrLen);
+  }
+  // Otherwise, buffer is needed to apply new string
+  else {
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
+    CopyMem (StrStart, String, InputStrLen + 1);
+    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
+
+    FreePool (Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UpdateSmbiosType4 (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  UINTN              Index;
+  CHAR8              Str[40];
+  CHAR8              *StringPack;
+  SMBIOS_TABLE_TYPE4 *Table;
+
+  ASSERT (PlatformHob != NULL);
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    if (Index == 0) {
+      Table = &mArmDefaultType4Sk0.Base;
+      StringPack = mArmDefaultType4Sk0.Strings;
+    } else {
+      Table = &mArmDefaultType4Sk1.Base;
+      StringPack = mArmDefaultType4Sk1.Strings;
+    }
+
+    AsciiSPrint (Str, sizeof (Str), "CPU %d", Index);
+    UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_1);
+
+    Table->CoreCount = (UINT8)GetMaximumNumberOfCores ();
+    Table->ThreadCount = (UINT8)GetMaximumNumberOfCores ();
+    Table->EnabledCoreCount = (UINT8)GetNumberOfActiveCoresPerSocket (Index);
+
+    if (Table->EnabledCoreCount) {
+      Table->CurrentSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+      Table->ExternalClock = (UINT16)(PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
+      Table->MaxSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+      if (PlatformHob->TurboCapability[Index]) {
+        Table->MaxSpeed = (UINT16)(PlatformHob->TurboFrequency[Index]);
+      }
+    } else {
+      Table->CurrentSpeed = 0;
+      Table->ExternalClock = 0;
+      Table->MaxSpeed = 0;
+      Table->Status = 0;
+    }
+
+    *((UINT32 *)&Table->ProcessorId) = (UINT32)ArmReadMidr ();
+    *((UINT32 *)&Table->ProcessorId + 1) = 0;
+    *((UINT8 *)&Table->Voltage) = 0x80 | PlatformHob->CoreVoltage[Index] / 100;
+
+    /* Type 4 Part number */
+    if (Table->EnabledCoreCount) {
+      if ((PlatformHob->ScuProductId[Index] & 0xff) == 0x01) {
+        AsciiSPrint (
+          Str,
+          sizeof (Str),
+          "Q%02d-%02X",
+          PlatformHob->SkuMaxCore[Index],
+          PlatformHob->SkuMaxTurbo[Index]
+          );
+      } else {
+        AsciiSPrint (
+          Str,
+          sizeof (Str),
+          "M%02d%02X",
+          PlatformHob->SkuMaxCore[Index],
+          PlatformHob->SkuMaxTurbo[Index]
+          );
+      }
+
+      UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_4);
+    }
+  }
+}
+
+STATIC
+VOID
+UpdateSmbiosType7 (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  UINTN              Index;
+  SMBIOS_TABLE_TYPE7 *Table;
+
+  ASSERT (PlatformHob != NULL);
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L1.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L1.Base;
+    }
+
+    Table->Associativity = (UINT8)CpuGetAssociativity (1);
+    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (1) << 8); /* Enabled, Internal, L1 */
+    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (1));
+    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (1));
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (1));
+    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (1));
+
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L2.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L2.Base;
+    }
+
+    Table->Associativity = (UINT8)CpuGetAssociativity (2);
+    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (2) << 8 | 1); /* Enabled, Internal, L2 */
+    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (2));
+    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (2));
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (2));
+    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (2));
+
+    if (Index == 0) {
+      Table = &mArmDefaultType7Sk0L3.Base;
+    } else {
+      Table = &mArmDefaultType7Sk1L3.Base;
+    }
+
+    // CpuGetCacheSize() not return L3 size, set it to 32MB
+    Table->MaximumCacheSize  = CACHE_SIZE (32 << 20);
+    Table->InstalledSize     = CACHE_SIZE (32 << 20);
+    Table->MaximumCacheSize2 = CACHE_SIZE_2 (32 << 20);
+    Table->InstalledSize2    = CACHE_SIZE_2 (32 << 20);
+  }
+
+  if (GetNumberOfSupportedSockets () == 2 && GetNumberOfActiveCoresPerSocket (1) == 0) {
+    mArmDefaultType7Sk1L1.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L1.Base.InstalledSize2 = 0;
+    mArmDefaultType7Sk1L2.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L2.Base.InstalledSize2 = 0;
+    mArmDefaultType7Sk1L3.Base.InstalledSize = 0;
+    mArmDefaultType7Sk1L3.Base.InstalledSize2 = 0;
+  }
+
+}
+
+STATIC
+VOID
+UpdateSmbiosInfo (
+  VOID
+  )
+{
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  UpdateSmbiosType4 (PlatformHob);
+  UpdateSmbiosType7 (PlatformHob);
+}
+
+/**
+   Install SMBIOS Type 7 table
+
+   @param  Smbios               SMBIOS protocol.
+**/
+EFI_STATUS
+InstallType7Structures (
+  IN EFI_SMBIOS_PROTOCOL *Smbios
+  )
+{
+  EFI_STATUS         Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE  SmbiosHandle;
+  SMBIOS_TABLE_TYPE4 *Type4Table;
+  CONST VOID         **Tables;
+  UINTN              Index;
+  UINTN              Level;
+
+  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
+    if ( Index == 0) {
+      Tables = DefaultType7Sk0Tables;
+      Type4Table = &mArmDefaultType4Sk0.Base;
+    } else {
+      Tables = DefaultType7Sk1Tables;
+      Type4Table = &mArmDefaultType4Sk1.Base;
+    }
+
+    for (Level = 0; Level < CPU_CACHE_LEVEL_MAX; Level++ ) {
+      SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)Tables[Level])->Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER *)Tables[Level]
+                         );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((
+          DEBUG_ERROR,
+          "%a: adding SMBIOS type 7 Socket %d L%d cache failed\n",
+          __FUNCTION__,
+          Index,
+          Level + 1
+          ));
+        // stop adding rather than continuing
+        return Status;
+      }
+
+      // Save handle to Type 4
+      if (Level == 0) { // L1 cache
+        Type4Table->L1CacheHandle = SmbiosHandle;
+      } else if (Level == 1) { // L2 cache
+        Type4Table->L2CacheHandle = SmbiosHandle;
+      } else if (Level == 2) { // L3 cache
+        Type4Table->L3CacheHandle = SmbiosHandle;
+      }
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Install a whole table worth of structructures
+
+   @param  Smbios               SMBIOS protocol.
+   @param  DefaultTables        A pointer to the default SMBIOS table structure.
+**/
+EFI_STATUS
+InstallStructures (
+  IN       EFI_SMBIOS_PROTOCOL *Smbios,
+  IN CONST VOID                *DefaultTables[]
+  )
+{
+  EFI_STATUS        Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE SmbiosHandle;
+  UINTN             Index;
+
+  for (Index = 0; Index < GetNumberOfSupportedSockets () && DefaultTables[Index] != NULL; Index++) {
+    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index])->Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index]
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, Index));
+
+      // stop adding rather than continuing
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+   Install all structures from the DefaultTables structure
+
+   @param  Smbios               SMBIOS protocol
+
+**/
+EFI_STATUS
+InstallAllStructures (
+  IN EFI_SMBIOS_PROTOCOL *Smbios
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  UpdateSmbiosInfo ();
+
+  // Install Type 7 structures
+  InstallType7Structures (Smbios);
+
+  // Install Tables
+  Status = InstallStructures (Smbios, DefaultCommonTables);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbiosCpuDxeEntry (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS          Status;
+  EFI_SMBIOS_PROTOCOL *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **)&Smbios
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = InstallAllStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosCpu install: %r\n", Status));
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
new file mode 100644
index 000000000000..a262239b53ba
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
@@ -0,0 +1,705 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Guid/SmBios.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/Smbios.h>
+
+#define TYPE16_ADDITIONAL_STRINGS        \
+  "\0" /* no string*/
+
+#define TYPE17_ADDITIONAL_STRINGS        \
+  "Device Locator not set \0"  \
+  "Bank Locator not set \0"    \
+  "Manufacturer not set \0"    \
+  "Serial Number not set \0"   \
+  "Asset Tag not set \0"       \
+  "Part Number not set \0"     \
+
+#define TYPE19_ADDITIONAL_STRINGS        \
+  "\0" /* no string */
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE16 Base;
+  CHAR8               Strings[sizeof (TYPE16_ADDITIONAL_STRINGS)];
+} ARM_TYPE16;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE17 Base;
+  CHAR8               Strings[sizeof (TYPE17_ADDITIONAL_STRINGS)];
+} ARM_TYPE17;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE19 Base;
+  CHAR8               Strings[sizeof (TYPE19_ADDITIONAL_STRINGS)];
+} ARM_TYPE19;
+
+#pragma pack()
+// Type 16 Physical Memory Array
+STATIC ARM_TYPE16 mArmDefaultType16 = {
+  {
+    {                                        // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE16),          // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    MemoryArrayLocationSystemBoard,   // on motherboard
+    MemoryArrayUseSystemMemory,       // system RAM
+    MemoryErrorCorrectionMultiBitEcc, // ECC RAM
+    0x80000000,
+    0xFFFE,   // No error information structure
+    0x10,
+    0x40000000000ULL,
+  },
+  TYPE16_ADDITIONAL_STRINGS
+};
+
+// Type 17 Memory Device
+STATIC ARM_TYPE17 mArmDefaultType17 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_MEMORY_DEVICE,
+      sizeof (SMBIOS_TABLE_TYPE17),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    0xFFFF,                         // array to which this module belongs
+    0xFFFE,                         // no errors
+    72,                             // single DIMM with ECC
+    64,                             // data width of this device (64-bits)
+    0,                              // no module installed
+    0x09,                           // DIMM
+    1,                              // part of a set
+    1,                              // device locator
+    2,                              // bank locator
+    MemoryTypeDdr4,                 // DDR4
+    {},                             // type detail
+    0,                              // ? MHz
+    3,                              // manufacturer
+    4,                              // serial
+    5,                              // asset tag
+    6,                              // part number
+    0,                              // rank
+  },
+  TYPE17_ADDITIONAL_STRINGS
+};
+
+// Type 19 Memory Array Mapped Address
+STATIC ARM_TYPE19 mArmDefaultType19 = {
+  {
+    {  // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
+      sizeof (SMBIOS_TABLE_TYPE19),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    0xFFFFFFFF, // invalid, look at extended addr field
+    0xFFFFFFFF,
+    0xFFFF,    // handle
+    1,
+    0x0,
+    0x0,
+  },
+  TYPE19_ADDITIONAL_STRINGS
+};
+
+typedef struct _JEDEC_MF_ID {
+  UINT8 VendorId;
+  CHAR8 *ManufacturerString;
+} JEDEC_MF_ID;
+
+JEDEC_MF_ID Bank0Table[] = {
+  { 0x01, "AMD" },
+  { 0x04, "Fujitsu" },
+  { 0x07, "Hitachi" },
+  { 0x89, "Intel" },
+  { 0x10, "NEC" },
+  { 0x97, "Texas Instrument" },
+  { 0x98, "Toshiba" },
+  { 0x1c, "Mitsubishi" },
+  { 0x1f, "Atmel" },
+  { 0x20, "STMicroelectronics" },
+  { 0xa4, "IBM" },
+  { 0x2c, "Micron Technology" },
+  { 0xad, "SK Hynix" },
+  { 0xb0, "Sharp" },
+  { 0xb3, "IDT" },
+  { 0x3e, "Oracle" },
+  { 0xbf, "SST" },
+  { 0x40, "ProMos/Mosel" },
+  { 0xc1, "Infineon" },
+  { 0xc2, "Macronix" },
+  { 0x45, "SanDisk" },
+  { 0xce, "Samsung" },
+  { 0xda, "Winbond" },
+  { 0xe0, "LG Semi" },
+  { 0x62, "Sanyo" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank1Table[] = {
+  { 0x98, "Kingston" },
+  { 0xba, "PNY" },
+  { 0x4f, "Transcend" },
+  { 0x7a, "Apacer" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank2Table[] = {
+  { 0x9e, "Corsair" },
+  { 0xfe, "Elpida" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank3Table[] = {
+  { 0x0b, "Nanya" },
+  { 0x94, "Mushkin" },
+  { 0x25, "Kingmax" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank4Table[] = {
+  { 0xb0, "OCZ" },
+  { 0xcb, "A-DATA" },
+  { 0xcd, "G Skill" },
+  { 0xef, "Team" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank5Table[] = {
+  { 0x02, "Patriot" },
+  { 0x9b, "Crucial" },
+  { 0x51, "Qimonda" },
+  { 0x57, "AENEON" },
+  { 0xf7, "Avant" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank6Table[] = {
+  { 0x34, "Super Talent" },
+  { 0xd3, "Silicon Power" },
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID Bank7Table[] = {
+  { 0xff, "Undefined" }
+};
+
+JEDEC_MF_ID *ManufacturerJedecIdBankTable[] = {
+  Bank0Table,
+  Bank1Table,
+  Bank2Table,
+  Bank3Table,
+  Bank4Table,
+  Bank5Table,
+  Bank6Table,
+  Bank7Table
+};
+
+STATIC
+UINTN
+GetStringPackSize (
+  CHAR8 *StringPack
+  )
+{
+  UINTN StrCount;
+  CHAR8 *StrStart;
+
+  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
+    return 0;
+  }
+
+  // String section ends in double-null (0000h)
+  for (StrCount = 0, StrStart = StringPack;
+       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
+  {
+  }
+
+  return StrCount + 2; // Included the double NULL
+}
+
+// Update String at String number to String Pack
+EFI_STATUS
+UpdateStringPack (
+  CHAR8 *StringPack,
+  CHAR8 *String,
+  UINTN StringNumber
+  )
+{
+  CHAR8 *StrStart;
+  UINTN StrIndex;
+  UINTN InputStrLen;
+  UINTN TargetStrLen;
+  UINTN BufferSize;
+  CHAR8 *Buffer;
+
+  StrStart = StringPack;
+  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
+    // A string ends in 00h
+    if (*StrStart == 0) {
+      StrIndex++;
+    }
+    // String section ends in double-null (0000h)
+    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
+      return EFI_NOT_FOUND;
+    }
+  }
+
+  if (*StrStart == 0) {
+    StrStart++;
+  }
+
+  InputStrLen = AsciiStrLen (String);
+  TargetStrLen = AsciiStrLen (StrStart);
+  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
+
+  // Replace the String if length matched
+  // OR this is the last string
+  if ((InputStrLen == TargetStrLen) || (BufferSize == 0)) {
+    CopyMem (StrStart, String, InputStrLen);
+  }
+  // Otherwise, buffer is needed to apply new string
+  else {
+    Buffer = AllocateZeroPool (BufferSize);
+    if (Buffer == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+
+    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
+    CopyMem (StrStart, String, InputStrLen + 1);
+    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
+
+    FreePool (Buffer);
+  }
+
+  return EFI_SUCCESS;
+}
+
+UINT8
+GetMemoryType (
+  IN UINT8 *SpdData
+  )
+{
+  return (SpdData[2] == 0x08) ? 1 :    // DDR2
+         (SpdData[2] == 0x0B) ? 2 :    // DDR3
+         (SpdData[2] == 0x0C) ? 3 : 0; // DDR4
+}
+
+EFI_STATUS
+UpdateManufacturer (
+  IN VOID  *Table,
+  IN UINT8 *SpdData
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  UINTN       i;
+  UINT8       Data8;
+  UINT8       MemType;
+  JEDEC_MF_ID *IdTblPtr = NULL;
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    for (i = 0; i < 8; i++) {      // DDR2
+      Data8 = SpdData[64 + i];
+      if (Data8 != 0x7f) {
+        break;
+      }
+    }
+    break;
+
+  case 2:                    // DDR3
+    i = SpdData[117] & 0x7f; // Remove parity bit
+    Data8 = SpdData[118];
+    break;
+
+  case 3:                    // DDR4
+    i = SpdData[320] & 0x7f; // Remove parity bit
+    Data8 = SpdData[321];
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;  // Not supported
+  }
+
+  if (i > 7) {
+    i = 7;
+  }
+  IdTblPtr = ManufacturerJedecIdBankTable[i];
+
+  // Search in Manufacturer table
+  while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
+    IdTblPtr++;
+  }
+
+  if (IdTblPtr->VendorId != 0xff) {
+    Status = UpdateStringPack (
+               ((ARM_TYPE17 *)Table)->Strings,
+               IdTblPtr->ManufacturerString,
+               ((ARM_TYPE17 *)Table)->Base.Manufacturer
+               );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+UpdateSerialNumber (
+  IN VOID  *Table,
+  IN UINT8 *SpdData
+  )
+{
+  UINT8 MemType;
+  UINTN Offset;
+  CHAR8 Str[64];
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    Offset = 95;
+    break;
+
+  case 2:                          // DDR3
+    Offset = 122;
+    break;
+
+  case 3:                          // DDR4
+    Offset = 325;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;        // Not supported
+  }
+
+  AsciiSPrint (
+    Str,
+    sizeof (Str),
+    "%02X%02X%02X%02X",
+    SpdData[Offset],
+    SpdData[Offset + 1],
+    SpdData[Offset + 2],
+    SpdData[Offset + 3]
+    );
+
+  return UpdateStringPack (
+           ((ARM_TYPE17 *)Table)->Strings,
+           Str,
+           ((ARM_TYPE17 *)Table)->Base.SerialNumber
+           );
+}
+
+CHAR8
+Printable (
+  IN CHAR8 Character
+  )
+{
+  if((Character >= 0x20) && (Character <= 0x7E)) {
+    return Character;
+  }
+
+  return ' ';
+}
+
+EFI_STATUS
+UpdatePartNumber (
+  IN VOID  *Table,
+  IN UINT8 *SpdData
+  )
+{
+  UINT8 MemType;
+  UINTN Offset;
+  CHAR8 Str[64];
+
+  MemType = GetMemoryType (SpdData);
+
+  switch (MemType) {
+  case 1:
+    Offset = 73;
+    break;
+
+  case 2:                          // DDR3
+    Offset = 128;
+    break;
+
+  case 3:                          // DDR4
+    Offset = 329;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;        // Not supported
+  }
+
+  AsciiSPrint (
+    Str,
+    sizeof (Str),
+    "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+    Printable (SpdData[Offset]),
+    Printable (SpdData[Offset + 1]),
+    Printable (SpdData[Offset + 2]),
+    Printable (SpdData[Offset + 3]),
+    Printable (SpdData[Offset + 4]),
+    Printable (SpdData[Offset + 5]),
+    Printable (SpdData[Offset + 6]),
+    Printable (SpdData[Offset + 7]),
+    Printable (SpdData[Offset + 8]),
+    Printable (SpdData[Offset + 9]),
+    Printable (SpdData[Offset + 10]),
+    Printable (SpdData[Offset + 11]),
+    Printable (SpdData[Offset + 12]),
+    Printable (SpdData[Offset + 13]),
+    Printable (SpdData[Offset + 14]),
+    Printable (SpdData[Offset + 15]),
+    Printable (SpdData[Offset + 16]),
+    Printable (SpdData[Offset + 17])
+    );
+
+  return UpdateStringPack (
+           ((ARM_TYPE17 *)Table)->Strings,
+           Str,
+           ((ARM_TYPE17 *)Table)->Base.PartNumber
+           );
+}
+
+/**
+   Install SMBIOS Type 16 17 and 19 table
+
+   @param  Smbios               SMBIOS protocol.
+**/
+EFI_STATUS
+InstallMemStructures (
+  IN EFI_SMBIOS_PROTOCOL *Smbios
+  )
+{
+  EFI_STATUS         Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE  SmbiosHandle;
+  EFI_SMBIOS_HANDLE  Type16Handle;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  PLATFORM_DIMM      *Dimm;
+  CHAR8              *Table;
+  VOID               *Hob;
+  UINTN              Index;
+  UINTN              SlotIndex;
+  UINTN              MemRegionIndex;
+  UINT64             MemorySize = 0;
+  CHAR8              Str[64];
+
+  ASSERT (Smbios != NULL);
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  Table = AllocateZeroPool (sizeof (ARM_TYPE17));
+  if (Table == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
+    // Copy template to Type 16
+    CopyMem (Table, (VOID *)&mArmDefaultType16, sizeof (ARM_TYPE16));
+
+    ((ARM_TYPE16 *)Table)->Base.MaximumCapacity = 0x80000000;
+    ((ARM_TYPE16 *)Table)->Base.ExtendedMaximumCapacity = 0x40000000000ULL; /* 4TB per socket */
+    ((ARM_TYPE16 *)Table)->Base.MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
+
+    // Install Type 16 and hold the handle so that the subsequence type17/19 could use
+    Type16Handle = ((ARM_TYPE16 *)Table)->Base.Hdr.Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &Type16Handle,
+                       (EFI_SMBIOS_TABLE_HEADER *)Table
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 16 socket %d failed\n", __FUNCTION__, Index));
+      FreePool (Table);
+      // stop adding rather than continuing
+      return Status;
+    }
+
+    for (SlotIndex = 0; SlotIndex < PlatformHob->DimmList.BoardDimmSlots; SlotIndex++) {
+      // Copy Tempplate to Type 17
+      CopyMem (Table, (VOID *)&mArmDefaultType17, sizeof (ARM_TYPE17));
+
+      // Fill up type 17 table's content here
+      Dimm = &PlatformHob->DimmList.Dimm[SlotIndex];
+      if (Dimm->NodeId != Index) {
+        continue;
+      }
+
+      if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
+
+        UpdateManufacturer ((VOID *)Table, Dimm->SpdData.Data);
+        UpdateSerialNumber ((VOID *)Table, Dimm->SpdData.Data);
+        UpdatePartNumber ((VOID *)Table, Dimm->SpdData.Data);
+
+        MemorySize = Dimm->Info.DimmSize * 1024;
+        if (MemorySize >= 0x7FFF) {
+          ((ARM_TYPE17 *)Table)->Base.Size = 0x7FFF;
+          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = MemorySize;
+        } else {
+          ((ARM_TYPE17 *)Table)->Base.Size = (UINT16)MemorySize;
+          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = 0;
+        }
+
+        ((ARM_TYPE17 *)Table)->Base.MemoryType = 0x1A; /* DDR4 */
+        ((ARM_TYPE17 *)Table)->Base.Speed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
+        ((ARM_TYPE17 *)Table)->Base.ConfiguredMemoryClockSpeed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
+        ((ARM_TYPE17 *)Table)->Base.Attributes = Dimm->Info.DimmNrRank & 0x0F;
+        ((ARM_TYPE17 *)Table)->Base.ConfiguredVoltage = 1200;
+        ((ARM_TYPE17 *)Table)->Base.MinimumVoltage = 1140;
+        ((ARM_TYPE17 *)Table)->Base.MaximumVoltage = 1260;
+        ((ARM_TYPE17 *)Table)->Base.DeviceSet = 0; // None
+
+        if (Dimm->Info.DimmType == UDIMM || Dimm->Info.DimmType == SODIMM) {
+          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Unbuffered = 1; /* BIT 14: unregistered */
+        } else if (Dimm->Info.DimmType == RDIMM
+                   || Dimm->Info.DimmType == LRDIMM
+                   || Dimm->Info.DimmType == RSODIMM)
+        {
+          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Registered = 1; /* BIT 13: registered */
+        }
+        /* FIXME: Determine if need to set technology to NVDIMM-* when supported */
+        ((ARM_TYPE17 *)Table)->Base.MemoryTechnology = 0x3; // DRAM
+      }
+      AsciiSPrint (Str, sizeof (Str), "Socket %d DIMM %d", Index, SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.DeviceLocator);
+      AsciiSPrint (Str, sizeof (Str), "Bank %d", SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.BankLocator);
+      AsciiSPrint (Str, sizeof (Str), "Array %d Asset Tag %d", Index, SlotIndex);
+      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.AssetTag);
+
+      // Update Type 16 handle
+      ((ARM_TYPE17 *)Table)->Base.MemoryArrayHandle = Type16Handle;
+
+      // Install structure
+      SmbiosHandle = ((ARM_TYPE17 *)Table)->Base.Hdr.Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER *)Table
+                         );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((
+          DEBUG_ERROR,
+          "%a: adding SMBIOS type 17 Socket %d Slot %d failed\n",
+          __FUNCTION__,
+          Index,
+          SlotIndex
+          ));
+        FreePool (Table);
+        // stop adding rather than continuing
+        return Status;
+      }
+    }
+
+    for (MemRegionIndex = 0; MemRegionIndex < PlatformHob->DramInfo.NumRegion; MemRegionIndex++) {
+      // Copy Tempplate to Type 19
+      CopyMem (Table, (VOID *)&mArmDefaultType19, sizeof (ARM_TYPE19));
+
+      if (PlatformHob->DramInfo.NvdRegion[MemRegionIndex] > 0
+          || PlatformHob->DramInfo.Socket[MemRegionIndex] != Index)
+      {
+        continue;
+      }
+
+      ((ARM_TYPE19 *)Table)->Base.StartingAddress = 0xFFFFFFFF;
+      ((ARM_TYPE19 *)Table)->Base.EndingAddress = 0xFFFFFFFF;
+      ((ARM_TYPE19 *)Table)->Base.ExtendedStartingAddress = PlatformHob->DramInfo.Base[MemRegionIndex];
+      ((ARM_TYPE19 *)Table)->Base.ExtendedEndingAddress = PlatformHob->DramInfo.Base[MemRegionIndex] +
+                                                          PlatformHob->DramInfo.Size[MemRegionIndex] - 1;
+
+      if (MemorySize != 0) {
+        ((ARM_TYPE19 *)Table)->Base.PartitionWidth = (PlatformHob->DramInfo.Size[MemRegionIndex] - 1) / MemorySize + 1;
+      }
+
+      // Update Type 16 handle
+      ((ARM_TYPE19 *)Table)->Base.MemoryArrayHandle = Type16Handle;
+
+      // Install structure
+      SmbiosHandle = ((ARM_TYPE19 *)Table)->Base.Hdr.Handle;
+      Status = Smbios->Add (
+                         Smbios,
+                         NULL,
+                         &SmbiosHandle,
+                         (EFI_SMBIOS_TABLE_HEADER *)Table
+                         );
+      if (EFI_ERROR (Status)) {
+        DEBUG ((
+          DEBUG_ERROR,
+          "%a: adding SMBIOS type 19 Socket %d MemRegion %d failed\n",
+          __FUNCTION__,
+          Index,
+          MemRegionIndex
+          ));
+        FreePool (Table);
+        // stop adding rather than continuing
+        return Status;
+      }
+    }
+  }
+
+  FreePool (Table);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SmbiosMemInfoDxeEntry (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS          Status;
+  EFI_SMBIOS_PROTOCOL *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **)&Smbios
+                  );
+
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  Status = InstallMemStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosMemInfoDxe install: %r\n", Status));
+
+  return Status;
+}
diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
new file mode 100644
index 000000000000..086fdd9749fb
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
@@ -0,0 +1,1049 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Guid/SmBios.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/Smbios.h>
+
+// Type0 Data
+#define VENDOR_TEMPLATE       "Ampere(R)\0"
+#define BIOS_VERSION_TEMPLATE "TianoCore EDKII\0"
+#define RELEASE_DATE_TEMPLATE "MM/DD/YYYY\0"
+
+#define TYPE0_ADDITIONAL_STRINGS                    \
+  VENDOR_TEMPLATE       /* Vendor */         \
+  BIOS_VERSION_TEMPLATE /* BiosVersion */    \
+  RELEASE_DATE_TEMPLATE /* BiosReleaseDate */
+
+// Type1 Data
+#define MANUFACTURER_TEMPLATE "Ampere(R)\0"
+#define PRODUCT_NAME_TEMPLATE "Mt. Jade\0"
+#define SYS_VERSION_TEMPLATE  "PR010\0"
+#define SERIAL_TEMPLATE       "123456789ABCDEFF123456789ABCDEFF\0"
+#define SKU_TEMPLATE          "FEDCBA9876543211FEDCBA9876543211\0"
+#define FAMILY_TEMPLATE       "ARMv8\0"
+
+#define TYPE1_ADDITIONAL_STRINGS                  \
+  MANUFACTURER_TEMPLATE /* Manufacturer */  \
+  PRODUCT_NAME_TEMPLATE /* Product Name */  \
+  SYS_VERSION_TEMPLATE  /* Version */       \
+  SERIAL_TEMPLATE       /* Serial Number */ \
+  SKU_TEMPLATE          /* SKU Number */    \
+  FAMILY_TEMPLATE       /* Family */
+
+#define TYPE2_ADDITIONAL_STRINGS                   \
+  MANUFACTURER_TEMPLATE /* Manufacturer */   \
+  PRODUCT_NAME_TEMPLATE /* Product Name */   \
+  "EVT2\0"              /* Version */        \
+  "Serial Not Set\0"    /* Serial */         \
+  "Base of Chassis\0"   /* board location */ \
+  "FF\0"                /* Version */        \
+  "FF\0"                /* Version */
+
+#define CHASSIS_VERSION_TEMPLATE    "None               \0"
+#define CHASSIS_SERIAL_TEMPLATE     "Serial Not Set     \0"
+#define CHASSIS_ASSET_TAG_TEMPLATE  "Asset Tag Not Set  \0"
+
+#define TYPE3_ADDITIONAL_STRINGS                 \
+  MANUFACTURER_TEMPLATE      /* Manufacturer */ \
+  CHASSIS_VERSION_TEMPLATE   /* Version */      \
+  CHASSIS_SERIAL_TEMPLATE    /* Serial  */      \
+  CHASSIS_ASSET_TAG_TEMPLATE /* Asset Tag */    \
+  SKU_TEMPLATE               /* SKU Number */
+
+#define TYPE8_ADDITIONAL_STRINGS      \
+  "VGA1 - Rear VGA Connector\0"       \
+  "DB-15 Male (VGA)         \0"
+
+#define TYPE9_ADDITIONAL_STRINGS       \
+  "Socket 0 Riser 1 x32 - Slot 1\0"
+
+#define TYPE11_ADDITIONAL_STRINGS       \
+  "www.amperecomputing.com\0"
+
+#define TYPE13_ADDITIONAL_STRINGS       \
+  "en|US|iso8859-1\0"
+
+#define TYPE41_ADDITIONAL_STRINGS       \
+  "Onboard VGA\0"
+
+//
+// Type definition and contents of the default SMBIOS table.
+// This table covers only the minimum structures required by
+// the SMBIOS specification (section 6.2, version 3.0)
+//
+#pragma pack(1)
+typedef struct {
+  SMBIOS_TABLE_TYPE0 Base;
+  CHAR8              Strings[sizeof (TYPE0_ADDITIONAL_STRINGS)];
+} ARM_TYPE0;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE1 Base;
+  CHAR8              Strings[sizeof (TYPE1_ADDITIONAL_STRINGS)];
+} ARM_TYPE1;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE2 Base;
+  CHAR8              Strings[sizeof (TYPE2_ADDITIONAL_STRINGS)];
+} ARM_TYPE2;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE3 Base;
+  CHAR8              Strings[sizeof (TYPE3_ADDITIONAL_STRINGS)];
+} ARM_TYPE3;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE8 Base;
+  CHAR8              Strings[sizeof (TYPE8_ADDITIONAL_STRINGS)];
+} ARM_TYPE8;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE9 Base;
+  CHAR8              Strings[sizeof (TYPE9_ADDITIONAL_STRINGS)];
+} ARM_TYPE9;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE11 Base;
+  CHAR8               Strings[sizeof (TYPE11_ADDITIONAL_STRINGS)];
+} ARM_TYPE11;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE13 Base;
+  CHAR8               Strings[sizeof (TYPE13_ADDITIONAL_STRINGS)];
+} ARM_TYPE13;
+
+typedef struct {
+  SMBIOS_TABLE_TYPE41 Base;
+  CHAR8               Strings[sizeof (TYPE41_ADDITIONAL_STRINGS)];
+} ARM_TYPE41;
+
+#pragma pack()
+
+//-------------------------------------
+//        SMBIOS Platform Common
+//-------------------------------------
+enum {
+  ADDITIONAL_STR_INDEX_1 = 1,
+  ADDITIONAL_STR_INDEX_2,
+  ADDITIONAL_STR_INDEX_3,
+  ADDITIONAL_STR_INDEX_4,
+  ADDITIONAL_STR_INDEX_5,
+  ADDITIONAL_STR_INDEX_6,
+  ADDITIONAL_STR_INDEX_MAX
+};
+
+
+// Type 0 BIOS information
+STATIC ARM_TYPE0 mArmDefaultType0 = {
+  {
+    {                                   // Header
+      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length, The length of the structure's string-set is not included.
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+
+    ADDITIONAL_STR_INDEX_1,     // SMBIOS_TABLE_STRING       Vendor
+    ADDITIONAL_STR_INDEX_2,     // SMBIOS_TABLE_STRING       BiosVersion
+    0,                          // UINT16                    BiosSegment
+    ADDITIONAL_STR_INDEX_3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
+    0,                          // UINT8                     BiosSize
+
+    // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
+    {
+      0,0,0,0,0,0,
+      1, // PCI supported
+      0,
+      1, // PNP supported
+      0,
+      1, // BIOS upgradable
+      0, 0, 0,
+      0, // Boot from CD
+      1, // selectable boot
+    },
+
+    // BIOSCharacteristicsExtensionBytes[2]
+    {
+      0,
+      0,
+    },
+
+    0,     // UINT8                     SystemBiosMajorRelease
+    0,     // UINT8                     SystemBiosMinorRelease
+
+    // If the system does not have field upgradeable embedded controller
+    // firmware, the value is 0FFh
+    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
+    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
+  },
+
+  // Text strings (unformatted area)
+  TYPE0_ADDITIONAL_STRINGS
+};
+
+// Type 1 System information
+STATIC ARM_TYPE1 mArmDefaultType1 = {
+  {
+    { // Header
+      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
+      sizeof (SMBIOS_TABLE_TYPE1),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+
+    ADDITIONAL_STR_INDEX_1,                                                     // Manufacturer
+    ADDITIONAL_STR_INDEX_2,                                                     // Product Name
+    ADDITIONAL_STR_INDEX_3,                                                     // Version
+    ADDITIONAL_STR_INDEX_4,                                                     // Serial Number
+    { 0x12345678, 0x9ABC, 0xDEFF, { 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xFF }}, // UUID
+    SystemWakeupTypePowerSwitch,                                                // Wakeup type
+    ADDITIONAL_STR_INDEX_5,                                                     // SKU Number
+    ADDITIONAL_STR_INDEX_6,                                                     // Family
+  },
+
+  // Text strings (unformatted)
+  TYPE1_ADDITIONAL_STRINGS
+};
+
+// Type 2 Baseboard
+STATIC ARM_TYPE2 mArmDefaultType2 = {
+  {
+    {                                        // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE2),           // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1, // Manufacturer
+    ADDITIONAL_STR_INDEX_2, // Product Name
+    ADDITIONAL_STR_INDEX_3, // Version
+    ADDITIONAL_STR_INDEX_4, // Serial
+    0,                      // Asset tag
+    {1},                    // motherboard, not replaceable
+    ADDITIONAL_STR_INDEX_5, // location of board
+    0xFFFF,                 // chassis handle
+    BaseBoardTypeMotherBoard,
+    0,
+    {0},
+  },
+  TYPE2_ADDITIONAL_STRINGS
+};
+
+// Type 3 Enclosure
+STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
+  {
+    {                                   // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE3),      // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,          // Manufacturer
+    MiscChassisTypeRackMountChassis, // Rack-mounted chassis
+    ADDITIONAL_STR_INDEX_2,          // version
+    ADDITIONAL_STR_INDEX_3,          // serial
+    ADDITIONAL_STR_INDEX_4,          // asset tag
+    ChassisStateUnknown,             // boot chassis state
+    ChassisStateSafe,                // power supply state
+    ChassisStateSafe,                // thermal state
+    ChassisSecurityStatusNone,       // security state
+    {0,0,0,0},                       // OEM defined
+    1,                               // 1U height
+    2,                               // number of power cords
+    0,                               // no contained elements
+    3,                               // ContainedElementRecordLength;
+  },
+  TYPE3_ADDITIONAL_STRINGS
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8Vga = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeDB15Female,  // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeVideoPort,            // PortType;
+  },
+  "VGA1 - Rear VGA Connector\0" \
+  "DB-15 Male (VGA)\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8USBFront = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeUsb,         // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeUsb,                  // PortType;
+  },
+  "Front Panel USB 3.0\0"  \
+  "USB\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8USBRear = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeUsb,         // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeUsb,                  // PortType;
+  },
+  "Rear Panel USB 3.0\0"   \
+  "USB\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8NetRJ45 = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortConnectorTypeRJ45,        // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortConnectorTypeRJ45,        // ExternalConnectorType;
+    PortTypeNetworkPort,          // PortType;
+  },
+  "RJ1 - BMC RJ45 Port\0" \
+  "RJ45 Connector\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8NetOcp = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
+    PortTypeOther,                // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
+    PortTypeOther,                // ExternalConnectorType;
+    PortTypeNetworkPort,          // PortType;
+  },
+  "OCP1 - OCP NIC 3.0 Connector\0"  \
+  "OCP NIC 3.0\0"
+};
+
+// Type 8 Port Connector Information
+STATIC CONST ARM_TYPE8 mArmDefaultType8Uart = {
+  {
+    {                                             // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,        // InternalReferenceDesignator String
+    PortTypeOther,                 // InternalConnectorType;
+    ADDITIONAL_STR_INDEX_2,        // ExternalReferenceDesignator String
+    PortConnectorTypeDB9Female,    // ExternalConnectorType;
+    PortTypeSerial16550Compatible, // PortType;
+  },
+  "UART1 - BMC UART5 Connector\0"  \
+  "DB-9 female\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot1 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth16X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    0,
+    0,
+    0,
+  },
+  "S0 Riser 1 x32 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot2 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    4,
+    0,
+    0,
+  },
+  "S0 Riser x32 - Slot 2\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot3 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    5,
+    0,
+    0,
+  },
+  "S0 Riser x32 - Slot 3\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot1 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    7,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot2 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    8,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 2\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot3 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    9,
+    0,
+    0,
+  },
+  "S1 Riser x24 - Slot 3\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX8Slot1 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth8X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    8,
+    0,
+    0,
+  },
+  "S1 Riser x8 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk0OcpNic = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth16X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    1,
+    0,
+    0,
+  },
+  "S0 OCP NIC 3.0\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot1 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth4X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    5,
+    0,
+    0,
+  },
+  "S1 NVMe M.2 - Slot 1\0"
+};
+
+// Type 9 System Slots
+STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot2 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1,
+    SlotTypePciExpressGen3,
+    SlotDataBusWidth4X,
+    SlotUsageAvailable,
+    SlotLengthLong,
+    0,
+    {0, 0, 1}, // Provides 3.3 Volts
+    {1},       // PME
+    5,
+    0,
+    0,
+  },
+  "S1 NVMe M.2 - Slot 2\0"
+};
+
+// Type 11 OEM Strings
+STATIC ARM_TYPE11 mArmDefaultType11 = {
+  {
+    {                               // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_OEM_STRINGS,  // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE11), // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    ADDITIONAL_STR_INDEX_1
+  },
+  TYPE11_ADDITIONAL_STRINGS
+};
+
+// Type 13 BIOS Language Information
+STATIC ARM_TYPE13 mArmDefaultType13 = {
+  {
+    {                                            // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION, // UINT8 Type
+      sizeof (SMBIOS_TABLE_TYPE13),              // UINT8 Length
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    1,
+    0,
+    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
+    1,
+  },
+  TYPE13_ADDITIONAL_STRINGS
+};
+
+// Type 24 Hardware Security
+STATIC SMBIOS_TABLE_TYPE24 mArmDefaultType24 = {
+  {                                    // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_HARDWARE_SECURITY, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE24),      // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  0
+};
+
+// Type 32 System Boot Information
+STATIC SMBIOS_TABLE_TYPE32 mArmDefaultType32 = {
+  {                                          // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE32),            // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  {0, 0, 0, 0, 0, 0},
+  0
+};
+
+// Type 38 IPMI Device Information
+STATIC SMBIOS_TABLE_TYPE38 mArmDefaultType38 = {
+  {                                          // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION, // UINT8 Type
+    sizeof (SMBIOS_TABLE_TYPE38),            // UINT8 Length
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  IPMIDeviceInfoInterfaceTypeSSIF,
+  0x20,
+  0x20,
+  0xFF,
+  0x20
+};
+
+// Type 41 Onboard Devices Extended Information
+STATIC ARM_TYPE41 mArmDefaultType41 = {
+  {
+    { // SMBIOS_STRUCTURE Hdr
+      EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION,
+      sizeof (SMBIOS_TABLE_TYPE41),
+      SMBIOS_HANDLE_PI_RESERVED,
+    },
+    1,
+    0x83,  // OnBoardDeviceExtendedTypeVideo, Enabled
+    1,
+    4,
+    2,
+    0,
+  },
+  TYPE41_ADDITIONAL_STRINGS
+};
+
+// Type 42 System Boot Information
+STATIC SMBIOS_TABLE_TYPE42 mArmDefaultType42 = {
+  { // SMBIOS_STRUCTURE Hdr
+    EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE,
+    sizeof (SMBIOS_TABLE_TYPE42),
+    SMBIOS_HANDLE_PI_RESERVED,
+  },
+  MCHostInterfaceTypeOemDefined,
+  4,
+  {0xFF, 0, 0, 0}
+};
+
+STATIC CONST VOID *DefaultCommonTables[] =
+{
+  &mArmDefaultType0,
+  &mArmDefaultType1,
+  &mArmDefaultType2,
+  &mArmDefaultType8Vga,
+  &mArmDefaultType8USBFront,
+  &mArmDefaultType8USBRear,
+  &mArmDefaultType8NetRJ45,
+  &mArmDefaultType8NetOcp,
+  &mArmDefaultType8Uart,
+  &mArmDefaultType9Sk0RiserX32Slot1,
+  &mArmDefaultType9Sk0RiserX32Slot2,
+  &mArmDefaultType9Sk0RiserX32Slot3,
+  &mArmDefaultType9Sk1RiserX24Slot1,
+  &mArmDefaultType9Sk1RiserX24Slot2,
+  &mArmDefaultType9Sk1RiserX24Slot3,
+  &mArmDefaultType9Sk1RiserX8Slot1,
+  &mArmDefaultType9Sk0OcpNic,
+  &mArmDefaultType9Sk1NvmeM2Slot1,
+  &mArmDefaultType9Sk1NvmeM2Slot2,
+  &mArmDefaultType11,
+  &mArmDefaultType13,
+  &mArmDefaultType24,
+  &mArmDefaultType32,
+  &mArmDefaultType38,
+  &mArmDefaultType41,
+  &mArmDefaultType42,
+  NULL
+};
+
+typedef struct {
+  CHAR8 MonthNameStr[4]; // example "Jan", Compiler build date, month
+  CHAR8 DigitStr[3];     // example "01", Smbios date format, month
+} MonthStringDig;
+
+STATIC MonthStringDig MonthMatch[12] = {
+  { "Jan", "01" },
+  { "Feb", "02" },
+  { "Mar", "03" },
+  { "Apr", "04" },
+  { "May", "05" },
+  { "Jun", "06" },
+  { "Jul", "07" },
+  { "Aug", "08" },
+  { "Sep", "09" },
+  { "Oct", "10" },
+  { "Nov", "11" },
+  { "Dec", "12" }
+};
+
+STATIC
+VOID
+ConstructBuildDate (
+  OUT CHAR8 *DateBuf
+  )
+{
+  UINTN i;
+
+  // GCC __DATE__ format is "Feb  2 1996"
+  // If the day of the month is less than 10, it is padded with a space on the left
+  CHAR8 *BuildDate = __DATE__;
+
+  // SMBIOS spec date string: MM/DD/YYYY
+  CHAR8 SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE)] = { 0 };
+
+  SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE) - 1] = '\0';
+
+  SmbiosDateStr[2] = '/';
+  SmbiosDateStr[5] = '/';
+
+  // Month
+  for (i = 0; i < sizeof (MonthMatch) / sizeof (MonthMatch[0]); i++) {
+    if (AsciiStrnCmp (&BuildDate[0], MonthMatch[i].MonthNameStr, AsciiStrLen (MonthMatch[i].MonthNameStr)) == 0) {
+      CopyMem (&SmbiosDateStr[0], MonthMatch[i].DigitStr, AsciiStrLen (MonthMatch[i].DigitStr));
+      break;
+    }
+  }
+
+  // Day
+  CopyMem (&SmbiosDateStr[3], &BuildDate[4], 2);
+  if (BuildDate[4] == ' ') {
+    // day is less then 10, SAPCE filed by compiler, SMBIOS requires 0
+    SmbiosDateStr[3] = '0';
+  }
+
+  // Year
+  CopyMem (&SmbiosDateStr[6], &BuildDate[7], 4);
+
+  CopyMem (DateBuf, SmbiosDateStr, AsciiStrLen (RELEASE_DATE_TEMPLATE));
+}
+
+STATIC
+UINT8
+GetBiosVerMajor (
+  VOID
+  )
+{
+  return (PcdGet8 (PcdSmbiosTables1MajorVersion));
+}
+
+STATIC
+UINT8
+GetBiosVerMinor (
+  VOID
+  )
+{
+  return (PcdGet8 (PcdSmbiosTables1MinorVersion));
+}
+
+STATIC
+EFI_STATUS
+UpdateSmbiosType0 (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  EFI_STATUS                          Status        = EFI_SUCCESS;
+  MISC_BIOS_CHARACTERISTICS_EXTENSION *MiscExt      = NULL;
+  CHAR8                               *ReleaseDateBuf = NULL;
+  CHAR8                               *PcdReleaseDate = NULL;
+  CHAR8                               AsciiVersion[32];
+  UINTN                               Index;
+
+  //
+  //  Update Type0 information
+  //
+  ReleaseDateBuf = &mArmDefaultType0.Strings[0]
+                   + sizeof (VENDOR_TEMPLATE) - 1
+                   + sizeof (BIOS_VERSION_TEMPLATE) - 1;
+  PcdReleaseDate = (CHAR8 *)PcdGetPtr (PcdSmbiosTables0BiosReleaseDate);
+
+  if (AsciiStrnCmp (PcdReleaseDate, RELEASE_DATE_TEMPLATE, AsciiStrLen (RELEASE_DATE_TEMPLATE)) == 0) {
+    // If PCD is still template date MM/DD/YYYY, use compiler date
+    ConstructBuildDate (ReleaseDateBuf);
+  } else {
+    // PCD is updated somehow, use PCD date
+    CopyMem (ReleaseDateBuf, PcdReleaseDate, AsciiStrLen (PcdReleaseDate));
+  }
+
+  if (PcdGet32 (PcdFdSize) < SIZE_16MB) {
+    mArmDefaultType0.Base.BiosSize = (PcdGet32 (PcdFdSize) / SIZE_64KB) - 1;
+
+    mArmDefaultType0.Base.ExtendedBiosSize.Size = 0;
+    mArmDefaultType0.Base.ExtendedBiosSize.Unit = 0;
+  } else {
+    // TODO: Need to update Extended BIOS ROM Size
+    mArmDefaultType0.Base.BiosSize = 0xFF;
+
+    // As a reminder
+    ASSERT (FALSE);
+  }
+
+  // Type0 BIOS Characteristics Extension Byte 1
+  MiscExt = (MISC_BIOS_CHARACTERISTICS_EXTENSION *)&(mArmDefaultType0.Base.BIOSCharacteristicsExtensionBytes);
+
+  MiscExt->BiosReserved.AcpiIsSupported = 1;
+
+  // Type0 BIOS Characteristics Extension Byte 2
+  MiscExt->SystemReserved.BiosBootSpecIsSupported = 1;
+  MiscExt->SystemReserved.FunctionKeyNetworkBootIsSupported = 1;
+  MiscExt->SystemReserved.UefiSpecificationSupported = 1;
+
+  // Type0 BIOS Release
+  // TODO: to decide another way: If the system does not support the use of this
+  // field, the value is 0FFh
+  mArmDefaultType0.Base.SystemBiosMajorRelease = GetBiosVerMajor ();
+  mArmDefaultType0.Base.SystemBiosMinorRelease = GetBiosVerMinor ();
+
+  /* Update SMBIOS Type 0 EC Info */
+  CopyMem (
+    (VOID *)&AsciiVersion,
+    (VOID *)&PlatformHob->SmPmProVer,
+    sizeof (PlatformHob->SmPmProVer)
+    );
+  /* The AsciiVersion is formated as "major.minor" */
+  for (Index = 0; Index < (UINTN)AsciiStrLen (AsciiVersion); Index++) {
+    if (AsciiVersion[Index] == '.') {
+      AsciiVersion[Index] = '\0';
+      break;
+    }
+  }
+
+  mArmDefaultType0.Base.EmbeddedControllerFirmwareMajorRelease =
+    (UINT8)AsciiStrDecimalToUintn (AsciiVersion);
+  mArmDefaultType0.Base.EmbeddedControllerFirmwareMinorRelease =
+    (UINT8)AsciiStrDecimalToUintn (AsciiVersion + Index + 1);
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+InstallType3Structure (
+  IN EFI_SMBIOS_PROTOCOL *Smbios
+  )
+{
+  EFI_STATUS          Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE   SmbiosHandle;
+
+  ASSERT (Smbios != NULL);
+
+  SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) &mArmDefaultType3)->Handle;
+  Status = Smbios->Add (
+                     Smbios,
+                     NULL,
+                     &SmbiosHandle,
+                     (EFI_SMBIOS_TABLE_HEADER *)&mArmDefaultType3
+                     );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "adding SMBIOS type 3 failed\n"));
+    // stop adding rather than continuing
+    return Status;
+  }
+
+  // Save this handle to type 2 table
+  mArmDefaultType2.Base.ChassisHandle = SmbiosHandle;
+
+  return Status;
+}
+
+/**
+   Install a whole table worth of structures
+
+   @param  Smbios               SMBIOS protocol.
+   @param  DefaultTables        A pointer to the default SMBIOS table structure.
+**/
+EFI_STATUS
+InstallStructures (
+  IN       EFI_SMBIOS_PROTOCOL *Smbios,
+  IN CONST VOID                *DefaultTables[]
+  )
+{
+  EFI_STATUS        Status = EFI_SUCCESS;
+  EFI_SMBIOS_HANDLE SmbiosHandle;
+  UINTN             TableIndex;
+
+  ASSERT (Smbios != NULL);
+
+  for (TableIndex = 0; DefaultTables[TableIndex] != NULL; TableIndex++) {
+    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex])->Handle;
+    Status = Smbios->Add (
+                       Smbios,
+                       NULL,
+                       &SmbiosHandle,
+                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex]
+                       );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, TableIndex));
+
+      // stop adding rather than continuing
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UpdateSmbiosInfo (
+  VOID
+  )
+{
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  //
+  //  Update Type0 information
+  //
+  UpdateSmbiosType0 (PlatformHob);
+
+}
+
+/**
+   Install all structures from the DefaultTables structure
+
+   @param  Smbios               SMBIOS protocol
+
+**/
+EFI_STATUS
+InstallAllStructures (
+  IN EFI_SMBIOS_PROTOCOL *Smbios
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  ASSERT (Smbios != NULL);
+
+  // Update SMBIOS Tables
+  UpdateSmbiosInfo ();
+
+  // Install Type 3 table
+  InstallType3Structure (Smbios);
+
+  // Install Tables
+  Status = InstallStructures (Smbios, DefaultCommonTables);
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
+
+/**
+   Installs SMBIOS information for ARM platforms
+
+   @param ImageHandle     Module's image handle
+   @param SystemTable     Pointer of EFI_SYSTEM_TABLE
+
+   @retval EFI_SUCCESS    Smbios data successfully installed
+   @retval Other          Smbios data was not installed
+
+**/
+EFI_STATUS
+EFIAPI
+SmbiosPlatformDxeEntry (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS          Status;
+  EFI_SMBIOS_PROTOCOL *Smbios;
+
+  //
+  // Find the SMBIOS protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiSmbiosProtocolGuid,
+                  NULL,
+                  (VOID **)&Smbios
+                  );
+
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = InstallAllStructures (Smbios);
+  DEBUG ((DEBUG_ERROR, "SmbiosPlatform install - %r\n", Status));
+
+  return Status;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (20 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:08   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
                   ` (12 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Helps to show various system information like CPU info and Board Setting
values to UART console during boot process.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                    |   2 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf |  41 ++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c   | 230 ++++++++++++++++++++
 4 files changed, 274 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
index 930bbb5d385b..2d380b21df24 100755
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
@@ -534,6 +534,7 @@ [Components.common]
   ArmPlatformPkg/PlatformPei/PlatformPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
   ArmPkg/Drivers/CpuPei/CpuPei.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 3d5d857178b3..8c09e2a49089 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -167,6 +167,8 @@ [FV.FVMAIN_COMPACT]
   #
   # Print platform information before passing control into the Driver Execution Environment (DXE) phase
   #
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
+
   INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
 
   FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
new file mode 100755
index 000000000000..11414f72f369
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
@@ -0,0 +1,41 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = DebugInfo
+  FILE_GUID                      = C0571D26-6176-11E9-8647-D663BD873D93
+  MODULE_TYPE                    = PEIM
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = DebugInfoPeiEntryPoint
+
+[Sources]
+  DebugInfoPei.c
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  ArmLib
+  HobLib
+  NVParamLib
+  PeimEntryPoint
+  PrintLib
+  SerialPortLib
+
+[Guids]
+  gPlatformHobGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
new file mode 100644
index 000000000000..d6775ffa4a79
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
@@ -0,0 +1,230 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Uefi.h>
+
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/ArmLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PrintLib.h>
+#include <Library/SerialPortLib.h>
+#include <NVParamDef.h>
+#include <Pcie.h>
+#include <PlatformInfoHob.h>
+
+#define MAX_PRINT_LEN       512
+
+#define GB_SCALE_FACTOR     1073741824
+#define MB_SCALE_FACTOR     1048576
+#define KB_SCALE_FACTOR     1024
+#define MHZ_SCALE_FACTOR    1000000
+
+STATIC VOID
+SerialPrint (
+  IN CONST CHAR8 *FormatString,
+  ...
+  )
+{
+  CHAR8   Buf[MAX_PRINT_LEN];
+  VA_LIST Marker;
+  UINTN   NumberOfPrinted;
+
+  VA_START (Marker, FormatString);
+  NumberOfPrinted = AsciiVSPrint (Buf, sizeof (Buf), FormatString, Marker);
+  SerialPortWrite ((UINT8 *)Buf, NumberOfPrinted);
+  VA_END (Marker);
+}
+
+/**
+  Print any existence NVRAM.
+**/
+STATIC VOID
+PrintNVRAM (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  NVPARAM    Idx;
+  UINT32     Val;
+  UINT16     ACLRd = NV_PERM_ALL;
+  BOOLEAN    Flag;
+
+  Flag = FALSE;
+  for (Idx = NV_PREBOOT_PARAM_START; Idx <= NV_PREBOOT_PARAM_MAX; Idx += NVPARAM_SIZE) {
+    Status = NVParamGet (Idx, ACLRd, &Val);
+    if (!EFI_ERROR (Status)) {
+      if (!Flag) {
+        SerialPrint ("Pre-boot Configuration Setting:\n");
+        Flag = TRUE;
+      }
+      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
+    }
+  }
+
+  Flag = FALSE;
+  for (Idx = NV_MANU_PARAM_START; Idx <= NV_MANU_PARAM_MAX; Idx += NVPARAM_SIZE) {
+    Status = NVParamGet (Idx, ACLRd, &Val);
+    if (!EFI_ERROR (Status)) {
+      if (!Flag) {
+        SerialPrint ("Manufacturer Configuration Setting:\n");
+        Flag = TRUE;
+      }
+      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
+    }
+  }
+
+  Flag = FALSE;
+  for (Idx = NV_USER_PARAM_START; Idx <= NV_USER_PARAM_MAX; Idx += NVPARAM_SIZE) {
+    Status = NVParamGet (Idx, ACLRd, &Val);
+    if (!EFI_ERROR (Status)) {
+      if (!Flag) {
+        SerialPrint ("User Configuration Setting:\n");
+        Flag = TRUE;
+      }
+      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
+    }
+  }
+
+  Flag = FALSE;
+  for (Idx = NV_BOARD_PARAM_START; Idx <= NV_BOARD_PARAM_MAX; Idx += NVPARAM_SIZE) {
+    Status = NVParamGet (Idx, ACLRd, &Val);
+    if (!EFI_ERROR (Status)) {
+      if (!Flag) {
+        SerialPrint ("Board Configuration Setting:\n");
+        Flag = TRUE;
+      }
+      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
+    }
+  }
+}
+
+STATIC
+CHAR8 *
+GetCCIXLinkSpeed (
+  IN UINTN Speed
+  )
+{
+  switch (Speed) {
+  case 1:
+    return "2.5 GT/s";
+
+  case 2:
+    return "5 GT/s";
+
+  case 3:
+    return "8 GT/s";
+
+  case 4:
+  case 6:
+    return "16 GT/s";
+
+  case 0xa:
+    return "20 GT/s";
+
+  case 0xf:
+    return "25 GT/s";
+  }
+
+  return "Unknown";
+}
+
+/**
+  Print system info
+**/
+STATIC VOID
+PrintSystemInfo (
+  VOID
+  )
+{
+  UINTN              Idx;
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return;
+  }
+
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  SerialPrint ("SCP FW version    : %a\n", (const CHAR8 *)PlatformHob->SmPmProVer);
+  SerialPrint ("SCP FW build date : %a\n", (const CHAR8 *)PlatformHob->SmPmProBuild);
+
+  SerialPrint ("Failsafe status                 : %d\n", PlatformHob->FailSafeStatus);
+  SerialPrint ("Reset status                    : %d\n", PlatformHob->ResetStatus);
+  SerialPrint ("CPU info\n");
+  SerialPrint ("    CPU ID                      : %X\n", ArmReadMidr ());
+  SerialPrint ("    CPU Clock                   : %d MHz\n", PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+  SerialPrint ("    Number of active sockets    : %d\n", GetNumberOfActiveSockets ());
+  SerialPrint ("    Number of active cores      : %d\n", GetNumberOfActiveCores ());
+  if (IsSlaveSocketActive ()) {
+    SerialPrint (
+      "    Inter Socket Connection 0   : Width: x%d / Speed %a\n",
+      PlatformHob->Link2PWidth[0],
+      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[0])
+      );
+    SerialPrint (
+      "    Inter Socket Connection 1   : Width: x%d / Speed %a\n",
+      PlatformHob->Link2PWidth[1],
+      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[1])
+      );
+  }
+  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
+    SerialPrint ("    Socket[%d]: Core voltage     : %d\n", Idx, PlatformHob->CoreVoltage[Idx]);
+    SerialPrint ("    Socket[%d]: SCU ProductID    : %X\n", Idx, PlatformHob->ScuProductId[Idx]);
+    SerialPrint ("    Socket[%d]: Max cores        : %d\n", Idx, PlatformHob->MaxNumOfCore[Idx]);
+    SerialPrint ("    Socket[%d]: Warranty         : %d\n", Idx, PlatformHob->Warranty[Idx]);
+    SerialPrint ("    Socket[%d]: Subnuma          : %d\n", Idx, PlatformHob->SubNumaMode[Idx]);
+    SerialPrint ("    Socket[%d]: RC disable mask  : %X\n", Idx, PlatformHob->RcDisableMask[Idx]);
+    SerialPrint ("    Socket[%d]: AVS enabled      : %d\n", Idx, PlatformHob->AvsEnable[Idx]);
+    SerialPrint ("    Socket[%d]: AVS voltage      : %d\n", Idx, PlatformHob->AvsVoltageMV[Idx]);
+  }
+
+  SerialPrint ("SOC info\n");
+  SerialPrint ("    DDR Frequency               : %d MHz\n", PlatformHob->DramInfo.MaxSpeed);
+  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
+    SerialPrint ("    Socket[%d]: Soc voltage      : %d\n", Idx, PlatformHob->SocVoltage[Idx]);
+    SerialPrint ("    Socket[%d]: DIMM1 voltage    : %d\n", Idx, PlatformHob->Dimm1Voltage[Idx]);
+    SerialPrint ("    Socket[%d]: DIMM2 voltage    : %d\n", Idx, PlatformHob->Dimm2Voltage[Idx]);
+  }
+
+  SerialPrint ("    PCP Clock                   : %d MHz\n", PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
+  SerialPrint ("    SOC Clock                   : %d MHz\n", PlatformHob->SocClk / MHZ_SCALE_FACTOR);
+  SerialPrint ("    SYS Clock                   : %d MHz\n", PlatformHob->SysClk / MHZ_SCALE_FACTOR);
+  SerialPrint ("    AHB Clock                   : %d MHz\n", PlatformHob->AhbClk / MHZ_SCALE_FACTOR);
+}
+
+/**
+  Entry point function for the PEIM
+
+  @param FileHandle      Handle of the file being invoked.
+  @param PeiServices     Describes the list of possible PEI Services.
+
+  @return EFI_SUCCESS    If we installed our PPI
+
+**/
+EFI_STATUS
+EFIAPI
+DebugInfoPeiEntryPoint (
+  IN       EFI_PEI_FILE_HANDLE FileHandle,
+  IN CONST EFI_PEI_SERVICES    **PeiServices
+  )
+{
+  PrintSystemInfo ();
+  PrintNVRAM ();
+
+  return EFI_SUCCESS;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (21 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:10   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
                   ` (11 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provide screen menu with basic platform information include:
* Platform name
* SCP firmware info
* System bus clock frequency.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Platform/Ampere/JadePkg/Jade.dsc                                          |   5 +
 Platform/Ampere/JadePkg/Jade.fdf                                          |   5 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf |  52 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h   |  22 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr             | 112 ++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c   | 391 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni      |  56 +++
 7 files changed, 643 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 9c7d7cad4915..b5edb673abba 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -174,3 +174,8 @@ [Components.common]
   Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
   Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
   Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
+
+  #
+  # HII
+  #
+  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 8c09e2a49089..6dd759322d9d 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -350,4 +350,9 @@ [FV.FvMain]
   INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
   INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
 
+  #
+  # HII
+  #
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
new file mode 100644
index 000000000000..09de87915510
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
@@ -0,0 +1,52 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PlatformInfoDxe
+  FILE_GUID                      = 6FDFB3E8-105E-48C4-94AA-3D7646F9B50D
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PlatformInfoEntryPoint
+
+[Sources.common]
+  PlatformInfoDxe.c
+  PlatformInfoHii.h
+  Vfr.vfr
+  VfrStrings.uni
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DevicePathLib
+  HiiLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gPlatformManagerFormsetGuid
+  gEfiIfrTianoGuid
+  gPlatformHobGuid
+
+[Protocols]
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
new file mode 100644
index 000000000000..7f363160afc8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
@@ -0,0 +1,22 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PLATFORM_INFO_HII_H_
+#define PLATFORM_INFO_HII_H_
+
+#define PLATFORM_INFO_FORMSET_GUID \
+  { \
+    0x8DF0F6FB, 0x65A5, 0x434B, { 0xB2, 0xA6, 0xCE, 0xDF, 0xD2, 0x0A, 0x96, 0x8A } \
+  }
+
+#define LABEL_UPDATE             0x2223
+#define LABEL_END                0x2224
+
+#define PLATFORM_INFO_FORM_ID    0x1
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
new file mode 100644
index 000000000000..5dd32a30f0ad
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
@@ -0,0 +1,112 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlatformInfoHii.h"
+
+formset
+  guid      = PLATFORM_INFO_FORMSET_GUID,
+  title     = STRING_TOKEN(STR_PLATFORM_INFO_FORM),
+  help      = STRING_TOKEN(STR_PLATFORM_INFO_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  form
+    formid = PLATFORM_INFO_FORM_ID,
+    title  = STRING_TOKEN(STR_PLATFORM_INFO_FORM);
+    subtitle text = STRING_TOKEN(STR_PLATFORM_INFO_FORM_HELP);
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    text
+      help   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK),
+      text   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK_VALUE),
+      flags  = 0,
+      key    = 0;
+
+    label LABEL_UPDATE;
+    // dynamic content here
+    label LABEL_END;
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
new file mode 100644
index 000000000000..a55d0e9da9e7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
@@ -0,0 +1,391 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/IoLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <PlatformInfoHob.h>
+
+#include "PlatformInfoHii.h"
+
+//
+// uni string and Vfr Binary data.
+//
+extern UINT8 VfrBin[];
+extern UINT8 PlatformInfoDxeStrings[];
+
+EFI_HANDLE     mDriverHandle = NULL;
+EFI_HII_HANDLE mHiiHandle = NULL;
+
+#pragma pack(1)
+
+//
+// HII specific Vendor Device Path definition.
+//
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+// PLATFORM_INFO_FORMSET_GUID
+EFI_GUID gPlatformInfoFormSetGuid = PLATFORM_INFO_FORMSET_GUID;
+
+HII_VENDOR_DEVICE_PATH mPlatformInfoHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    PLATFORM_INFO_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+#define MAX_STRING_SIZE     64
+#define MHZ_SCALE_FACTOR    1000000
+
+STATIC
+CHAR8 *
+GetCCIXLinkSpeed (
+  IN UINTN Speed
+  )
+{
+  switch (Speed) {
+  case 1:
+    return "2.5 GT/s";
+
+  case 2:
+    return "5 GT/s";
+
+  case 3:
+    return "8 GT/s";
+
+  case 4:
+  case 6:
+    return "16 GT/s";
+
+  case 0xa:
+    return "20 GT/s";
+
+  case 0xf:
+    return "25 GT/s";
+  }
+
+  return "Unknown";
+}
+
+STATIC
+EFI_STATUS
+UpdatePlatformInfoScreen (
+  IN EFI_HII_HANDLE *HiiHandle
+  )
+{
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  CHAR16             Str[MAX_STRING_SIZE];
+
+  VOID               *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *EndLabel;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  /* SCP Version */
+  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->SmPmProVer, Str, MAX_STRING_SIZE);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_SCPVER_VALUE),
+    Str,
+    NULL
+    );
+
+  /* SCP build */
+  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->SmPmProBuild, Str, MAX_STRING_SIZE);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_SCPBUILD_VALUE),
+    Str,
+    NULL
+    );
+
+  /* CPU Info */
+  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->CpuInfo, Str, MAX_STRING_SIZE);
+  UnicodeSPrint (Str, sizeof (Str), L"%s", Str);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_CPUINFO_VALUE),
+    Str,
+    NULL
+    );
+
+  /* CPU clock */
+  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_CPUCLK_VALUE),
+    Str,
+    NULL
+    );
+
+  /* PCP clock */
+  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_PCPCLK_VALUE),
+    Str,
+    NULL
+    );
+
+  /* SOC clock */
+  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->SocClk / MHZ_SCALE_FACTOR);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_SOCCLK_VALUE),
+    Str,
+    NULL
+    );
+
+  /* L1 Cache */
+  UnicodeSPrint (Str, sizeof (Str), L"64KB");
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_L1ICACHE_VALUE),
+    Str,
+    NULL
+    );
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_L1DCACHE_VALUE),
+    Str,
+    NULL
+    );
+
+  /* L2 Cache */
+  UnicodeSPrint (Str, sizeof (Str), L"1MB");
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_L2CACHE_VALUE),
+    Str,
+    NULL
+    );
+
+  /* AHB clock */
+  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->AhbClk / MHZ_SCALE_FACTOR);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_AHBCLK_VALUE),
+    Str,
+    NULL
+    );
+
+  /* SYS clock */
+  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->SysClk / MHZ_SCALE_FACTOR);
+  HiiSetString (
+    HiiHandle,
+    STRING_TOKEN (STR_PLATFORM_INFO_SYSCLK_VALUE),
+    Str,
+    NULL
+    );
+
+  /* Initialize the container for dynamic opcodes */
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  /* Create Hii Extend Label OpCode as the start opcode */
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  ASSERT (StartLabel != NULL);
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  /* Create Hii Extend Label OpCode as the end opcode */
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  ASSERT (EndLabel != NULL);
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  if (IsSlaveSocketActive ()) {
+    /* Create the inter socket link text string */
+    UnicodeSPrint (
+      Str,
+      sizeof (Str),
+      L"Width x%d / Speed %a",
+      PlatformHob->Link2PWidth[0],
+      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[0])
+      );
+
+    HiiSetString (
+      mHiiHandle,
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE),
+      Str,
+      NULL
+      );
+
+    HiiCreateTextOpCode (
+      StartOpCodeHandle,
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0),
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0),
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE)
+      );
+
+    UnicodeSPrint (
+      Str,
+      sizeof (Str),
+      L"Width x%d / Speed %a",
+      PlatformHob->Link2PWidth[1],
+      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[1])
+      );
+
+    HiiSetString (
+      mHiiHandle,
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE),
+      Str,
+      NULL
+      );
+
+    HiiCreateTextOpCode (
+      StartOpCodeHandle,
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1),
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1),
+      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE)
+      );
+  }
+
+  HiiUpdateForm (
+    mHiiHandle,                 // HII handle
+    &gPlatformInfoFormSetGuid,  // Formset GUID
+    PLATFORM_INFO_FORM_ID,      // Form ID
+    StartOpCodeHandle,          // Label for where to insert opcodes
+    EndOpCodeHandle             // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformInfoUnload (
+  VOID
+  )
+{
+  if (mDriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mPlatformInfoHiiVendorDevicePath,
+           NULL
+           );
+    mDriverHandle = NULL;
+  }
+
+  if (mHiiHandle != NULL) {
+    HiiRemovePackages (mHiiHandle);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PlatformInfoEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mDriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mPlatformInfoHiiVendorDevicePath,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  //
+  // Publish our HII data
+  //
+  mHiiHandle = HiiAddPackages (
+                 &gPlatformInfoFormSetGuid,
+                 mDriverHandle,
+                 PlatformInfoDxeStrings,
+                 VfrBin,
+                 NULL
+                 );
+  if (mHiiHandle == NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mPlatformInfoHiiVendorDevicePath,
+           NULL
+           );
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = UpdatePlatformInfoScreen (mHiiHandle);
+  if (EFI_ERROR (Status)) {
+    PlatformInfoUnload ();
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a %d Fail to update the platform info screen \n",
+      __FUNCTION__,
+      __LINE__
+      ));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
new file mode 100644
index 000000000000..235d104c217f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US  "English"
+
+#string STR_PLATFORM_INFO_FORM                      #language en-US "Platform Board Information"
+#string STR_PLATFORM_INFO_FORM_HELP                 #language en-US "Platform Board Information"
+
+#string STR_PLATFORM_INFO_SEPERATE_LINE             #language en-US ""
+
+#string STR_PLATFORM_INFO_BOARD                     #language en-US "Board"
+#string STR_PLATFORM_INFO_BOARD_VALUE               #language en-US "Mt. Jade"
+
+#string STR_PLATFORM_INFO_SCPVER                    #language en-US "SCP FW Version"
+#string STR_PLATFORM_INFO_SCPVER_VALUE              #language en-US "0"
+
+#string STR_PLATFORM_INFO_RCVER                     #language en-US "Reference Code version"
+#string STR_PLATFORM_INFO_RCVER_VALUE               #language en-US "0"
+
+#string STR_PLATFORM_INFO_SCPBUILD                  #language en-US "SCP FW Build"
+#string STR_PLATFORM_INFO_SCPBUILD_VALUE            #language en-US "0"
+
+#string STR_PLATFORM_INFO_CPUINFO                   #language en-US "CPU"
+#string STR_PLATFORM_INFO_CPUINFO_VALUE             #language en-US " "
+
+#string STR_PLATFORM_INFO_CPUCLK                    #language en-US "CPU Clock"
+#string STR_PLATFORM_INFO_CPUCLK_VALUE              #language en-US "0MHz"
+
+#string STR_PLATFORM_INFO_PCPCLK                    #language en-US "PCP Clock"
+#string STR_PLATFORM_INFO_PCPCLK_VALUE              #language en-US "0MHz"
+
+#string STR_PLATFORM_INFO_L1ICACHE                  #language en-US "L1I CACHE"
+#string STR_PLATFORM_INFO_L1ICACHE_VALUE            #language en-US "0KB"
+
+#string STR_PLATFORM_INFO_L1DCACHE                  #language en-US "L1D CACHE"
+#string STR_PLATFORM_INFO_L1DCACHE_VALUE            #language en-US "0KB"
+
+#string STR_PLATFORM_INFO_L2CACHE                   #language en-US "L2 CACHE"
+#string STR_PLATFORM_INFO_L2CACHE_VALUE             #language en-US "0KB"
+
+#string STR_PLATFORM_INFO_SOCCLK                    #language en-US "SOC Clock"
+#string STR_PLATFORM_INFO_SOCCLK_VALUE              #language en-US "0MHz"
+
+#string STR_PLATFORM_INFO_SYSCLK                    #language en-US "Sys Clock"
+#string STR_PLATFORM_INFO_SYSCLK_VALUE              #language en-US "0MHz"
+
+#string STR_PLATFORM_INFO_AHBCLK                    #language en-US "AHB Clock"
+#string STR_PLATFORM_INFO_AHBCLK_VALUE              #language en-US "0MHz"
+
+#string STR_CPU_FORM_INTER_SOCKET_LINK0             #language en-US "Inter Socket Connection: Link 0"
+#string STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE       #language en-US ""
+#string STR_CPU_FORM_INTER_SOCKET_LINK1             #language en-US "Inter Socket Connection: Link 1"
+#string STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE       #language en-US ""
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (22 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:14   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
                   ` (10 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provide memory screen with below info:
* Memory total capacity
* Memory RAS and Performance Configuration
* Per DIMM Information

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Platform/Ampere/JadePkg/Jade.dsc                                          |    1 +
 Platform/Ampere/JadePkg/Jade.fdf                                          |    1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf           |   59 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h          |  168 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h            |   47 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr                  |   62 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c        |  394 ++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c          | 1325 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni           |    9 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni      |    9 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni |   64 +
 11 files changed, 2139 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index b5edb673abba..75b3ece3817e 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -179,3 +179,4 @@ [Components.common]
   # HII
   #
   Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 6dd759322d9d..e71f3e79e6b3 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -354,5 +354,6 @@ [FV.FvMain]
   # HII
   #
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
new file mode 100644
index 000000000000..2328051c6e1a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = MemInfoDxe
+  MODULE_UNI_FILE                = MemInfoDxe.uni
+  FILE_GUID                      = D9EFCEFE-189B-4599-BB07-04F0A8DF5C2F
+  MODULE_TYPE                    = DXE_DRIVER
+  ENTRY_POINT                    = MemInfoScreenInitialize
+
+[Sources]
+  MemInfoNvramLib.c
+  MemInfoScreen.c
+  MemInfoScreen.h
+  MemInfoScreenStrings.uni
+  NVDataStruc.h
+  Vfr.vfr
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  DevicePathLib
+  HiiLib
+  HobLib
+  MemoryAllocationLib
+  NVParamLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gEfiIfrTianoGuid                              ## PRODUCES ## UNDEFINED
+  gPlatformManagerFormsetGuid
+  gPlatformHobGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+
+[Depex]
+  TRUE
+
+[UserExtensions.TianoCore."ExtraFiles"]
+  MemInfoDxeExtra.uni
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
new file mode 100644
index 000000000000..546f554f8fb2
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
@@ -0,0 +1,168 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef MEM_INFO_SCREEN_H_
+#define MEM_INFO_SCREEN_H_
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigKeyword.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+
+#include "NVDataStruc.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 MemInfoDxeStrings[];
+
+enum DDR_ECC_MODE {
+  ECC_DISABLE = 0,
+  ECC_SECDED,
+  SYMBOL_ECC
+};
+
+enum DDR_ERROR_CTRL_MODE_DE {
+  ERRCTLR_DE_DISABLE = 0,
+  ERRCTLR_DE_ENABLE,
+};
+
+enum DDR_ERROR_CTRL_MODE_FI {
+  ERRCTLR_FI_DISABLE = 0,
+  ERRCTLR_FI_ENABLE,
+};
+
+#define MEM_INFO_DDR_SPEED_SEL_OFFSET                     OFFSET_OF (MEM_INFO_VARSTORE_DATA, DDRSpeedSel)
+#define MEM_INFO_ECC_MODE_SEL_OFFSET                      OFFSET_OF (MEM_INFO_VARSTORE_DATA, EccMode)
+#define MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET              OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_DE)
+#define MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET              OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_FI)
+#define MEM_INFO_ERR_SLAVE_32BIT_OFFSET                   OFFSET_OF (MEM_INFO_VARSTORE_DATA, Slave32bit)
+#define MEM_INFO_DDR_SCRUB_OFFSET                         OFFSET_OF (MEM_INFO_VARSTORE_DATA, ScrubPatrol)
+#define MEM_INFO_DDR_DEMAND_SCRUB_OFFSET                  OFFSET_OF (MEM_INFO_VARSTORE_DATA, DemandScrub)
+#define MEM_INFO_DDR_WRITE_CRC_OFFSET                     OFFSET_OF (MEM_INFO_VARSTORE_DATA, WriteCrc)
+#define MEM_INFO_FGR_MODE_OFFSET                          OFFSET_OF (MEM_INFO_VARSTORE_DATA, FGRMode)
+#define MEM_INFO_REFRESH2X_MODE_OFFSET                    OFFSET_OF (MEM_INFO_VARSTORE_DATA, Refresh2x)
+#define MEM_INFO_NVDIMM_MODE_SEL_OFFSET                   OFFSET_OF (MEM_INFO_VARSTORE_DATA, NvdimmModeSel)
+
+#define MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE            SIGNATURE_32 ('M', 'E', 'M', 'i')
+
+#define MEM_INFO_DDR_SPEED_SEL_QUESTION_ID                       0x8001
+#define MEM_INFO_FORM_PERFORMANCE_QUESTION_ID                    0x8002
+#define MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID                0x8003
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID        0x8004
+#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID        0x8005
+#define MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID                     0x8006
+#define MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID                    0x8007
+#define MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID                    0x8008
+#define MEM_INFO_DDR_WRITE_CRC_QUESTION_ID                       0x8009
+#define MEM_INFO_FGR_MODE_QUESTION_ID                            0x800A
+#define MEM_INFO_REFRESH2X_MODE_QUESTION_ID                      0x800B
+#define MEM_INFO_FORM_NVDIMM_QUESTION_ID                         0x800C
+#define MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID                0x800D
+
+#define DDR_DEFAULT_SCRUB_PATROL_DURATION 24
+#define DDR_DEFAULT_DEMAND_SCRUB          1
+#define DDR_DEFAULT_WRITE_CRC             0
+#define DDR_DEFAULT_FGR_MODE              0
+#define DDR_DEFAULT_REFRESH2X_MODE        0
+#define DDR_DEFAULT_NVDIMM_MODE_SEL       3
+
+#define DDR_FGR_MODE_GET(Value)           ((Value) & 0x3) /* Bit 0, 1 */
+#define DDR_FGR_MODE_SET(Dst, Src)        do { Dst = (((Dst) & ~0x3) | ((Src) & 0x3)); } while (0)
+
+#define DDR_REFRESH_2X_GET(Value)         ((Value) & 0x10000) >> 16 /* Bit 16 only */
+#define DDR_REFRESH_2X_SET(Dst, Src)      do { Dst = (((Dst) & ~0x10000) | ((Src) & 0x1) << 16); } while (0)
+
+#define DDR_NVDIMM_MODE_SEL_MASK         0x7FFFFFFF
+#define DDR_NVDIMM_MODE_SEL_VALID_BIT    BIT31
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE             DriverHandle;
+  EFI_HII_HANDLE         HiiHandle;
+  MEM_INFO_VARSTORE_DATA VarStoreConfig;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
+  EFI_HII_STRING_PROTOCOL             *HiiString;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
+  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+  EFI_FORM_BROWSER2_PROTOCOL          *FormBrowser2;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} MEM_INFO_SCREEN_PRIVATE_DATA;
+
+#define MEM_INFO_SCREEN_PRIVATE_FROM_THIS(a)  CR (a, MEM_INFO_SCREEN_PRIVATE_DATA, ConfigAccess, MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+EFI_STATUS
+MemInfoScreenInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  );
+
+EFI_STATUS
+MemInfoScreenUnload (
+  IN EFI_HANDLE ImageHandle
+  );
+
+EFI_STATUS
+MemInfoNvparamGet (
+  OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+  );
+
+EFI_STATUS
+MemInfoNvparamSet (
+  IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+  );
+
+#endif /* MEM_INFO_SCREEN_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
new file mode 100644
index 000000000000..7a6e776e7f4e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
@@ -0,0 +1,47 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVDATASTRUC_H_
+#define NVDATASTRUC_H_
+
+#define MEM_INFO_VARSTORE_NAME        L"MemInfoIfrNVData"
+#define MEM_INFO_VARSTORE_ID          0x1234
+#define MEM_INFO_FORM_ID              0x1235
+#define MEM_INFO_FORM_PERFORMANCE_ID  0x1236
+#define MEM_INFO_FORM_NVDIMM_ID       0x1237
+#define MEM_INFO_FORM_SET_GUID                    { 0xd58338ee, 0xe9f7, 0x4d8d, { 0xa7, 0x08, 0xdf, 0xb2, 0xc6, 0x66, 0x1d, 0x61 } }
+#define MEM_INFO_FORM_SET_PERFORMANCE_GUID        { 0x4a072c78, 0x42f9, 0x11ea, { 0xb7, 0x7f, 0x2e, 0x28, 0xce, 0x88, 0x12, 0x62 } }
+
+#pragma pack(1)
+
+//
+// NV data structure definition
+//
+typedef struct {
+  UINT32 DDRSpeedSel;
+  UINT32 EccMode;
+  UINT32 ErrCtrl_DE;
+  UINT32 ErrCtrl_FI;
+  UINT32 Slave32bit;
+  UINT32 ScrubPatrol;
+  UINT32 DemandScrub;
+  UINT32 WriteCrc;
+  UINT32 FGRMode;
+  UINT32 Refresh2x;
+  UINT32 NvdimmModeSel;
+} MEM_INFO_VARSTORE_DATA;
+
+//
+// Labels definition
+//
+#define LABEL_UPDATE             0x2223
+#define LABEL_END                0x2224
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
new file mode 100644
index 000000000000..6c7ccb7375d0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
@@ -0,0 +1,62 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformManagerHii.h>
+#include "NVDataStruc.h"
+
+formset
+  guid    = MEM_INFO_FORM_SET_GUID,
+  title   = STRING_TOKEN(STR_MEM_INFO_FORM),
+  help    = STRING_TOKEN(STR_MEM_INFO_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  //
+  // Define a variable Storage
+  //
+  varstore MEM_INFO_VARSTORE_DATA,
+    varid = MEM_INFO_VARSTORE_ID,
+    name  = MemInfoIfrNVData,
+    guid  = MEM_INFO_FORM_SET_GUID;
+
+  form
+    formid = MEM_INFO_FORM_ID,
+    title = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+    subtitle text = STRING_TOKEN(STR_MEM_INFO_FORM);
+
+    label LABEL_UPDATE;
+    // dynamic content here
+    label LABEL_END;
+
+  endform;
+
+  form
+    formid = MEM_INFO_FORM_PERFORMANCE_ID,
+    title = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+    subtitle text = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
+
+    label LABEL_UPDATE;
+    // dynamic content here
+    label LABEL_END;
+
+  endform;
+
+  form
+    formid = MEM_INFO_FORM_NVDIMM_ID,
+    title = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+    subtitle text = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
+
+    label LABEL_UPDATE;
+    // dynamic content here
+    label LABEL_END;
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
new file mode 100644
index 000000000000..c83f489f4078
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
@@ -0,0 +1,394 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/NVParamLib.h>
+
+#include "MemInfoScreen.h"
+#include "NVParamDef.h"
+
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT    0
+#define DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK     0x1
+
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT    1
+#define DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK     0x2
+
+/**
+  This is function collects meminfo from NVParam
+
+  @param  Data                  The buffer to return the contents.
+
+  @retval EFI_SUCCESS           Get response data successfully.
+  @retval Other value           Failed to get meminfo from NVParam
+**/
+EFI_STATUS
+MemInfoNvparamGet (
+  OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
+  )
+{
+  UINT32     Value;
+  EFI_STATUS Status;
+
+  ASSERT (VarStoreConfig != NULL);
+
+  Status = NVParamGet (
+             NV_SI_DDR_SPEED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->DDRSpeedSel = 0; /* Default auto mode */
+  } else {
+    VarStoreConfig->DDRSpeedSel = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_ECC_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->EccMode = ECC_SECDED; /* Default enable */
+  } else {
+    VarStoreConfig->EccMode = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_ERRCTRL,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->ErrCtrl_DE = ERRCTLR_DE_ENABLE;
+    VarStoreConfig->ErrCtrl_FI = ERRCTLR_FI_ENABLE;
+  } else {
+    VarStoreConfig->ErrCtrl_DE = (Value & DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT;
+    VarStoreConfig->ErrCtrl_FI = (Value & DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->Slave32bit = 0; /* Default disabled */
+  } else {
+    VarStoreConfig->Slave32bit = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_SCRUB_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->ScrubPatrol = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+  } else {
+    VarStoreConfig->ScrubPatrol = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_WR_BACK_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->DemandScrub = DDR_DEFAULT_DEMAND_SCRUB;
+  } else {
+    VarStoreConfig->DemandScrub = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_CRC_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->WriteCrc = DDR_DEFAULT_WRITE_CRC;
+  } else {
+    VarStoreConfig->WriteCrc = Value;
+  }
+
+  Status = NVParamGet (
+             NV_SI_DDR_REFRESH_GRANULARITY,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->FGRMode = DDR_DEFAULT_FGR_MODE;
+    VarStoreConfig->Refresh2x = DDR_DEFAULT_REFRESH2X_MODE;
+  } else {
+    VarStoreConfig->FGRMode = DDR_FGR_MODE_GET (Value);
+    VarStoreConfig->Refresh2x = DDR_REFRESH_2X_GET (Value);
+  }
+
+  Status = NVParamGet (
+             NV_SI_NVDIMM_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->NvdimmModeSel = DDR_DEFAULT_NVDIMM_MODE_SEL;
+  } else {
+    VarStoreConfig->NvdimmModeSel = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This is function stores meminfo to corresponding NVParam
+
+  @param  VarStoreConfig         The contents for the variable.
+
+  @retval EFI_SUCCESS            Set data successfully.
+  @retval Other value            Failed to set meminfo to NVParam
+
+**/
+EFI_STATUS
+MemInfoNvparamSet (
+  IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value, TmpValue, Value2, Update;
+
+  ASSERT (VarStoreConfig != NULL);
+
+  /* Set DDR speed */
+  Status = NVParamGet (
+             NV_SI_DDR_SPEED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != VarStoreConfig->DDRSpeedSel) {
+    Status = NVParamSet (
+               NV_SI_DDR_SPEED,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               VarStoreConfig->DDRSpeedSel
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Set ECC mode */
+  Status = NVParamGet (
+             NV_SI_DDR_ECC_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != VarStoreConfig->EccMode) {
+    Status = NVParamSet (
+               NV_SI_DDR_ECC_MODE,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               VarStoreConfig->EccMode
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Set ErrCtrl */
+  TmpValue = (VarStoreConfig->ErrCtrl_DE << DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT) |
+             (VarStoreConfig->ErrCtrl_FI << DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT);
+  Status = NVParamGet (
+             NV_SI_DDR_ERRCTRL,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != TmpValue ) {
+    Status = NVParamSet (
+               NV_SI_DDR_ERRCTRL,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               TmpValue
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Set slave's 32bit region */
+  TmpValue = VarStoreConfig->Slave32bit;
+  Status = NVParamGet (
+             NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != TmpValue ) {
+    if (TmpValue == 0) {
+      /* Default is disabled so just clear nvparam */
+      Status = NVParamClr (
+                 NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+                 );
+    } else {
+      Status = NVParamSet (
+                 NV_SI_DDR_SLAVE_32BIT_MEM_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 TmpValue
+                 );
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Set Scrub patrol */
+  TmpValue = VarStoreConfig->ScrubPatrol;
+  Status = NVParamGet (
+             NV_SI_DDR_SCRUB_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != TmpValue ) {
+    if (TmpValue == DDR_DEFAULT_SCRUB_PATROL_DURATION) {
+      Status = NVParamClr (
+                 NV_SI_DDR_SCRUB_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+                 );
+    } else {
+      Status = NVParamSet (
+                 NV_SI_DDR_SCRUB_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 TmpValue
+                 );
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Demand Scrub */
+  TmpValue = VarStoreConfig->DemandScrub;
+  Status = NVParamGet (
+             NV_SI_DDR_WR_BACK_EN,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != TmpValue ) {
+    if (TmpValue == DDR_DEFAULT_DEMAND_SCRUB) {
+      Status = NVParamClr (
+                 NV_SI_DDR_WR_BACK_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
+                 );
+    } else {
+      Status = NVParamSet (
+                 NV_SI_DDR_WR_BACK_EN,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 TmpValue
+                 );
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Write CRC */
+  TmpValue = VarStoreConfig->WriteCrc;
+  Status = NVParamGet (
+             NV_SI_DDR_CRC_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status) || Value != TmpValue ) {
+    if (TmpValue == DDR_DEFAULT_WRITE_CRC) {
+      Status = NVParamClr (
+                 NV_SI_DDR_CRC_MODE,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+                 );
+    } else {
+      Status = NVParamSet (
+                 NV_SI_DDR_CRC_MODE,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 TmpValue
+                 );
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Write FGR/Refresh2X */
+  Value = 0;
+  Update = 0;
+  TmpValue = VarStoreConfig->FGRMode;
+  Status = NVParamGet (
+             NV_SI_DDR_REFRESH_GRANULARITY,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  Value2 = DDR_FGR_MODE_GET (Value);
+  if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_FGR_MODE)
+      || Value2 != TmpValue)
+  {
+    DDR_FGR_MODE_SET (Value, TmpValue);
+    Update = 1;
+  }
+
+  Value2 = DDR_REFRESH_2X_GET (Value);
+  TmpValue = VarStoreConfig->Refresh2x;
+  if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_REFRESH2X_MODE)
+      || Value2 != TmpValue)
+  {
+    DDR_REFRESH_2X_SET (Value, TmpValue);
+    Update = 1;
+  }
+
+  if (Update == 1) {
+    Status = NVParamSet (
+               NV_SI_DDR_REFRESH_GRANULARITY,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  /* Write NVDIMM-N Mode selection */
+  Value = 0;
+  TmpValue = VarStoreConfig->NvdimmModeSel;
+  Status = NVParamGet (
+             NV_SI_NVDIMM_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  Value2 = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
+  if (EFI_ERROR (Status) || Value2 != TmpValue ) {
+    if (TmpValue == DDR_DEFAULT_NVDIMM_MODE_SEL) {
+      Status = NVParamClr (
+                 NV_SI_NVDIMM_MODE,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
+                 );
+    } else {
+      Value = TmpValue | DDR_NVDIMM_MODE_SEL_VALID_BIT; /* Add valid bit */
+      Status = NVParamSet (
+                 NV_SI_NVDIMM_MODE,
+                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+                 NV_PERM_BIOS | NV_PERM_MANU,
+                 Value
+                 );
+    }
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
new file mode 100644
index 000000000000..75f743b824e0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
@@ -0,0 +1,1325 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MemInfoScreen.h"
+
+#define MAX_STRING_SIZE     64
+#define GB_SCALE_FACTOR     (1024*1024*1024)
+#define MB_SCALE_FACTOR     (1024*1024)
+
+EFI_GUID gMemInfoFormSetGuid = MEM_INFO_FORM_SET_GUID;
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    MEM_INFO_FORM_SET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+EFI_HANDLE                   DriverHandle = NULL;
+MEM_INFO_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Request,
+  OUT      EFI_STRING                     *Progress,
+  OUT      EFI_STRING                     *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  MEM_INFO_SCREEN_PRIVATE_DATA    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  CHAR16                          *StrPointer;
+  BOOLEAN                         AllocatedRequest;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+  //
+  // Get Buffer Storage data from EFI variable.
+  // Try to get the current setting from variable.
+  //
+  BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  if (Request == NULL) {
+    //
+    // Request is set to NULL, construct full request string.
+    //
+
+    //
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (&gMemInfoFormSetGuid, MEM_INFO_VARSTORE_NAME, PrivateData->DriverHandle);
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+    ConfigRequestHdr = NULL;
+  } else {
+    //
+    // Check routing data in <ConfigHdr>.
+    // Note: if only one Storage is used, then this checking could be skipped.
+    //
+    if (!HiiIsConfigHdrMatch (Request, &gMemInfoFormSetGuid, NULL)) {
+      return EFI_NOT_FOUND;
+    }
+
+    //
+    // Set Request to the unified request string.
+    //
+    ConfigRequest = Request;
+
+    //
+    // Check whether Request includes Request Element.
+    //
+    if (StrStr (Request, L"OFFSET") == NULL) {
+      //
+      // Check Request Element does exist in Request String
+      //
+      StrPointer = StrStr (Request, L"PATH");
+      if (StrPointer == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      if (StrStr (StrPointer, L"&") == NULL) {
+        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
+        ConfigRequest    = AllocateZeroPool (Size);
+        ASSERT (ConfigRequest != NULL);
+        AllocatedRequest = TRUE;
+        UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
+      }
+    }
+  }
+
+  //
+  // Check if requesting Name/Value storage
+  //
+  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    Status = EFI_SUCCESS;
+  } else {
+    //
+    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+    //
+    Status = HiiConfigRouting->BlockToConfig (
+                                 HiiConfigRouting,
+                                 ConfigRequest,
+                                 (UINT8 *)&PrivateData->VarStoreConfig,
+                                 BufferSize,
+                                 Results,
+                                 Progress
+                                 );
+  }
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+  }
+
+  if (ConfigRequestHdr != NULL) {
+    FreePool (ConfigRequestHdr);
+  }
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Configuration,
+  OUT      EFI_STRING                     *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  MEM_INFO_SCREEN_PRIVATE_DATA    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &gMemInfoFormSetGuid, NULL)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get Buffer Storage data from NVParam
+  //
+  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Check if configuring Name/Value storage
+  //
+  if (StrStr (Configuration, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)&PrivateData->VarStoreConfig,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store Buffer Storage back to NVParam
+  //
+  Status = MemInfoNvparamSet (&PrivateData->VarStoreConfig);
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+  @retval EFI_SUCCESS            The callback successfully handled the action.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
+                                 callback.
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+      || (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  switch (Action) {
+  case EFI_BROWSER_ACTION_FORM_OPEN:
+  case EFI_BROWSER_ACTION_FORM_CLOSE:
+    break;
+
+  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
+  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
+  {
+    switch (QuestionId) {
+    case MEM_INFO_DDR_SPEED_SEL_QUESTION_ID:
+      //
+      // DDR speed selection default to auto
+      //
+      Value->u32 = 0;
+      break;
+
+    case MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID:
+      //
+      // ECC mode default to be enabled
+      //
+      Value->u32 = ECC_SECDED;
+      break;
+
+    case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID:
+      //
+      // ErrCtrl_DE default to be enabled
+      //
+      Value->u32 = ERRCTLR_DE_ENABLE;
+      break;
+
+    case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID:
+      //
+      // ErrCtrl_FI default to be enabled
+      //
+      Value->u32 = ERRCTLR_FI_ENABLE;
+      break;
+
+    case MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID:
+      //
+      // Slave's 32bit region to be disabled
+      //
+      Value->u32 = 0;
+      break;
+
+    case MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_SCRUB_PATROL_DURATION;
+      break;
+
+    case MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_DEMAND_SCRUB;
+      break;
+
+    case MEM_INFO_DDR_WRITE_CRC_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_WRITE_CRC;
+      break;
+
+    case MEM_INFO_FGR_MODE_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_FGR_MODE;
+      break;
+
+    case MEM_INFO_REFRESH2X_MODE_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_REFRESH2X_MODE;
+      break;
+
+    case MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID:
+      Value->u32 = DDR_DEFAULT_NVDIMM_MODE_SEL;
+      break;
+    }
+  }
+  break;
+
+  case EFI_BROWSER_ACTION_RETRIEVE:
+  case EFI_BROWSER_ACTION_CHANGING:
+  case EFI_BROWSER_ACTION_SUBMITTED:
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoMainScreen (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+  EFI_STATUS                   Status;
+  VOID                         *StartOpCodeHandle;
+  VOID                         *OptionsOpCodeHandle;
+  VOID                         *OptionsOpCodeHandle1;
+  EFI_IFR_GUID_LABEL           *StartLabel;
+  EFI_STRING_ID                StringId;
+  VOID                         *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL           *EndLabel;
+  CHAR16                       Str[MAX_STRING_SIZE], Str1[MAX_STRING_SIZE];
+  EFI_HOB_RESOURCE_DESCRIPTOR  *ResHob;
+  PLATFORM_DIMM_INFO           *DimmInfo;
+  UINT64                       Size;
+  UINTN                        Count;
+
+  //
+  // Get Buffer Storage data from EFI variable
+  //
+  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = EFI_SUCCESS;
+
+  /* Update Total memory */
+  UnicodeSPrint (Str, sizeof (Str), L"%d GB", PlatformHob->DramInfo.TotalSize / GB_SCALE_FACTOR);
+  HiiSetString (
+    PrivateData->HiiHandle,
+    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE),
+    Str,
+    NULL
+    );
+
+  /* Update effective memory */
+  Size = 0;
+  ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+  while (ResHob != NULL) {
+    if ((ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)) {
+      Size += ResHob->ResourceLength;
+    }
+    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
+  }
+  UnicodeSPrint (Str, sizeof (Str), L"%d GB", Size / GB_SCALE_FACTOR);
+  HiiSetString (
+    PrivateData->HiiHandle,
+    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE),
+    Str,
+    NULL
+    );
+
+  /* Update current DDR speed */
+  UnicodeSPrint (Str, sizeof (Str), L"%d MHz", PlatformHob->DramInfo.MaxSpeed);
+  HiiSetString (
+    PrivateData->HiiHandle,
+    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE),
+    Str,
+    NULL
+    );
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Option OpCode to display speed configuration
+  //
+  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (OptionsOpCodeHandle != NULL);
+
+  //
+  // Create Option OpCode to display FGR mode configuration
+  //
+  OptionsOpCodeHandle1 = HiiAllocateOpCodeHandle ();
+  ASSERT (OptionsOpCodeHandle1 != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  //
+  // Create a total mem title
+  //
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
+    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE)
+    );
+
+  //
+  // Create a effective mem title
+  //
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
+    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE)
+    );
+
+  //
+  // Create a current speed title
+  //
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
+    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE)
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE0),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    0
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE1),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2133
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE2),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2400
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE3),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2666
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE4),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2933
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE5),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    3200
+    );
+
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_DDR_SPEED_SEL_QUESTION_ID,                  // Question ID (or call it "key")
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_DDR_SPEED_SEL_OFFSET,               // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_PROMPT),     // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_HELP),       // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
+    OptionsOpCodeHandle,                                 // Option Opcode list
+    NULL                                                 // Default Opcode is NULl
+    );
+
+  if (IsSlaveSocketActive ()) {
+    /* Display enable slave's 32bit region */
+    HiiCreateCheckBoxOpCode (
+      StartOpCodeHandle,                                    // Container for dynamic created opcodes
+      MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID,                 // Question ID
+      MEM_INFO_VARSTORE_ID,                                 // VarStore ID
+      (UINT16)MEM_INFO_ERR_SLAVE_32BIT_OFFSET,              // Offset in Buffer Storage
+      STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT), // Question prompt text
+      STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP),   // Question help text
+      EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+      0,
+      NULL
+      );
+  }
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle1,
+    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE0),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    0
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle1,
+    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE1),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    1
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle1,
+    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE2),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2
+    );
+
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_FGR_MODE_QUESTION_ID,                       // Question ID (or call it "key")
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_FGR_MODE_OFFSET,                    // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_PROMPT),         // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_HELP),           // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
+    OptionsOpCodeHandle1,                                // Option Opcode list
+    NULL                                                 // Default Opcode is NULl
+    );
+
+  //
+  // Create a Goto OpCode to ras memory configuration
+  //
+  HiiCreateGotoOpCode (
+    StartOpCodeHandle,                                 // Container for dynamic created opcodes
+    MEM_INFO_FORM_PERFORMANCE_ID,                      // Target Form ID
+    STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM),      // Prompt text
+    STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM_HELP), // Help text
+    0,                                                 // Question flag
+    MEM_INFO_FORM_PERFORMANCE_QUESTION_ID              // Question ID
+    );
+
+  //
+  // Create a Goto OpCode to nvdimm-n configuration
+  //
+  HiiCreateGotoOpCode (
+    StartOpCodeHandle,                            // Container for dynamic created opcodes
+    MEM_INFO_FORM_NVDIMM_ID,                      // Target Form ID
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM),      // Prompt text
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM_HELP), // Help text
+    0,                                            // Question flag
+    MEM_INFO_FORM_NVDIMM_QUESTION_ID              // Question ID
+    );
+
+  //
+  // Display DIMM list info
+  //
+  HiiCreateSubTitleOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_DIMM_INFO),
+    0,
+    0,
+    0
+    );
+
+  for (Count = 0; Count < PlatformHob->DimmList.BoardDimmSlots; Count++) {
+    DimmInfo = &PlatformHob->DimmList.Dimm[Count].Info;
+    switch (DimmInfo->DimmType) {
+    case UDIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"UDIMM");
+      break;
+
+    case RDIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"RDIMM");
+      break;
+
+    case SODIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"SODIMM");
+      break;
+
+    case LRDIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"LRDIMM");
+      break;
+
+    case RSODIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"RSODIMM");
+      break;
+
+    case NVRDIMM:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"NV-RDIMM");
+      break;
+
+    default:
+      UnicodeSPrint (Str, sizeof (Str), L"Unknown Type");
+    }
+    if (DimmInfo->DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
+      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: %d GB %s Installed&Operational", Count + 1, DimmInfo->DimmSize, Str);
+    } else if (DimmInfo->DimmStatus == DIMM_NOT_INSTALLED) {
+      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Not Installed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+    } else if (DimmInfo->DimmStatus == DIMM_INSTALLED_NONOPERATIONAL) {
+      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Non-Operational", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+    } else {
+      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Failed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
+    }
+
+    StringId = HiiSetString (PrivateData->HiiHandle, 0, Str1, NULL);
+
+    HiiCreateSubTitleOpCode (
+      StartOpCodeHandle,
+      StringId,
+      0,
+      0,
+      0
+      );
+  }
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,  // HII handle
+    &gMemInfoFormSetGuid,    // Formset GUID
+    MEM_INFO_FORM_ID,        // Form ID
+    StartOpCodeHandle,       // Label for where to insert opcodes
+    EndOpCodeHandle          // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+  return Status;
+}
+
+EFI_STATUS
+MemInfoMainPerformanceScreen (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  EFI_STATUS                   Status;
+  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
+  VOID                         *StartOpCodeHandle;
+  VOID                         *OptionsEccOpCodeHandle, *OptionsScrubOpCodeHandle;
+  EFI_IFR_GUID_LABEL           *StartLabel;
+  VOID                         *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL           *EndLabel;
+  EFI_STRING_ID                StringId;
+  CHAR16                       Str[MAX_STRING_SIZE];
+  UINTN                        Idx;
+
+  Status = EFI_SUCCESS;
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  /* Display ECC mode selection */
+  OptionsEccOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (OptionsEccOpCodeHandle != NULL);
+
+  UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsEccOpCodeHandle,
+    StringId,
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    0
+    );
+
+  UnicodeSPrint (Str, sizeof (Str), L"SECDED");
+  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsEccOpCodeHandle,
+    StringId,
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    1
+    );
+
+  UnicodeSPrint (Str, sizeof (Str), L"Symbol");
+  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsEccOpCodeHandle,
+    StringId,
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2
+    );
+
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID,           // Question ID (or call it "key")
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_ECC_MODE_SEL_OFFSET,                // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_PROMPT),       // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_HELP),         // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
+    OptionsEccOpCodeHandle,                              // Option Opcode list
+    NULL                                                 // Default Opcode is NULl
+    );
+
+  /*
+   * Display ErrCtrl options
+   */
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                                    // Container for dynamic created opcodes
+    MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID,    // Question ID
+    MEM_INFO_VARSTORE_ID,                                 // VarStore ID
+    (UINT16)MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET,         // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                                    // Container for dynamic created opcodes
+    MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID,    // Question ID
+    MEM_INFO_VARSTORE_ID,                                 // VarStore ID
+    (UINT16)MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET,         // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  /* Display Scrub Patrol selection */
+  OptionsScrubOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (OptionsScrubOpCodeHandle != NULL);
+
+  UnicodeSPrint (Str, sizeof (Str), L"Disabled");
+  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsScrubOpCodeHandle,
+    StringId,
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    0
+    );
+
+  for (Idx = 1; Idx <= 24; Idx++) {
+    UnicodeSPrint (Str, sizeof (Str), L"%d", Idx);
+    StringId = HiiSetString (
+                 PrivateData->HiiHandle,
+                 0,
+                 Str,
+                 NULL
+                 );
+    HiiCreateOneOfOptionOpCode (
+      OptionsScrubOpCodeHandle,
+      StringId,
+      0,
+      EFI_IFR_NUMERIC_SIZE_4,
+      Idx
+      );
+  }
+
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID,               // Question ID (or call it "key")
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_DDR_SCRUB_OFFSET,                   // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB),            // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB_HELP),       // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
+    OptionsScrubOpCodeHandle,                            // Option Opcode list
+    NULL                                                 // Default Opcode is NULl
+    );
+
+  /*
+   * Display Demand Scrub options
+   */
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                                      // Container for dynamic created opcodes
+    MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID,                  // Question ID
+    MEM_INFO_VARSTORE_ID,                                   // VarStore ID
+    (UINT16)MEM_INFO_DDR_DEMAND_SCRUB_OFFSET,               // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  /*
+   * Display Write CRC options
+   */
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_DDR_WRITE_CRC_QUESTION_ID,                  // Question ID
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_DDR_WRITE_CRC_OFFSET,               // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  /*
+   * Display CVE-2020-10255 options
+   */
+  HiiCreateCheckBoxOpCode (
+    StartOpCodeHandle,                                 // Container for dynamic created opcodes
+    MEM_INFO_REFRESH2X_MODE_QUESTION_ID,               // Question ID
+    MEM_INFO_VARSTORE_ID,                              // VarStore ID
+    (UINT16)MEM_INFO_REFRESH2X_MODE_OFFSET,            // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_HELP),   // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    0,
+    NULL
+    );
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,              // HII handle
+    &gMemInfoFormSetGuid,                // Formset GUID
+    MEM_INFO_FORM_PERFORMANCE_ID,        // Form ID
+    StartOpCodeHandle,                   // Label for where to insert opcodes
+    EndOpCodeHandle                      // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+  HiiFreeOpCodeHandle (OptionsEccOpCodeHandle);
+  HiiFreeOpCodeHandle (OptionsScrubOpCodeHandle);
+
+  return Status;
+}
+
+EFI_STATUS
+MemInfoMainNvdimmScreen (
+  PLATFORM_INFO_HOB  *PlatformHob
+  )
+{
+  EFI_STATUS                   Status;
+  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
+  VOID                         *StartOpCodeHandle;
+  VOID                         *OptionsOpCodeHandle;
+  EFI_IFR_GUID_LABEL           *StartLabel;
+  VOID                         *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL           *EndLabel;
+  CHAR16                       Str[MAX_STRING_SIZE];
+
+  Status = EFI_SUCCESS;
+  PrivateData = mPrivateData;
+
+  if (PlatformHob == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  //
+  // Update Current NVDIMM-N Mode title Socket0
+  //
+  switch (PlatformHob->DramInfo.NvdimmMode[0]) {
+  case 0:
+    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+    break;
+
+  case 1:
+    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+    break;
+
+  case 2:
+    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+    break;
+
+  default:
+    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+    break;
+  }
+
+  HiiSetString (
+    PrivateData->HiiHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE),
+    Str,
+    NULL
+    );
+
+  HiiCreateTextOpCode (
+    StartOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE)
+    );
+
+  //
+  // Update Current NVDIMM-N Mode title Socket1
+  //
+  if (IsSlaveSocketActive ()) {
+    switch (PlatformHob->DramInfo.NvdimmMode[1]) {
+    case 0:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
+      break;
+
+    case 1:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
+      break;
+
+    case 2:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
+      break;
+
+    default:
+      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
+      break;
+    }
+
+    HiiSetString (
+      PrivateData->HiiHandle,
+      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE),
+      Str,
+      NULL
+      );
+
+    HiiCreateTextOpCode (
+      StartOpCodeHandle,
+      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
+      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE)
+      );
+  }
+  //
+  // Create Option OpCode to NVDIMM-N Mode Selection
+  //
+  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (OptionsOpCodeHandle != NULL);
+
+  //
+  // Create OpCode to NVDIMM-N Mode Selection
+  //
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    0
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    1
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    2
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    OptionsOpCodeHandle,
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3),
+    0,
+    EFI_IFR_NUMERIC_SIZE_4,
+    3
+    );
+
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                                   // Container for dynamic created opcodes
+    MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID,           // Question ID (or call it "key")
+    MEM_INFO_VARSTORE_ID,                                // VarStore ID
+    (UINT16)MEM_INFO_NVDIMM_MODE_SEL_OFFSET,             // Offset in Buffer Storage
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT),  // Question prompt text
+    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_HELP),    // Question help text
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
+    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
+    OptionsOpCodeHandle,                                 // Option Opcode list
+    NULL                                                 // Default Opcode is NULl
+    );
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,              // HII handle
+    &gMemInfoFormSetGuid,                // Formset GUID
+    MEM_INFO_FORM_NVDIMM_ID,             // Form ID
+    StartOpCodeHandle,                   // Label for where to insert opcodes
+    EndOpCodeHandle                      // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
+
+  return Status;
+}
+
+/**
+  This function sets up the first elements of the form.
+  @param  PrivateData            Private data.
+  @retval EFI_SUCCESS            The form is set up successfully.
+**/
+EFI_STATUS
+MemInfoScreenSetup (
+  VOID
+  )
+{
+  EFI_STATUS         Status;
+  VOID               *Hob;
+  PLATFORM_INFO_HOB  *PlatformHob;
+
+  /* Get the Platform HOB */
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  if (Hob == NULL) {
+    return EFI_DEVICE_ERROR;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  Status = MemInfoMainScreen (PlatformHob);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = MemInfoMainPerformanceScreen (PlatformHob);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = MemInfoMainNvdimmScreen (PlatformHob);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  BOOLEAN                         ActionFlag;
+  EFI_STRING                      ConfigRequestHdr;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (MEM_INFO_SCREEN_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
+  mPrivateData->ConfigAccess.Callback = DriverCallback;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = DriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gMemInfoFormSetGuid,
+                DriverHandle,
+                MemInfoDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  //
+  // Try to read NV config EFI variable first
+  //
+  ConfigRequestHdr = HiiConstructConfigHdr (
+                       &gMemInfoFormSetGuid,
+                       MEM_INFO_VARSTORE_NAME,
+                       DriverHandle
+                       );
+  ASSERT (ConfigRequestHdr != NULL);
+
+  //
+  // Validate Current Setting
+  //
+  ActionFlag = HiiValidateSettings (ConfigRequestHdr);
+  if (!ActionFlag) {
+    MemInfoScreenUnload (ImageHandle);
+    return EFI_INVALID_PARAMETER;
+  }
+  FreePool (ConfigRequestHdr);
+
+  Status = MemInfoScreenSetup ();
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MemInfoScreenUnload (
+  IN EFI_HANDLE ImageHandle
+  )
+{
+  ASSERT (mPrivateData != NULL);
+
+  if (DriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           DriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    DriverHandle = NULL;
+  }
+
+  if (mPrivateData->HiiHandle != NULL) {
+    HiiRemovePackages (mPrivateData->HiiHandle);
+  }
+
+  FreePool (mPrivateData);
+  mPrivateData = NULL;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
new file mode 100644
index 000000000000..a8c7cb99d6a7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_MODULE_ABSTRACT             #language en-US "An Altra DDR screen setup driver"
+
+#string STR_MODULE_DESCRIPTION          #language en-US "This driver exposes a screen setup for DDR information and configuration."
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
new file mode 100644
index 000000000000..f44f210594be
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
@@ -0,0 +1,9 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"Ampere Altra MemInfo DXE Driver"
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
new file mode 100644
index 000000000000..d170f9ee7313
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
@@ -0,0 +1,64 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef   en-US "English"    // English
+
+#string STR_MEM_INFO_FORM                   #language en-US "Memory Configuration"
+#string STR_MEM_INFO_FORM_HELP              #language en-US "Memory Configuration"
+#string STR_MEM_INFO_TOTAL_MEM              #language en-US "Total Memory"
+#string STR_MEM_INFO_TOTAL_MEM_VALUE        #language en-US "0 GB"
+#string STR_MEM_INFO_EFFECT_MEM             #language en-US "Effective Memory"
+#string STR_MEM_INFO_EFFECT_MEM_VALUE       #language en-US "0 MB"
+#string STR_MEM_INFO_CURRENT_SPEED          #language en-US "Memory Speed"
+#string STR_MEM_INFO_CURRENT_SPEED_VALUE    #language en-US "0 MHz"
+#string STR_MEM_INFO_SPEED_SELECT_PROMPT    #language en-US "Memory Operating Speed Selection"
+#string STR_MEM_INFO_SPEED_SELECT_HELP      #language en-US "Force specific Memory Operating Speed or use Auto setting."
+#string STR_MEM_INFO_SPEED_SELECT_VALUE0    #language en-US "Auto"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE1    #language en-US "2133"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE2    #language en-US "2400"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE3    #language en-US "2666"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE4    #language en-US "2933"
+#string STR_MEM_INFO_SPEED_SELECT_VALUE5    #language en-US "3200"
+#string STR_MEM_INFO_DIMM_INFO              #language en-US "DIMM Information"
+
+#string STR_MEM_INFO_PERFORMANCE_FORM              #language en-US "Memory RAS and Performance Configuration"
+#string STR_MEM_INFO_PERFORMANCE_FORM_HELP         #language en-US "Displays and provides options to change the memory RAS and performance Settings"
+#string STR_MEM_INFO_ENABLE_ECC_PROMPT             #language en-US "ECC mode"
+#string STR_MEM_INFO_ENABLE_ECC_HELP               #language en-US "ECC mode: Disabled, SECDED or Symbol"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT      #language en-US "Defer uncorrectable read errors"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP        #language en-US "When enabled the DMC defers uncorrectable read errors to the consumer by sending an OK response and setting the TXDAT poison flag on the CHI-B interconnect. If this bit is clear the DMC defaults to non-deferred behavior when encountering an unrecoverable error"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT      #language en-US "Fault handling interrupt"
+#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP        #language en-US "Enables fault handling interrupt. The fault handling interrupt is raised to give notice that ECC fault has been recorded"
+#string STR_MEM_INFO_ENABLE_SCRUB                  #language en-US "Scrub Patrol duration (hour)"
+#string STR_MEM_INFO_ENABLE_SCRUB_HELP             #language en-US "Select duration (hour) for Scrub Patrol"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT    #language en-US "Demand scrub"
+#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP      #language en-US "Enable/Disable the ability to write corrected data back to the memory once a correctable error is detected"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT       #language en-US "Write CRC"
+#string STR_MEM_INFO_ENABLE_WRITE_CRC_HELP         #language en-US "Enable/Disable Cyclic Redundancy Check (CRC) functionality on write data. Be noted that enabling CRC will degrade Write bandwidth"
+
+
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT      #language en-US "Enable Slave 32bit memory region"
+#string STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP        #language en-US "Enables 32bit memory region (2GB) for slave socket"
+#string STR_MEM_INFO_FGR_MODE_PROMPT               #language en-US "Fine Granularity Refresh (FGR)"
+#string STR_MEM_INFO_FGR_MODE_VALUE0               #language en-US "1x"
+#string STR_MEM_INFO_FGR_MODE_VALUE1               #language en-US "2x"
+#string STR_MEM_INFO_FGR_MODE_VALUE2               #language en-US "4x"
+#string STR_MEM_INFO_FGR_MODE_HELP                 #language en-US "Select DDR Fine Granularity Refresh (FGR) mode 1x/2x/4x"
+#string STR_MEM_INFO_REFRESH2X_MODE_PROMPT         #language en-US "CVE-2020-10255 mitigation"
+#string STR_MEM_INFO_REFRESH2X_MODE_HELP           #language en-US "Enable mitigation for CVE-2020-10255, TRRespass"
+
+#string STR_MEM_INFO_NVDIMM_FORM                   #language en-US "NVDIMM-N Configuration"
+#string STR_MEM_INFO_NVDIMM_FORM_HELP              #language en-US "Displays and provides options to change the NVDIMM-N Settings"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0           #language en-US "Socket0 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1           #language en-US "Socket1 Configured Mode"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE     #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE     #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT        #language en-US "Mode Selection"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0        #language en-US "Non-NVDIMM"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1        #language en-US "Non-Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2        #language en-US "Hashed"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3        #language en-US "Auto"
+#string STR_MEM_INFO_NVDIMM_MODE_SEL_HELP          #language en-US "Select NVDIMM-N Mode (Non-NVDIMM/Non-Hashed/Hashed/Auto)"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (23 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:15   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
                   ` (9 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This screen only supports to configure the SubNUMA mode currently.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                    |   3 +
 Platform/Ampere/JadePkg/Jade.dsc                                    |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                    |   1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf |  58 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h   |  74 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h    |  19 +
 Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h           |  19 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr          |  43 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c   | 508 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni   |  17 +
 10 files changed, 743 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index a372a4e0078b..05b4e8576836 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -50,6 +50,9 @@ [LibraryClasses]
   TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
 
 [Guids]
+  # GUID for the CPU HII configuration form
+  gCpuConfigFormSetGuid        = { 0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } }
+
   ## NVParam MM GUID
   gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
 
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 75b3ece3817e..547fbb68b4e3 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -180,3 +180,4 @@ [Components.common]
   #
   Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index e71f3e79e6b3..b8342fde9d72 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -355,5 +355,6 @@ [FV.FvMain]
   #
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
new file mode 100755
index 000000000000..a47d2b894b76
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
@@ -0,0 +1,58 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = CpuConfigDxe
+  MODULE_UNI_FILE                = CpuConfigDxe.uni
+  FILE_GUID                      = A20D8E6E-EE6C-43C5-809F-19BB930653AE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = CpuConfigDxeEntryPoint
+
+[Sources.common]
+  CpuConfigDxe.c
+  CpuConfigDxe.h
+  NVDataStruc.h
+  Vfr.vfr
+  VfrStrings.uni
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  BaseLib
+  DebugLib
+  DevicePathLib
+  HiiLib
+  HobLib
+  IoLib
+  MemoryAllocationLib
+  NVParamLib
+  PcdLib
+  PrintLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiHiiConfigRoutingProtocolGuid             ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid              ## PRODUCES
+  gEfiDevicePathProtocolGuid                   ## PRODUCES
+
+[Guids]
+  gCpuConfigFormSetGuid
+  gPlatformManagerFormsetGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
new file mode 100644
index 000000000000..930fbea6f9d7
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
@@ -0,0 +1,74 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_CONFIG_H_
+#define CPU_CONFIG_H_
+
+#include <Uefi.h>
+
+#include <Guid/CpuConfigHii.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformManagerHii.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <NVParamDef.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#include "NVDataStruc.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+//
+extern UINT8 CpuConfigDxeStrings[];
+
+#define CPU_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('C', 'P', 'U', '_')
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE        DriverHandle;
+  EFI_HII_HANDLE    HiiHandle;
+  CPU_VARSTORE_DATA Configuration;
+
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} CPU_CONFIG_PRIVATE_DATA;
+
+#define CPU_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, CPU_CONFIG_PRIVATE_DATA, ConfigAccess, CPU_CONFIG_PRIVATE_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+#endif /* CPU_CONFIG_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
new file mode 100644
index 000000000000..d906a395c04c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_NV_DATA_STRUC_H_
+#define CPU_NV_DATA_STRUC_H_
+
+#pragma pack(1)
+typedef struct {
+  UINT32 CpuSubNumaMode;
+} CPU_VARSTORE_DATA;
+
+#pragma pack()
+
+#endif /* CPU_NV_DATA_STRUC_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
new file mode 100644
index 000000000000..71c8492f76a1
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef CPU_CONFIG_HII_H_
+#define CPU_CONFIG_HII_H_
+
+#define CPU_CONFIGURATION_FORMSET_GUID \
+  { \
+    0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } \
+  }
+
+extern EFI_GUID gCpuConfigFormSetGuid;
+
+#endif /* CPU_CONFIG_HII_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
new file mode 100644
index 000000000000..b085d030bbc5
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
@@ -0,0 +1,43 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiMultiPhase.h>
+#include <Guid/PlatformManagerHii.h>
+#include <Guid/CpuConfigHii.h>
+#include "NVDataStruc.h"
+
+#define SUBNUMA_MODE_FORM_ID 1
+
+formset
+  guid      = CPU_CONFIGURATION_FORMSET_GUID,
+  title     = STRING_TOKEN(STR_CPU_FORM),
+  help      = STRING_TOKEN(STR_CPU_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  varstore CPU_VARSTORE_DATA,
+    name  = CpuConfigNVData,
+    guid  = CPU_CONFIGURATION_FORMSET_GUID;
+
+  form
+    formid = SUBNUMA_MODE_FORM_ID,
+    title  = STRING_TOKEN(STR_CPU_FORM);
+    subtitle text = STRING_TOKEN(STR_CPU_FORM_HELP);
+
+    oneof
+      varid   = CpuConfigNVData.CpuSubNumaMode,
+      prompt  = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_PROMPT),
+      help    = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HELP),
+      flags   = RESET_REQUIRED,
+      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_MONOLITHIC), value = 0x0, flags = DEFAULT;
+      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HEMISPHERE), value = 0x1, flags = 0;
+      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_QUADRANT), value = 0x2, flags = 0;
+    endoneof;
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
new file mode 100644
index 000000000000..da0deb74c156
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
@@ -0,0 +1,508 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "CpuConfigDxe.h"
+
+//
+// Default settings definitions
+//
+#define NV_SI_SUBNUMA_MODE_DEFAULT   0x00 /* Monolithic mode */
+#define WA_ERRATUM_1542419_DEFAULT   0x00 /* Disable I-Cache coherency */
+#define NEAR_ATOMIC_DISABLE_DEFAULT  0x00 /* Enable Near Atomic */
+#define CPU_SLC_REPLACE_POLICY       0x00 /* eLRU */
+
+CHAR16 CpuVarstoreDataName[] = L"CpuConfigNVData";
+
+EFI_HANDLE              mDriverHandle = NULL;
+CPU_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mCpuConfigHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    CPU_CONFIGURATION_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+STATIC
+EFI_STATUS
+CpuNvParamGet (
+  OUT CPU_VARSTORE_DATA *Configuration
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  ASSERT (Configuration != NULL);
+
+  Status = NVParamGet (
+             NV_SI_SUBNUMA_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a %d Fail to write NVParam \n", __FUNCTION__, __LINE__));
+    Configuration->CpuSubNumaMode = SUBNUMA_MODE_MONOLITHIC;
+  } else {
+    Configuration->CpuSubNumaMode = Value;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+CpuNvParamSet (
+  IN CPU_VARSTORE_DATA *Configuration
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  ASSERT (Configuration != NULL);
+
+  Status = NVParamGet (
+             NV_SI_SUBNUMA_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  if (EFI_ERROR (Status) || Value != Configuration->CpuSubNumaMode) {
+    Status = NVParamSet (
+               NV_SI_SUBNUMA_MODE,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Configuration->CpuSubNumaMode
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a %d Fail to access NVParam \n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SetupDefaultSettings (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  //
+  // Subnuma Mode
+  //
+  Status = NVParamGet (
+             NV_SI_SUBNUMA_MODE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Status = NVParamSet (
+               NV_SI_SUBNUMA_MODE,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               NV_SI_SUBNUMA_MODE_DEFAULT
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  //
+  // ARM ERRATA 1542419 workaround
+  //
+  Status = NVParamSet (
+             NV_SI_ERRATUM_1542419_WA,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             WA_ERRATUM_1542419_DEFAULT
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Near atomic
+  //
+  Status = NVParamSet (
+             NV_SI_NEAR_ATOMIC_DISABLE,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             NEAR_ATOMIC_DISABLE_DEFAULT
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // SLC Replacement Policy
+  //
+  Status = NVParamSet (
+             NV_SI_HNF_AUX_CTL_32_63,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             CPU_SLC_REPLACE_POLICY
+             );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuConfigExtractConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN  CONST EFI_STRING                     Request,
+  OUT EFI_STRING                           *Progress,
+  OUT EFI_STRING                           *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  CPU_CONFIG_PRIVATE_DATA         *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  BOOLEAN                         AllocatedRequest;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PrivateData = CPU_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+  //
+  // Get current setting from NVParam.
+  //
+  Status = CpuNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  BufferSize = sizeof (CPU_VARSTORE_DATA);
+  ConfigRequest = Request;
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no request element, construct full request string.
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (&gCpuConfigFormSetGuid, CpuVarstoreDataName, PrivateData->DriverHandle);
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    if (ConfigRequest == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  Status = HiiConfigRouting->BlockToConfig (
+                               HiiConfigRouting,
+                               ConfigRequest,
+                               (UINT8 *)&PrivateData->Configuration,
+                               BufferSize,
+                               Results,
+                               Progress
+                               );
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+    ConfigRequest = NULL;
+  }
+
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuConfigRouteConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Configuration,
+  OUT      EFI_STRING                     *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  CPU_CONFIG_PRIVATE_DATA         *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = CPU_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get configuration data from NVParam
+  //
+  Status = CpuNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (CPU_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)&PrivateData->Configuration,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store configuration data back to NVParam
+  //
+  Status = CpuNvParamSet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuConfigCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  if (Action != EFI_BROWSER_ACTION_CHANGING) {
+    //
+    // Do nothing for other UEFI Action. Only do call back when data is changed.
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
+      (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CpuConfigDxeEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (CPU_CONFIG_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = CPU_CONFIG_PRIVATE_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = CpuConfigExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = CpuConfigRouteConfig;
+  mPrivateData->ConfigAccess.Callback = CpuConfigCallback;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mDriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mCpuConfigHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = mDriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gCpuConfigFormSetGuid,
+                mDriverHandle,
+                CpuConfigDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mCpuConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  //
+  // With the fresh system, the NVParam value is invalid (0xFFFFFFFF).
+  // It causes reading from the NVParam is failed.
+  // So, the NVParam should be setting with default values if any params is invalid.
+  //
+  Status = SetupDefaultSettings ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
new file mode 100644
index 000000000000..70c01f65e4b6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
@@ -0,0 +1,17 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US  "English"
+
+#string STR_CPU_FORM                                #language en-US "CPU Configuration"
+#string STR_CPU_FORM_HELP                           #language en-US "CPU Configuration"
+#string STR_CPU_FORM_SEPERATE_LINE                  #language en-US ""
+
+#string STR_CPU_SUBNUMA_MODE_PROMPT                 #language en-US "ANC mode"
+#string STR_CPU_SUBNUMA_MODE_HELP                   #language en-US "Provides 3 modes: Monolithic, Hemisphere, Quadrant. System with Monolithic mode has single NUMA partition per socket. System with Hemisphere has 2 NUMA partitions per socket. System with Quandrant has 4 NUMA partitions per socket"
+#string STR_CPU_SUBNUMA_MODE_MONOLITHIC             #language en-US "Monolithic"
+#string STR_CPU_SUBNUMA_MODE_HEMISPHERE             #language en-US "Hemisphere"
+#string STR_CPU_SUBNUMA_MODE_QUADRANT               #language en-US "Quadrant"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (24 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:20   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
                   ` (8 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

This supports:
* Enable/Disable APEI Support
* Enable/Disable CPPC Support
* Enable/Disable LPI support
* Enable/Disable Max Performance Mode

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                      |   3 +
 Platform/Ampere/JadePkg/Jade.dsc                                      |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                      |   1 +
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf   |   1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf |  56 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h            |   2 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h   |  85 +++
 Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h               |  28 +
 Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h        |  19 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr           |  69 ++
 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c            |  23 +-
 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c   | 733 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni    |  27 +
 13 files changed, 1046 insertions(+), 2 deletions(-)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 05b4e8576836..ede85d3a3421 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -53,6 +53,9 @@ [Guids]
   # GUID for the CPU HII configuration form
   gCpuConfigFormSetGuid        = { 0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } }
 
+  # GUID for the ACPI HII configuration form
+  gAcpiConfigFormSetGuid = { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } }
+
   ## NVParam MM GUID
   gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
 
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 547fbb68b4e3..e82b0cce691a 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -181,3 +181,4 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index b8342fde9d72..ddd601075f19 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -356,5 +356,6 @@ [FV.FvMain]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
index a1a323eee472..287b4eadbf4a 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
@@ -64,6 +64,7 @@ [Guids]
   gArmMpCoreInfoGuid
   gEfiAcpiTableGuid
   gEfiEventReadyToBootGuid
+  gAcpiConfigFormSetGuid
   gPlatformHobGuid
 
 [Protocols]
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
new file mode 100644
index 000000000000..bc2fbebc84d1
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = AcpiConfigDxe
+  FILE_GUID                      = F36685AE-2623-4231-ABC0-2C151451E6B7
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = AcpiConfigEntryPoint
+
+[Sources.common]
+  AcpiConfigDxe.c
+  AcpiConfigDxe.h
+  Vfr.vfr
+  VfrStrings.uni
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AcpiHelperLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  HiiLib
+  HobLib
+  MemoryAllocationLib
+  SystemFirmwareInterfaceLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gPlatformManagerFormsetGuid
+  gAcpiConfigFormSetGuid
+  gEfiEventReadyToBootGuid
+  gPlatformHobGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+
+[Depex]
+  gEfiVariableArchProtocolGuid AND
+  gEfiVariableWriteArchProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
index c207142459ad..5a0ce9dcc69a 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
@@ -9,7 +9,9 @@
 #ifndef ACPI_APEI_H_
 #define ACPI_APEI_H_
 
+#include <AcpiNVDataStruc.h>
 #include <Base.h>
+#include <Guid/AcpiConfigFormSet.h>
 #include <IndustryStandard/Acpi63.h>
 #include <Library/AcpiHelperLib.h>
 #include <Library/AmpereCpuLib.h>
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
new file mode 100644
index 000000000000..45cb08e01f7b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
@@ -0,0 +1,85 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef DRIVER_SAMPLE_H_
+#define DRIVER_SAMPLE_H_
+
+#include <Uefi.h>
+
+#include <AcpiNVDataStruc.h>
+#include <Guid/AcpiConfigFormSet.h>
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PlatformInfoHobGuid.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/AcpiHelperLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/SystemFirmwareInterfaceLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+//
+extern UINT8 AcpiConfigDxeStrings[];
+
+#define ACPI_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('A', 'C', 'P', 'I')
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE                DriverHandle;
+  EFI_HII_HANDLE            HiiHandle;
+  ACPI_CONFIG_VARSTORE_DATA Configuration;
+  PLATFORM_INFO_HOB         *PlatformHob;
+  EFI_ACPI_SDT_PROTOCOL     *AcpiTableProtocol;
+  EFI_ACPI_HANDLE           AcpiTableHandle;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} ACPI_CONFIG_PRIVATE_DATA;
+
+#define ACPI_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, ACPI_CONFIG_PRIVATE_DATA, ConfigAccess, ACPI_CONFIG_PRIVATE_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
new file mode 100644
index 000000000000..17f80113797d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
@@ -0,0 +1,28 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_NV_DATA_STRUC_H_
+#define ACPI_NV_DATA_STRUC_H_
+
+#pragma pack(1)
+
+//
+// ACPI Configuration NV data structure definition
+//
+typedef struct {
+  UINT32 EnableApeiSupport;
+  UINT32 AcpiCppcEnable;
+  UINT32 AcpiLpiEnable;
+  UINT32 AcpiTurboSupport;
+  UINT32 AcpiTurboMode;
+  UINT32 Reserved[4];
+} ACPI_CONFIG_VARSTORE_DATA;
+
+#pragma pack()
+
+#endif /* ACPI_NV_DATA_STRUC_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
new file mode 100644
index 000000000000..1779a4543769
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef ACPI_CONFIG_FORMSET_GUID_H_
+#define ACPI_CONFIG_FORMSET_GUID_H_
+
+#define ACPI_CONFIGURATION_FORMSET_GUID \
+  { \
+    0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } \
+  }
+
+extern EFI_GUID gAcpiConfigFormSetGuid;
+
+#endif /* ACPI_CONFIG_FORMSET_GUID_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
new file mode 100644
index 000000000000..6cbd896987b5
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
@@ -0,0 +1,69 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <Guid/AcpiConfigFormSet.h>
+#include <AcpiNVDataStruc.h>
+
+#define ACPI_CONFIG_FORM_ID  1
+
+formset
+  guid      = ACPI_CONFIGURATION_FORMSET_GUID,
+  title     = STRING_TOKEN(STR_ACPI_FORM),
+  help      = STRING_TOKEN(STR_ACPI_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  varstore ACPI_CONFIG_VARSTORE_DATA,
+    name  = AcpiConfigNVData,
+    guid  = ACPI_CONFIGURATION_FORMSET_GUID;
+
+  form
+    formid = ACPI_CONFIG_FORM_ID,
+    title  = STRING_TOKEN(STR_ACPI_FORM);
+    subtitle text = STRING_TOKEN(STR_ACPI_FORM_HELP);
+
+    oneof
+      varid   = AcpiConfigNVData.EnableApeiSupport,
+      prompt  = STRING_TOKEN(STR_ACPI_APEI_SUPPORT_PROMPT),
+      help    = STRING_TOKEN(STR_ACPI_APEI_SUPPORT_HELP),
+      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
+      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
+    endoneof;
+
+    oneof
+      varid   = AcpiConfigNVData.AcpiCppcEnable,
+      prompt  = STRING_TOKEN(STR_ACPI_CPPC_PROMPT),
+      help    = STRING_TOKEN(STR_ACPI_CPPC_HELP),
+      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
+      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
+    endoneof;
+
+    oneof
+      varid   = AcpiConfigNVData.AcpiLpiEnable,
+      prompt  = STRING_TOKEN(STR_ACPI_LPI_PROMPT),
+      help    = STRING_TOKEN(STR_ACPI_LPI_HELP),
+      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
+      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
+    endoneof;
+
+    grayoutif ideqval AcpiConfigNVData.AcpiTurboSupport == 0;
+      oneof
+        varid   = AcpiConfigNVData.AcpiTurboMode,
+        prompt  = STRING_TOKEN(STR_ACPI_TURBO_PROMPT),
+        help    = STRING_TOKEN(STR_ACPI_TURBO_HELP),
+        option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
+        option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
+        suppressif ideqval AcpiConfigNVData.AcpiTurboSupport > 0;
+        option text = STRING_TOKEN(STR_ACPI_UNSUPPORTED), value = 2, flags = 0;
+        endif;
+      endoneof;
+    endif;
+
+  endform;
+
+endformset;
diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
index fa188c7776db..3ec63250a5de 100644
--- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
+++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
@@ -445,8 +445,27 @@ AcpiApeiUpdate (
   VOID
   )
 {
-  if (!IsSlaveSocketActive ()) {
-    AcpiApeiHestUpdateTable1P ();
+  EFI_STATUS                Status;
+  ACPI_CONFIG_VARSTORE_DATA AcpiConfigData;
+  UINTN                     BufferSize;
+
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  L"AcpiConfigNVData",
+                  &gAcpiConfigFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &AcpiConfigData
+                  );
+  if (!EFI_ERROR (Status) && (AcpiConfigData.EnableApeiSupport == 0)) {
+    AcpiApeiUninstallTable (EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE);
+    AcpiApeiUninstallTable (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE);
+    AcpiApeiUninstallTable (EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE);
+    AcpiApeiUninstallTable (EFI_ACPI_6_3_ERROR_INJECTION_TABLE_SIGNATURE);
+  } else {
+    if (!IsSlaveSocketActive ()) {
+      AcpiApeiHestUpdateTable1P ();
+    }
   }
 
   if (!IsSdeiEnabled ()) {
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
new file mode 100644
index 000000000000..ea9004ef2e3c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
@@ -0,0 +1,733 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "AcpiConfigDxe.h"
+
+#define ACPI_VARSTORE_ATTRIBUTES EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+                                 EFI_VARIABLE_RUNTIME_ACCESS     | \
+                                 EFI_VARIABLE_NON_VOLATILE
+
+CHAR16 AcpiVarstoreDataName[] = L"AcpiConfigNVData";
+
+EFI_HANDLE               mDriverHandle = NULL;
+ACPI_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mAcpiConfigHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    ACPI_CONFIGURATION_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN  CONST EFI_STRING                     Request,
+  OUT EFI_STRING                           *Progress,
+  OUT EFI_STRING                           *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  ACPI_CONFIG_PRIVATE_DATA        *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  BOOLEAN                         AllocatedRequest;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gAcpiConfigFormSetGuid, AcpiVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PrivateData = ACPI_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+  //
+  // Get Buffer Storage data from EFI variable.
+  // Try to get the current setting from variable.
+  //
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  AcpiVarstoreDataName,
+                  &gAcpiConfigFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &PrivateData->Configuration
+                  );
+  if (EFI_ERROR (Status)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  ConfigRequest = Request;
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no request element, construct full request string.
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (
+                         &gAcpiConfigFormSetGuid,
+                         AcpiVarstoreDataName,
+                         PrivateData->DriverHandle
+                         );
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    if (ConfigRequest == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  Status = HiiConfigRouting->BlockToConfig (
+                               HiiConfigRouting,
+                               ConfigRequest,
+                               (UINT8 *)&PrivateData->Configuration,
+                               BufferSize,
+                               Results,
+                               Progress
+                               );
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+    ConfigRequest = NULL;
+  }
+
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN  CONST EFI_STRING                     Configuration,
+  OUT EFI_STRING                           *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  ACPI_CONFIG_PRIVATE_DATA        *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = ACPI_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &gAcpiConfigFormSetGuid, AcpiVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get Buffer Storage data from EFI variable
+  //
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  AcpiVarstoreDataName,
+                  &gAcpiConfigFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &PrivateData->Configuration
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)&PrivateData->Configuration,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store Buffer Storage back to EFI variable
+  //
+  Status = gRT->SetVariable (
+                  AcpiVarstoreDataName,
+                  &gAcpiConfigFormSetGuid,
+                  ACPI_VARSTORE_ATTRIBUTES,
+                  sizeof (ACPI_CONFIG_VARSTORE_DATA),
+                  &PrivateData->Configuration
+                  );
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN  EFI_BROWSER_ACTION                   Action,
+  IN  EFI_QUESTION_ID                      QuestionId,
+  IN  UINT8                                Type,
+  IN  EFI_IFR_TYPE_VALUE                   *Value,
+  OUT EFI_BROWSER_ACTION_REQUEST           *ActionRequest
+  )
+{
+  if (Action != EFI_BROWSER_ACTION_CHANGING) {
+    //
+    // Do nothing for other UEFI Action. Only do call back when data is changed.
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (((Value == NULL)
+       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+      || (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+AcpiNVDataUpdate (
+  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
+  )
+{
+  EFI_STATUS         Status;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  UINT32             TurboSupport;
+
+  ASSERT (PrivateData != NULL);
+
+  PlatformHob = PrivateData->PlatformHob;
+  TurboSupport = PlatformHob->TurboCapability[0] + PlatformHob->TurboCapability[1];
+
+  if (TurboSupport == 0) {
+    PrivateData->Configuration.AcpiTurboMode = 2; // Unsupported mode
+    PrivateData->Configuration.AcpiTurboSupport = 0;
+  } else {
+    PrivateData->Configuration.AcpiTurboSupport = 1;
+  }
+
+  Status = gRT->SetVariable (
+                  AcpiVarstoreDataName,
+                  &gAcpiConfigFormSetGuid,
+                  ACPI_VARSTORE_ATTRIBUTES,
+                  sizeof (ACPI_CONFIG_VARSTORE_DATA),
+                  &PrivateData->Configuration
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a %d gRT->SetVariable() failed \n", __FUNCTION__, __LINE__));
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateTurboModeConfig (
+  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
+  )
+{
+  EFI_STATUS         Status;
+  PLATFORM_INFO_HOB  *PlatformHob;
+  BOOLEAN            EnableTurbo;
+
+  ASSERT (PrivateData != NULL);
+
+  if (PrivateData->Configuration.AcpiTurboSupport != 0) {
+    PlatformHob = PrivateData->PlatformHob;
+    EnableTurbo = (PrivateData->Configuration.AcpiTurboMode != 0) ? TRUE : FALSE;
+
+    if (PlatformHob->TurboCapability[0] != 0) {
+      Status = MailboxMsgTurboConfig (0, EnableTurbo);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+    }
+
+    if (PlatformHob->TurboCapability[1] != 0) {
+      Status = MailboxMsgTurboConfig (1, EnableTurbo);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+    }
+  } else {
+    DEBUG ((DEBUG_INFO, "%a: Turbo mode is unsupported! \n", __FUNCTION__));
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateCPPCConfig (
+  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
+  )
+{
+  EFI_STATUS            Status;
+  EFI_ACPI_HANDLE       ChildHandle;
+  CHAR8                 Buffer[64];
+  EFI_ACPI_DATA_TYPE    DataType;
+  UINTN                 DataSize;
+  UINT8                 *Data;
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
+
+  ASSERT (PrivateData != NULL);
+
+  AcpiTableProtocol = PrivateData->AcpiTableProtocol;
+
+  AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.CPCE");
+  Status = AcpiTableProtocol->FindPath (
+                                PrivateData->AcpiTableHandle,
+                                (VOID *)Buffer,
+                                &ChildHandle
+                                );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to find path CPCE\n"));
+    AcpiTableProtocol->Close (PrivateData->AcpiTableHandle);
+    return Status;
+  }
+
+  Status = AcpiTableProtocol->GetOption (
+                                ChildHandle,
+                                2,
+                                &DataType,
+                                (VOID *)&Data,
+                                &DataSize
+                                );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data[0] = PrivateData->Configuration.AcpiCppcEnable;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+UpdateLPIConfig (
+  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
+  )
+{
+  EFI_STATUS            Status;
+  EFI_ACPI_HANDLE       ChildHandle;
+  CHAR8                 Buffer[64];
+  EFI_ACPI_DATA_TYPE    DataType;
+  UINTN                 DataSize;
+  UINT8                 *Data;
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
+
+  ASSERT (PrivateData != NULL);
+
+  AcpiTableProtocol = PrivateData->AcpiTableProtocol;
+
+  AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.LPIE");
+  Status = AcpiTableProtocol->FindPath (
+                                PrivateData->AcpiTableHandle,
+                                (VOID *)Buffer,
+                                &ChildHandle
+                                );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to find path LPIE\n"));
+    AcpiTableProtocol->Close (PrivateData->AcpiTableHandle);
+    return Status;
+  }
+
+  Status = AcpiTableProtocol->GetOption (
+                                ChildHandle,
+                                2,
+                                &DataType,
+                                (VOID *)&Data,
+                                &DataSize
+                                );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Data[0] = PrivateData->Configuration.AcpiLpiEnable;
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+VOID
+UpdateAcpiOnReadyToBoot (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS            Status;
+  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
+  EFI_ACPI_HANDLE       TableHandle;
+
+  ASSERT (mPrivateData != NULL);
+
+  //
+  // Find the AcpiTable protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiAcpiSdtProtocolGuid,
+                  NULL,
+                  (VOID **)&AcpiTableProtocol
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
+    return;
+  }
+
+  mPrivateData->AcpiTableProtocol = AcpiTableProtocol;
+
+  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Unable to locate DSDT table protocol\n"));
+    return;
+  }
+
+  mPrivateData->AcpiTableHandle = TableHandle;
+
+  Status = UpdateCPPCConfig (mPrivateData);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  Status = UpdateLPIConfig (mPrivateData);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  Status = UpdateTurboModeConfig (mPrivateData);
+  if (EFI_ERROR (Status)) {
+    return;
+  }
+
+  //
+  // Close DSDT Table
+  //
+  AcpiTableProtocol->Close (TableHandle);
+
+  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
+}
+
+STATIC
+EFI_STATUS
+AcpiConfigUnload (
+  VOID
+  )
+{
+  ASSERT (mPrivateData != NULL);
+
+  if (mDriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mAcpiConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    mDriverHandle = NULL;
+  }
+
+  if (mPrivateData->HiiHandle != NULL) {
+    HiiRemovePackages (mPrivateData->HiiHandle);
+  }
+
+  FreePool (mPrivateData);
+  mPrivateData = NULL;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+AcpiConfigEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  UINTN                           BufferSize;
+  ACPI_CONFIG_VARSTORE_DATA       *Configuration;
+  BOOLEAN                         ActionFlag;
+  EFI_STRING                      ConfigRequestHdr;
+  EFI_EVENT                       ReadyToBootEvent;
+  PLATFORM_INFO_HOB               *PlatformHob;
+  VOID                            *Hob;
+
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr = NULL;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (ACPI_CONFIG_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = ACPI_CONFIG_PRIVATE_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
+  mPrivateData->ConfigAccess.Callback = DriverCallback;
+
+  //
+  // Get the Platform HOB
+  //
+  Hob = GetFirstGuidHob (&gPlatformHobGuid);
+  ASSERT (Hob != NULL);
+  if (Hob == NULL) {
+    AcpiConfigUnload ();
+    return EFI_DEVICE_ERROR;
+  }
+  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
+
+  mPrivateData->PlatformHob = PlatformHob;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mDriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mAcpiConfigHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = mDriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gAcpiConfigFormSetGuid,
+                mDriverHandle,
+                AcpiConfigDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mAcpiConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  //
+  // Initialize configuration data
+  //
+  Configuration = &mPrivateData->Configuration;
+  ZeroMem (Configuration, sizeof (ACPI_CONFIG_VARSTORE_DATA));
+
+  //
+  // Try to read NV config EFI variable first
+  //
+  ConfigRequestHdr = HiiConstructConfigHdr (&gAcpiConfigFormSetGuid, AcpiVarstoreDataName, mDriverHandle);
+  ASSERT (ConfigRequestHdr != NULL);
+
+  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
+  Status = gRT->GetVariable (AcpiVarstoreDataName, &gAcpiConfigFormSetGuid, NULL, &BufferSize, Configuration);
+  if (EFI_ERROR (Status)) {
+    //
+    // Store zero data Buffer Storage to EFI variable
+    //
+    Status = gRT->SetVariable (
+                    AcpiVarstoreDataName,
+                    &gAcpiConfigFormSetGuid,
+                    ACPI_VARSTORE_ATTRIBUTES,
+                    sizeof (ACPI_CONFIG_VARSTORE_DATA),
+                    Configuration
+                    );
+    if (EFI_ERROR (Status)) {
+      AcpiConfigUnload ();
+      return Status;
+    }
+    //
+    // EFI variable for NV config doesn't exit, we should build this variable
+    // based on default values stored in IFR
+    //
+    ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
+    if (!ActionFlag) {
+      AcpiConfigUnload ();
+      return EFI_INVALID_PARAMETER;
+    }
+  } else {
+    //
+    // EFI variable does exist and Validate Current Setting
+    //
+    ActionFlag = HiiValidateSettings (ConfigRequestHdr);
+    if (!ActionFlag) {
+      AcpiConfigUnload ();
+      return EFI_INVALID_PARAMETER;
+    }
+  }
+  FreePool (ConfigRequestHdr);
+
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_NOTIFY,
+                  UpdateAcpiOnReadyToBoot,
+                  NULL,
+                  &gEfiEventReadyToBootGuid,
+                  &ReadyToBootEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fail to create ready to boot event %r!\n", Status));
+    return Status;
+  }
+
+  Status = AcpiNVDataUpdate (mPrivateData);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
new file mode 100644
index 000000000000..21a6188518fd
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
@@ -0,0 +1,27 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US  "English"
+
+#string STR_ACPI_FORM                                #language en-US "ACPI Configuration"
+#string STR_ACPI_FORM_HELP                           #language en-US "ACPI Configuration"
+
+#string STR_ACPI_FORM_SEPERATE_LINE                  #language en-US ""
+#string STR_ACPI_COMMON_ENABLE                       #language en-US "Enabled"
+#string STR_ACPI_COMMON_DISABLE                      #language en-US "Disabled"
+#string STR_ACPI_UNSUPPORTED                         #language en-US "Unsupported"
+
+#string STR_ACPI_APEI_SUPPORT_PROMPT                 #language en-US "APEI Support"
+#string STR_ACPI_APEI_SUPPORT_HELP                   #language en-US "Enable/Disable ACPI Platform Error Interface support"
+
+#string STR_ACPI_CPPC_PROMPT                         #language en-US "CPPC Support"
+#string STR_ACPI_CPPC_HELP                           #language en-US "Enables or Disables System ability to CPPC (Collaborative Processor Performance Control)"
+
+#string STR_ACPI_LPI_PROMPT                          #language en-US "LPI Support"
+#string STR_ACPI_LPI_HELP                            #language en-US "Enables or Disables System ability to LPI (Lower Power Idle)"
+
+#string STR_ACPI_TURBO_PROMPT                        #language en-US "Max Performance"
+#string STR_ACPI_TURBO_HELP                          #language en-US "Enables or Disables System ability to Max Performance"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (25 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:22   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
                   ` (7 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Quan Nguyen <quan@os.amperecomputing.com>

This supports user to enable/disable RAS components running the system
firmware such as HEST, BERT,...

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
---
 Platform/Ampere/JadePkg/Jade.dsc                                    |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                    |   1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf |  56 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h    |  46 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h   |  82 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr          | 105 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c   | 762 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni   |  38 +
 8 files changed, 1091 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index e82b0cce691a..26cf8be001ab 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -182,3 +182,4 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index ddd601075f19..c0b71a4732fa 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -357,5 +357,6 @@ [FV.FvMain]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
new file mode 100644
index 000000000000..7413b7474d7a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
@@ -0,0 +1,56 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001A
+  BASE_NAME                      = RasConfigDxe
+  FILE_GUID                      = 5b5ee6e3-3135-45f7-ad21-46a3f36813cc
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = RasConfigEntryPoint
+
+[Sources.common]
+  NVDataStruc.h
+  RasConfigDxe.c
+  RasConfigDxe.h
+  Vfr.vfr
+  VfrStrings.uni
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  AmpereCpuLib
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  DevicePathLib
+  HiiLib
+  MemoryAllocationLib
+  NVParamLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Guids]
+  gEfiIfrTianoGuid
+  gPlatformManagerFormsetGuid
+  gAcpiConfigFormSetGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
new file mode 100644
index 000000000000..e87d1c97597c
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
@@ -0,0 +1,46 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RAS_CONFIG_NVDATA_STRUC_H_
+#define RAS_CONFIG_NVDATA_STRUC_H_
+
+#define RAS_CONFIG_VARSTORE_ID       0x1234
+#define RAS_CONFIG_FORM_ID           0x1235
+
+#define RAS_VARSTORE_NAME        L"RasConfigNVData"
+
+#define RAS_CONFIG_FORMSET_GUID \
+  { \
+    0x96934cc6, 0xcb15, 0x4d8a, { 0xbe, 0x5f, 0x8e, 0x7d, 0x55, 0x0e, 0xc9, 0xc6 } \
+  }
+
+//
+// Labels definition
+//
+#define LABEL_UPDATE                 0x3234
+#define LABEL_END                    0xffff
+
+#pragma pack(1)
+
+//
+// Ras Configuration NV data structure definition
+//
+typedef struct {
+  UINT32 RasHardwareEinj;
+  UINT32 RasPcieAerFwFirstEnabled;
+  UINT32 RasBertEnabled;
+  UINT32 RasSdeiEnabled;
+  UINT32 RasDdrCeThreshold;
+  UINT32 Ras2pCeThreshold;
+  UINT32 RasCpmCeThreshold;
+  UINT32 RasLinkErrThreshold;
+} RAS_CONFIG_VARSTORE_DATA;
+
+#pragma pack()
+
+#endif /* RAS_CONFIG_NVDATA_STRUC_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
new file mode 100644
index 000000000000..66e2ded8b701
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
@@ -0,0 +1,82 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef RAS_CONFIG_DXE_H_
+#define RAS_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Library/AmpereCpuLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/HobLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <NVParamDef.h>
+#include <PlatformInfoHob.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#include "NVDataStruc.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+//
+extern UINT8 RasConfigDxeStrings[];
+
+#define RAS_2P_CE_THRESHOLD_OFST  OFFSET_OF (RAS_CONFIG_VARSTORE_DATA, Ras2pCeThreshold)
+
+#define RAS_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('R', 'A', 'S', 'C')
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE               DriverHandle;
+  EFI_HII_HANDLE           HiiHandle;
+  RAS_CONFIG_VARSTORE_DATA Configuration;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} RAS_CONFIG_PRIVATE_DATA;
+
+#define RAS_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, RAS_CONFIG_PRIVATE_DATA, ConfigAccess, RAS_CONFIG_PRIVATE_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+#endif /* RAS_CONFIG_DXE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
new file mode 100644
index 000000000000..3c2c4947a52b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
@@ -0,0 +1,105 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "NVDataStruc.h"
+
+formset
+  guid      = RAS_CONFIG_FORMSET_GUID,
+  title     = STRING_TOKEN(STR_RAS_FORM),
+  help      = STRING_TOKEN(STR_RAS_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  //
+  // Define a variable Storage
+  //
+  varstore RAS_CONFIG_VARSTORE_DATA,
+    varid = RAS_CONFIG_VARSTORE_ID,
+    name  = RasConfigNVData,
+    guid  = RAS_CONFIG_FORMSET_GUID;
+
+  form formid = RAS_CONFIG_FORM_ID,
+    title = STRING_TOKEN(STR_RAS_FORM);
+
+    subtitle text = STRING_TOKEN(STR_RAS_FORM);
+
+    oneof varid  = RasConfigNVData.RasHardwareEinj,
+      prompt      = STRING_TOKEN(STR_RAS_HARDWARE_EINJ_PROMPT),
+      help        = STRING_TOKEN(STR_RAS_HARDWARE_EINJ_HELP),
+      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = DEFAULT;
+      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = 0;
+
+    endoneof;
+
+    oneof varid  = RasConfigNVData.RasPcieAerFwFirstEnabled,
+      prompt      = STRING_TOKEN(STR_RAS_PCIE_AER_FW_FIRST_PROMPT),
+      help        = STRING_TOKEN(STR_RAS_PCIE_AER_FW_FIRST_HELP),
+      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = 0;
+      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = DEFAULT;
+
+    endoneof;
+
+    oneof varid  = RasConfigNVData.RasBertEnabled,
+      prompt      = STRING_TOKEN(STR_RAS_BERT_ENABLED_PROMPT),
+      help        = STRING_TOKEN(STR_RAS_BERT_ENABLED_HELP),
+      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = DEFAULT;
+      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = 0;
+
+    endoneof;
+
+    oneof varid  = RasConfigNVData.RasSdeiEnabled,
+      prompt      = STRING_TOKEN(STR_RAS_SDEI_ENABLED_PROMPT),
+      help        = STRING_TOKEN(STR_RAS_SDEI_ENABLED_HELP),
+      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = 0;
+      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = DEFAULT;
+
+    endoneof;
+
+    numeric varid   = RasConfigNVData.RasDdrCeThreshold,
+      prompt  = STRING_TOKEN(STR_RAS_DDR_CE_THRESHOLD_PROMPT),
+      help    = STRING_TOKEN(STR_RAS_DDR_CE_THRESHOLD_HELP),
+      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      minimum = 1,
+      maximum = 8192,
+      default = 1,
+
+    endnumeric;
+
+    label LABEL_UPDATE;
+    //
+    // This is where we will dynamically add other Action type op-code
+    //
+    label LABEL_END;
+
+    numeric varid   = RasConfigNVData.RasCpmCeThreshold,
+      prompt  = STRING_TOKEN(STR_RAS_CPM_CE_THRESHOLD_PROMPT),
+      help    = STRING_TOKEN(STR_RAS_CPM_CE_THRESHOLD_HELP),
+      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      minimum = 1,
+      maximum = 8192,
+      default = 1,
+
+    endnumeric;
+
+    numeric varid   = RasConfigNVData.RasLinkErrThreshold,
+      prompt  = STRING_TOKEN(STR_RAS_LINK_ERR_THRESHOLD_PROMPT),
+      help    = STRING_TOKEN(STR_RAS_LINK_ERR_THRESHOLD_HELP),
+      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
+      minimum = 1,
+      maximum = 8192,
+      default = 1,
+
+    endnumeric;
+
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
new file mode 100644
index 000000000000..ca115764ed7a
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
@@ -0,0 +1,762 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "RasConfigDxe.h"
+
+CHAR16 RasConfigVarstoreDataName[] = L"RasConfigNVData";
+
+EFI_HANDLE              mDriverHandle = NULL;
+RAS_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
+
+EFI_GUID mRasConfigFormSetGuid = RAS_CONFIG_FORMSET_GUID;
+
+//
+// Default RAS Settings
+//
+#define RAS_DEFAULT_HARDWARE_EINJ_SUPPORT     0
+#define RAS_DEFAULT_PCIE_AER_FW_FIRST         0
+#define RAS_DEFAULT_BERT_SUPPORT              1
+#define RAS_DEFAULT_SDEI_SUPPORT              0
+#define RAS_DEFAULT_DDR_CE_THRESHOLD          1
+#define RAS_DEFAULT_2P_CE_THRESHOLD           1
+#define RAS_DEFAULT_PROCESSOR_CE_THRESHOLD    1
+#define RAS_DEFAULT_DDR_LINK_ERROR_THRESHOLD  1
+
+
+HII_VENDOR_DEVICE_PATH mRasConfigHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    RAS_CONFIG_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+EFI_STATUS
+RasConfigNvParamGet (
+  OUT RAS_CONFIG_VARSTORE_DATA *Configuration
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  Status = NVParamGet (
+             NV_SI_HARDWARE_EINJ,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_HARDWARE_EINJ_SUPPORT;
+    Status = NVParamSet (
+               NV_SI_HARDWARE_EINJ,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasHardwareEinj = Value;
+
+  Status = NVParamGet (
+             NV_SI_RAS_PCIE_AER_FW_FIRST,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_PCIE_AER_FW_FIRST;
+    Status = NVParamSet (
+               NV_SI_RAS_PCIE_AER_FW_FIRST,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasPcieAerFwFirstEnabled = Value;
+
+  Status = NVParamGet (
+             NV_SI_RAS_BERT_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_BERT_SUPPORT;
+    Status = NVParamSet (
+               NV_SI_RAS_BERT_ENABLED,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasBertEnabled = Value;
+
+  Status = NVParamGet (
+             NV_SI_RAS_SDEI_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_SDEI_SUPPORT;
+    Status = NVParamSet (
+               NV_SI_RAS_SDEI_ENABLED,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasSdeiEnabled = Value;
+
+  Status = NVParamGet (
+             NV_SI_DDR_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_DDR_CE_THRESHOLD;
+    Status = NVParamSet (
+               NV_SI_DDR_CE_RAS_THRESHOLD,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasDdrCeThreshold = Value;
+
+  Status = NVParamGet (
+             NV_SI_2P_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_2P_CE_THRESHOLD;
+    Status = NVParamSet (
+               NV_SI_2P_CE_RAS_THRESHOLD,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->Ras2pCeThreshold = Value;
+
+  Status = NVParamGet (
+             NV_SI_CPM_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_PROCESSOR_CE_THRESHOLD;
+    Status = NVParamSet (
+               NV_SI_CPM_CE_RAS_THRESHOLD,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasCpmCeThreshold = Value;
+
+  Status = NVParamGet (
+             NV_SI_LINK_ERR_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    Value = RAS_DEFAULT_DDR_LINK_ERROR_THRESHOLD;
+    Status = NVParamSet (
+               NV_SI_LINK_ERR_THRESHOLD,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               Value
+               );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
+      ASSERT_EFI_ERROR (Status);
+      Value = 0;
+    }
+  }
+  Configuration->RasLinkErrThreshold = Value;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+RasConfigNvParamSet (
+  IN RAS_CONFIG_VARSTORE_DATA *Configuration
+  )
+{
+  EFI_STATUS Status;
+
+  Status = NVParamSet (
+             NV_SI_HARDWARE_EINJ,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasHardwareEinj
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_RAS_PCIE_AER_FW_FIRST,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasPcieAerFwFirstEnabled
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_RAS_BERT_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasBertEnabled
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_RAS_SDEI_ENABLED,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasSdeiEnabled
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_DDR_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasDdrCeThreshold
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_2P_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->Ras2pCeThreshold
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_CPM_CE_RAS_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasCpmCeThreshold
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = NVParamSet (
+             NV_SI_LINK_ERR_THRESHOLD,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             NV_PERM_BIOS | NV_PERM_MANU,
+             Configuration->RasLinkErrThreshold
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+RasConfigExtractConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Request,
+  OUT      EFI_STRING                     *Progress,
+  OUT      EFI_STRING                     *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  RAS_CONFIG_PRIVATE_DATA         *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  BOOLEAN                         AllocatedRequest;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mRasConfigFormSetGuid, RasConfigVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PrivateData = RAS_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+  //
+  // Get current setting from NVParam.
+  //
+  Status = RasConfigNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  BufferSize = sizeof (RAS_CONFIG_VARSTORE_DATA);
+  ConfigRequest = Request;
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no request element, construct full request string.
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (&mRasConfigFormSetGuid, RasConfigVarstoreDataName, PrivateData->DriverHandle);
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    if (ConfigRequest == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  Status = HiiConfigRouting->BlockToConfig (
+                               HiiConfigRouting,
+                               ConfigRequest,
+                               (UINT8 *)&PrivateData->Configuration,
+                               BufferSize,
+                               Results,
+                               Progress
+                               );
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+    ConfigRequest = NULL;
+  }
+
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+RasConfigRouteConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Configuration,
+  OUT      EFI_STRING                     *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  RAS_CONFIG_PRIVATE_DATA         *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = RAS_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &mRasConfigFormSetGuid, RasConfigVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get configuration data from NVParam
+  //
+  Status = RasConfigNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (RAS_CONFIG_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)&PrivateData->Configuration,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store configuration data back to NVParam
+  //
+  Status = RasConfigNvParamSet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+RasConfigCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  if (Action != EFI_BROWSER_ACTION_CHANGING) {
+    //
+    // Do nothing for other UEFI Action. Only do call back when data is changed.
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (((Value == NULL)
+       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+      || (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UpdateRasConfigScreen (
+  IN RAS_CONFIG_PRIVATE_DATA *PrivateData
+  )
+{
+  EFI_STATUS         Status;
+  VOID               *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *EndLabel;
+
+  if (!IsSlaveSocketActive ()) {
+    return EFI_SUCCESS;
+  }
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  if (StartLabel == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeOpCodeBuffer;
+  }
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  if (EndLabel == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto FreeOpCodeBuffer;
+  }
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = LABEL_END;
+
+  //
+  // Create the numeric for 2P CE threshold
+  //
+  HiiCreateNumericOpCode (
+    StartOpCodeHandle,                             // Container for dynamic created opcodes
+    0x8005,                                        // Question ID
+    RAS_CONFIG_VARSTORE_ID,                        // VarStore ID
+    (UINT16)RAS_2P_CE_THRESHOLD_OFST,              // Offset in Buffer Storage
+    STRING_TOKEN (STR_RAS_2P_CE_THRESHOLD_PROMPT), // Question prompt text
+    STRING_TOKEN (STR_RAS_2P_CE_THRESHOLD_HELP),
+    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
+    EFI_IFR_NUMERIC_SIZE_4,
+    1,
+    8192,
+    1,
+    NULL
+    );
+
+  Status = HiiUpdateForm (
+             PrivateData->HiiHandle,  // HII handle
+             &mRasConfigFormSetGuid,  // Formset GUID
+             RAS_CONFIG_FORM_ID,      // Form ID
+             StartOpCodeHandle,       // Label for where to insert opcodes
+             EndOpCodeHandle          // Insert data
+             );
+
+FreeOpCodeBuffer:
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+RasConfigUnload (
+  VOID
+  )
+{
+  ASSERT (mPrivateData != NULL);
+
+  if (mDriverHandle != NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mRasConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    mDriverHandle = NULL;
+  }
+
+  if (mPrivateData->HiiHandle != NULL) {
+    HiiRemovePackages (mPrivateData->HiiHandle);
+  }
+
+  FreePool (mPrivateData);
+  mPrivateData = NULL;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+RasConfigEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (RAS_CONFIG_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = RAS_CONFIG_PRIVATE_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = RasConfigExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = RasConfigRouteConfig;
+  mPrivateData->ConfigAccess.Callback = RasConfigCallback;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mDriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mRasConfigHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = mDriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &mRasConfigFormSetGuid,
+                mDriverHandle,
+                RasConfigDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mRasConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  Status = UpdateRasConfigScreen (mPrivateData);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((
+      DEBUG_ERROR,
+      "%a %d Fail to update Memory Configuration screen \n",
+      __FUNCTION__,
+      __LINE__
+      ));
+    RasConfigUnload ();
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
new file mode 100644
index 000000000000..c502093a2bbf
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
@@ -0,0 +1,38 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US  "English"
+
+#string STR_RAS_FORM                                #language en-US "RAS Configuration"
+#string STR_RAS_FORM_HELP                           #language en-US "RAS Configuration"
+
+#string STR_RAS_FORM_SEPERATE_LINE                  #language en-US ""
+#string STR_RAS_COMMON_ENABLE                       #language en-US "Enabled"
+#string STR_RAS_COMMON_DISABLE                      #language en-US "Disabled"
+
+#string STR_RAS_HARDWARE_EINJ_PROMPT                #language en-US "Hardware EINJ"
+#string STR_RAS_HARDWARE_EINJ_HELP                  #language en-US "Enable hardware EINJ support, if disabled EINJ is software simulated"
+
+#string STR_RAS_PCIE_AER_FW_FIRST_PROMPT            #language en-US "PCIe AER Firmware First"
+#string STR_RAS_PCIE_AER_FW_FIRST_HELP              #language en-US "Enable firmware to detect PCIe AER, if disabled OS detects AER"
+
+#string STR_RAS_BERT_ENABLED_PROMPT                 #language en-US "Enable BERT"
+#string STR_RAS_BERT_ENABLED_HELP                   #language en-US "Enable Boot Error Record Table, if disabled BERT will not be populated"
+
+#string STR_RAS_SDEI_ENABLED_PROMPT                 #language en-US "Enable SDEI"
+#string STR_RAS_SDEI_ENABLED_HELP                   #language en-US "Enable Software Delegated Exception Interface for NMI support"
+
+#string STR_RAS_DDR_CE_THRESHOLD_PROMPT             #language en-US "DDR CE Threshold"
+#string STR_RAS_DDR_CE_THRESHOLD_HELP               #language en-US "Number of DDR CEs to occur before using SCI notification to OS rather than polled notification"
+
+#string STR_RAS_2P_CE_THRESHOLD_PROMPT              #language en-US "2P CE Threshold"
+#string STR_RAS_2P_CE_THRESHOLD_HELP                #language en-US "Number of 2P CEs to occur before using SCI notification to OS rather than polled notification"
+
+#string STR_RAS_CPM_CE_THRESHOLD_PROMPT             #language en-US "Processor CE Threshold"
+#string STR_RAS_CPM_CE_THRESHOLD_HELP               #language en-US "Number of processor CEs to occur before using SCI notification to OS rather than polled notification"
+
+#string STR_RAS_LINK_ERR_THRESHOLD_PROMPT           #language en-US "DDR Link Error Threshold"
+#string STR_RAS_LINK_ERR_THRESHOLD_HELP             #language en-US "Number of DDR link errors before considering it fatal severity"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (26 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:24   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
                   ` (6 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Provide menu options to configure Secure Watchdog and Non-Secure Watchdog
timer.

By default, the values of these options are 5 minutes.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                              |   3 +
 Platform/Ampere/JadePkg/Jade.dsc                                              |   1 +
 Platform/Ampere/JadePkg/Jade.fdf                                              |   1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf |  50 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h         |  27 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h   |  82 ++++
 Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h                |  19 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr               |  58 +++
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c   | 460 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni        |  26 ++
 10 files changed, 727 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index ede85d3a3421..53930869f4f6 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -56,6 +56,9 @@ [Guids]
   # GUID for the ACPI HII configuration form
   gAcpiConfigFormSetGuid = { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } }
 
+  # GUID for the Watchdog HII configuration form
+  gWatchdogConfigFormSetGuid   = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } }
+
   ## NVParam MM GUID
   gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
 
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 26cf8be001ab..391ff75e237c 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -183,3 +183,4 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index c0b71a4732fa..431c9906e98e 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -358,5 +358,6 @@ [FV.FvMain]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
new file mode 100644
index 000000000000..530b7c3575f6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
@@ -0,0 +1,50 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = WatchdogConfigDxe
+  FILE_GUID                      = 135A0CA5-4851-4EF5-9E1A-C6E4610C39A9
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = WatchdogConfigInitialize
+
+[Sources.common]
+  NVDataStruc.h
+  Vfr.vfr
+  VfrStrings.uni
+  WatchdogConfigDxe.c
+  WatchdogConfigDxe.h
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  DevicePathLib
+  HiiLib
+  NVParamLib
+  PrintLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Guids]
+  gPlatformManagerFormsetGuid
+  gWatchdogConfigFormSetGuid
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
new file mode 100644
index 000000000000..ad95c21e391f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
@@ -0,0 +1,27 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVDATASTRUC_H_
+#define NVDATASTRUC_H_
+
+#include <Guid/WatchdogConfigHii.h>
+
+#define WATCHDOG_CONFIG_VARSTORE_ID       0x1234
+#define WATCHDOG_CONFIG_FORM_ID           0x1235
+
+#define NWDT_UEFI_DEFAULT_VALUE           300 // 5 minutes
+#define SWDT_DEFAULT_VALUE                300 // 5 minutes
+
+#pragma pack(1)
+typedef struct {
+  UINT32 WatchdogTimerUEFITimeout;
+  UINT32 SecureWatchdogTimerTimeout;
+} WATCHDOG_CONFIG_VARSTORE_DATA;
+#pragma pack()
+
+#endif
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
new file mode 100644
index 000000000000..fa2e5e062379
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
@@ -0,0 +1,82 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef WATCHDOG_CONFIG_DXE_H_
+#define WATCHDOG_CONFIG_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/NVParamLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <NVParamDef.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#include "NVDataStruc.h"
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+//
+extern UINT8 WatchdogConfigDxeStrings[];
+
+#define WATCHDOG_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('W', 'D', 'T', 'C')
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE                    DriverHandle;
+  EFI_HII_HANDLE                HiiHandle;
+  WATCHDOG_CONFIG_VARSTORE_DATA Configuration;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} WATCHDOG_CONFIG_PRIVATE_DATA;
+
+#define WATCHDOG_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, WATCHDOG_CONFIG_PRIVATE_DATA, ConfigAccess, WATCHDOG_CONFIG_PRIVATE_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+EFI_STATUS
+WatchdogConfigNvParamSet (
+  IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+  );
+
+EFI_STATUS
+WatchdogConfigNvParamGet (
+  OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+  );
+
+#endif /* WATCHDOG_CONFIG_DXE_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
new file mode 100644
index 000000000000..16319d61a759
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef WATCHDOG_CONFIG_HII_H_
+#define WATCHDOG_CONFIG_HII_H_
+
+#define WATCHDOG_CONFIG_FORMSET_GUID \
+  { \
+    0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } \
+  }
+
+extern EFI_GUID gWatchdogConfigFormSetGuid;
+
+#endif /* WATCHDOG_CONFIG_HII_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
new file mode 100644
index 000000000000..96b780ba9e7e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
@@ -0,0 +1,58 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "NVDataStruc.h"
+
+formset
+  guid      = WATCHDOG_CONFIG_FORMSET_GUID,
+  title     = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM),
+  help      = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  //
+  // Define a variable Storage
+  //
+  varstore WATCHDOG_CONFIG_VARSTORE_DATA,
+    varid   = WATCHDOG_CONFIG_VARSTORE_ID,
+    name    = WatchdogConfigNVData,
+    guid    = WATCHDOG_CONFIG_FORMSET_GUID;
+
+  form
+    formid = WATCHDOG_CONFIG_FORM_ID,
+    title  = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM);
+    subtitle text = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP);
+
+    oneof varid = WatchdogConfigNVData.WatchdogTimerUEFITimeout,
+      prompt      = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI),
+      help        = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI_HELP),
+      flags       = RESET_REQUIRED,
+      option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
+      default = NWDT_UEFI_DEFAULT_VALUE,
+    endoneof;
+
+    oneof varid = WatchdogConfigNVData.SecureWatchdogTimerTimeout,
+      prompt      = STRING_TOKEN(STR_SWDT_TIMEOUT),
+      help        = STRING_TOKEN(STR_SWDT_TIMEOUT_HELP),
+      flags       = RESET_REQUIRED,
+      option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
+      option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
+      default = SWDT_DEFAULT_VALUE,
+    endoneof;
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
new file mode 100644
index 000000000000..98557b2fde8b
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
@@ -0,0 +1,460 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "WatchdogConfigDxe.h"
+
+CHAR16 WatchDogConfigVarstoreDataName[] = L"WatchdogConfigNVData";
+
+EFI_HANDLE                   mDriverHandle = NULL;
+WATCHDOG_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mWatchdogConfigHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    WATCHDOG_CONFIG_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+EFI_STATUS
+WatchdogConfigNvParamGet (
+  OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+  BOOLEAN    SetDefault;
+
+  SetDefault = FALSE;
+  Status = NVParamGet (
+             NV_SI_WDT_BIOS_EXP_MINS,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->WatchdogTimerUEFITimeout = NWDT_UEFI_DEFAULT_VALUE;
+    if (Status == EFI_NOT_FOUND) {
+      SetDefault = TRUE;
+    } else {
+      ASSERT (FALSE);
+    }
+  } else {
+    VarStoreConfig->WatchdogTimerUEFITimeout = Value * 60;
+  }
+
+  Status = NVParamGet (
+             NV_SI_SEC_WDT_BIOS_EXP_MINS,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)) {
+    VarStoreConfig->SecureWatchdogTimerTimeout = SWDT_DEFAULT_VALUE;
+    if (Status == EFI_NOT_FOUND) {
+      SetDefault = TRUE;
+    } else {
+      ASSERT (FALSE);
+    }
+  } else {
+    VarStoreConfig->SecureWatchdogTimerTimeout = Value;
+  }
+
+  if (SetDefault) {
+    WatchdogConfigNvParamSet (VarStoreConfig);
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WatchdogConfigNvParamSet (
+  IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
+  )
+{
+  EFI_STATUS Status;
+  UINT32     Value;
+
+  Status = NVParamGet (
+             NV_SI_WDT_BIOS_EXP_MINS,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)
+      || Value != (VarStoreConfig->WatchdogTimerUEFITimeout / 60))
+  {
+    Status = NVParamSet (
+               NV_SI_WDT_BIOS_EXP_MINS,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               (VarStoreConfig->WatchdogTimerUEFITimeout / 60)
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  Status = NVParamGet (
+             NV_SI_SEC_WDT_BIOS_EXP_MINS,
+             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+             &Value
+             );
+  if (EFI_ERROR (Status)
+      || Value != VarStoreConfig->SecureWatchdogTimerTimeout)
+  {
+    Status = NVParamSet (
+               NV_SI_SEC_WDT_BIOS_EXP_MINS,
+               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
+               NV_PERM_BIOS | NV_PERM_MANU,
+               VarStoreConfig->SecureWatchdogTimerTimeout
+               );
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This function allows a caller to extract the current configuration for one
+  or more named elements from the target driver.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Request                A null-terminated Unicode string in
+                                 <ConfigRequest> format.
+  @param  Progress               On   return, points to a character in the Request
+                                 string. Points to the string's null terminator if
+                                 request was successful. Points to the most recent
+                                 '&' before the first failing name/value pair (or
+                                 the beginning of the string if the failure is in
+                                 the first name/value pair) if the request was not
+                                 successful.
+  @param  Results                A null-terminated Unicode string in
+                                 <ConfigAltResp> format which has all values filled
+                                 in for the names in the Request string. String to
+                                 be allocated by the called function.
+
+  @retval EFI_SUCCESS            The Results is filled with the requested values.
+  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
+  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogConfigExtractConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Request,
+  OUT      EFI_STRING                     *Progress,
+  OUT      EFI_STRING                     *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  WATCHDOG_CONFIG_PRIVATE_DATA    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  BOOLEAN                         AllocatedRequest;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  PrivateData = WATCHDOG_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+
+  //
+  // Get current setting from NVParam.
+  //
+  Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
+  ConfigRequest = Request;
+  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+    //
+    // Request has no request element, construct full request string.
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (&gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName, PrivateData->DriverHandle);
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    if (ConfigRequest == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+    FreePool (ConfigRequestHdr);
+  }
+
+  //
+  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+  //
+  Status = HiiConfigRouting->BlockToConfig (
+                               HiiConfigRouting,
+                               ConfigRequest,
+                               (UINT8 *)&PrivateData->Configuration,
+                               BufferSize,
+                               Results,
+                               Progress
+                               );
+
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+    ConfigRequest = NULL;
+  }
+
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogConfigRouteConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Configuration,
+  OUT      EFI_STRING                     *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  WATCHDOG_CONFIG_PRIVATE_DATA    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = WATCHDOG_CONFIG_PRIVATE_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (Configuration, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Get configuration data from NVParam
+  //
+  Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)&PrivateData->Configuration,
+                               &BufferSize,
+                               Progress
+                               );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //
+  // Store configuration data back to NVParam
+  //
+  Status = WatchdogConfigNvParamSet (&PrivateData->Configuration);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+
+  @retval  EFI_SUCCESS           The callback successfully handled the action.
+  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
+
+**/
+EFI_STATUS
+EFIAPI
+WatchdogConfigCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  if (Action != EFI_BROWSER_ACTION_CHANGING) {
+    //
+    // Do nothing for other UEFI Action. Only do call back when data is changed.
+    //
+    return EFI_UNSUPPORTED;
+  }
+  if (((Value == NULL)
+       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
+       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
+      || (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WatchdogConfigInitialize (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+
+  //
+  // Initialize driver private data
+  //
+  mPrivateData = AllocateZeroPool (sizeof (WATCHDOG_CONFIG_PRIVATE_DATA));
+  if (mPrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->Signature = WATCHDOG_CONFIG_PRIVATE_SIGNATURE;
+
+  mPrivateData->ConfigAccess.ExtractConfig = WatchdogConfigExtractConfig;
+  mPrivateData->ConfigAccess.RouteConfig = WatchdogConfigRouteConfig;
+  mPrivateData->ConfigAccess.Callback = WatchdogConfigCallback;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  mPrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mDriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mWatchdogConfigHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &mPrivateData->ConfigAccess,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  mPrivateData->DriverHandle = mDriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gWatchdogConfigFormSetGuid,
+                mDriverHandle,
+                WatchdogConfigDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    gBS->UninstallMultipleProtocolInterfaces (
+           mDriverHandle,
+           &gEfiDevicePathProtocolGuid,
+           &mWatchdogConfigHiiVendorDevicePath,
+           &gEfiHiiConfigAccessProtocolGuid,
+           &mPrivateData->ConfigAccess,
+           NULL
+           );
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  mPrivateData->HiiHandle = HiiHandle;
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
new file mode 100644
index 000000000000..1d0f820e456f
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef en-US  "English"
+
+#string STR_WATCHDOG_CONFIG_FORM        #language en-US "Watchdog Configuration"
+#string STR_WATCHDOG_CONFIG_FORM_HELP   #language en-US "Watchdog Configuration"
+
+#string STR_WDT_TIME_DISABLE            #language en-US  "Disabled"
+#string STR_WDT_TIME_3MIN               #language en-US  "3 minutes"
+#string STR_WDT_TIME_4MIN               #language en-US  "4 minutes"
+#string STR_WDT_TIME_5MIN               #language en-US  "5 minutes"
+#string STR_WDT_TIME_6MIN               #language en-US  "6 minutes"
+#string STR_WDT_TIME_10MIN              #language en-US  "10 minutes"
+#string STR_WDT_TIME_15MIN              #language en-US  "15 minutes"
+#string STR_WDT_TIME_20MIN              #language en-US  "20 minutes"
+
+#string STR_NWDT_TIMEOUT_OS             #language en-US  "OS Watchdog Timeout"
+#string STR_NWDT_TIMEOUT_OS_HELP        #language en-US  "Timeout when boot OS."
+#string STR_NWDT_TIMEOUT_UEFI           #language en-US  "UEFI Watchdog Timeout"
+#string STR_NWDT_TIMEOUT_UEFI_HELP      #language en-US  "Timeout when boot UEFI"
+#string STR_SWDT_TIMEOUT                #language en-US  "Secure Watchdog Timeout"
+#string STR_SWDT_TIMEOUT_HELP           #language en-US  "Timeout when SCP will reset system if it doesn't receive response from ARMv8."
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (27 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:34   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
                   ` (5 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

This screen provide menu options to configure Max Payload and Max Read
Request size for each PCIe device under Root Port. PCIe devices which
attach to external switch are not supported yet.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                  |    3 +
 Platform/Ampere/JadePkg/Jade.dsc                                                  |    1 +
 Platform/Ampere/JadePkg/Jade.fdf                                                  |    1 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf |   59 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h           |   56 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h   |   78 ++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h            |   58 ++
 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h                  |   19 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr                 |   50 +
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c   | 1046 ++++++++++++++++++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c            |  191 ++++
 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni |   24 +
 12 files changed, 1586 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
index 53930869f4f6..62e27c8b49b2 100644
--- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
@@ -59,6 +59,9 @@ [Guids]
   # GUID for the Watchdog HII configuration form
   gWatchdogConfigFormSetGuid   = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } }
 
+  # GUID for the Pcie Device HII configuration form
+  gPcieDeviceConfigFormSetGuid = { 0xEC7B1D21, 0x9167, 0x4B9D, { 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, 0x59 } }
+
   ## NVParam MM GUID
   gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
 
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 391ff75e237c..9d787113e3b5 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -184,3 +184,4 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index 431c9906e98e..b0c2894d00f8 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -359,5 +359,6 @@ [FV.FvMain]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
 
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
new file mode 100644
index 000000000000..a04c79661842
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
@@ -0,0 +1,59 @@
+## @file
+#
+# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = PcieDeviceConfigDxe
+  FILE_GUID                      = 17E9369D-0A1B-45F4-A286-B1DED6D85D33
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = PcieDeviceConfigEntryPoint
+
+[Sources.common]
+  NVDataStruc.h
+  PcieDeviceConfigDxe.c
+  PcieDeviceConfigDxe.h
+  PcieDeviceConfigDxe.uni
+  PcieHelper.c
+  PcieHelper.h
+  Vfr.vfr
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  DevicePathLib
+  HiiLib
+  MemoryAllocationLib
+  PrintLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Protocols]
+  gEfiPciIoProtocolGuid
+  gEfiDevicePathProtocolGuid                    ## CONSUMES
+  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
+  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
+  gEfiDevicePathToTextProtocolGuid
+
+[Guids]
+  gEfiIfrTianoGuid
+  gPcieDeviceConfigFormSetGuid
+  gPlatformManagerFormsetGuid
+  gPlatformManagerEntryEventGuid
+
+[Depex]
+  TRUE
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
new file mode 100644
index 000000000000..fb168e495670
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
@@ -0,0 +1,56 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef NVDATASTRUC_H_
+#define NVDATASTRUC_H_
+
+#include <Guid/PcieDeviceConfigHii.h>
+
+#define VARSTORE_NAME   L"PcieDeviceConfigNVData"
+
+#define MAIN_FORM_ID    0x01
+#define DEVICE_FORM_ID  0x02
+#define VARSTORE_ID     0x03
+
+#define MAIN_LABEL_UPDATE   0x21
+#define MAIN_LABEL_END      0x22
+#define DEVICE_LABEL_UPDATE 0x31
+#define DEVICE_LABEL_END    0x32
+
+#define DEVICE_KEY          0x6000
+#define MPS_ONE_OF_KEY      0x7000
+#define MRR_ONE_OF_KEY      0x8000
+
+#define MAX_DEVICE          40
+
+#define DEFAULT_MPS         0x00 // Section 7.5.3.4
+#define DEFAULT_MRR         0x02 // Section 7.5.3.4
+
+#define PCIE_ADD(Vid, Did, Seg, Bus, Dev) \
+        (UINT64)(Vid) << 40 | (UINT64)(Did) << 24 | Seg << 16 | Bus << 8 | Dev;
+
+#pragma pack(1)
+
+typedef struct {
+  UINT8  DEV;
+  UINT8  BUS;
+  UINT8  SEG;
+  UINT16 DID;
+  UINT16 VID;
+  UINT8  SlotId;
+} SLOT_INFO;
+
+typedef struct {
+  UINT8  MPS[MAX_DEVICE];
+  UINT8  MRR[MAX_DEVICE];
+  UINT64 SlotInfo[MAX_DEVICE];
+} VARSTORE_DATA;
+
+#pragma pack()
+
+#endif // NVDATASTRUC_H_
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
new file mode 100644
index 000000000000..40d7da1ef277
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
@@ -0,0 +1,78 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_DEVICE_CONFIG_H_
+#define PCIE_DEVICE_CONFIG_H_
+
+#include <Uefi.h>
+
+#include <Library/HiiLib.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigKeyword.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+
+#include "NVDataStruc.h"
+
+#define MAX_STRING_SIZE              100
+
+#define PRIVATE_DATA_SIGNATURE        SIGNATURE_32 ('P', 'E', 'D', 'C')
+#define PRIVATE_DATA_FROM_THIS(a)     \
+             CR (a, PRIVATE_DATA, ConfigAccess, PRIVATE_DATA_SIGNATURE)
+
+#pragma pack(1)
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+  VENDOR_DEVICE_PATH       VendorDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+#pragma pack()
+
+//
+// This is the generated IFR binary data for each formset defined in VFR.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 VfrBin[];
+
+//
+// This is the generated String package data for all .UNI files.
+// This data array is ready to be used as input of HiiAddPackages() to
+// create a packagelist (which contains Form packages, String packages, etc).
+//
+extern UINT8 PcieDeviceConfigDxeStrings[];
+
+typedef struct {
+  UINTN Signature;
+
+  EFI_HANDLE     DriverHandle;
+  EFI_HII_HANDLE HiiHandle;
+  VARSTORE_DATA  LastVarStoreConfig;
+  VARSTORE_DATA  VarStoreConfig;
+
+  //
+  // Consumed protocol
+  //
+  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
+  EFI_HII_STRING_PROTOCOL             *HiiString;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
+  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
+  EFI_FORM_BROWSER2_PROTOCOL          *FormBrowser2;
+
+  //
+  // Produced protocol
+  //
+  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+} PRIVATE_DATA;
+
+#endif // PCIE_DEVICE_CONFIG_H_
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
new file mode 100644
index 000000000000..32787865119d
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
@@ -0,0 +1,58 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_HELPER_H_
+#define PCIE_HELPER_H_
+
+#define PCIE_MAX_PAYLOAD_MASK         0x07
+#define PCIE_CONTROL_MAX_PAYLOAD_OFF  5
+#define PCIE_MAX_READ_REQUEST_MASK    0x07
+#define PCIE_CONTROL_READ_REQUEST_OFF 12
+
+#define PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG 0x04
+#define PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG      0x08
+
+#define FOR_EACH(Node, Tail, Type) \
+        for (Node = Tail->Type; Node != NULL; Node = Node->Type)
+
+struct _PCIE_NODE {
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  UINT8               MaxMps;
+  UINT8               PcieCapOffset;
+  UINT16              Vid;
+  UINT16              Did;
+  UINT8               Seg;
+  UINT8               Bus;
+  UINT8               Dev;
+  UINT8               Fun;
+  struct _PCIE_NODE   *Parent;
+  struct _PCIE_NODE   *Brother;
+};
+
+typedef struct _PCIE_NODE PCIE_NODE;
+
+EFI_STATUS
+WriteMps (
+  PCIE_NODE *Node,
+  UINT8     Value
+  );
+
+EFI_STATUS
+WriteMrr (
+  PCIE_NODE *Node,
+  UINT8     Value
+  );
+
+EFI_STATUS
+FindCapabilityPtr (
+  IN  EFI_PCI_IO_PROTOCOL *PciIo,
+  IN  UINT8               CapabilityId,
+  OUT UINT8               *CapabilityPtr
+  );
+
+#endif // PCIE_HELPER_H_
diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
new file mode 100644
index 000000000000..04b950abd49e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
@@ -0,0 +1,19 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef PCIE_DEVICE_CONFIG_HII_H_
+#define PCIE_DEVICE_CONFIG_HII_H_
+
+#define PCIE_DEVICE_CONFIG_FORMSET_GUID \
+  { \
+    0xEC7B1D21, 0x9167, 0x4B9D, { 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, 0x59 } \
+  }
+
+extern EFI_GUID gPcieDeviceConfigFormSetGuid;
+
+#endif /* PCIE_DEVICE_CONFIG_HII_H_ */
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
new file mode 100644
index 000000000000..b5b16802b23e
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
@@ -0,0 +1,50 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Guid/PlatformManagerHii.h>
+#include "NVDataStruc.h"
+
+formset
+  guid    = PCIE_DEVICE_CONFIG_FORMSET_GUID,
+  title   = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM),
+  help    = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_HELP),
+  classguid = gPlatformManagerFormsetGuid,
+
+  //
+  // Define a variable Storage
+  //
+  varstore VARSTORE_DATA,
+    varid   = VARSTORE_ID,
+    name    = PcieDeviceConfigNVData,
+    guid    = PCIE_DEVICE_CONFIG_FORMSET_GUID;
+
+  form
+    formid = MAIN_FORM_ID,
+    title = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM);
+
+    subtitle text = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM);
+
+    label MAIN_LABEL_UPDATE;
+    // dynamic content here
+    label MAIN_LABEL_END;
+
+  endform;
+
+  form
+    formid = DEVICE_FORM_ID,
+    title = STRING_TOKEN(STR_DEVICE_FORM);
+
+    subtitle text = STRING_TOKEN(STR_DEVICE_FORM);
+
+    label DEVICE_LABEL_UPDATE;
+    // dynamic content here
+    label DEVICE_LABEL_END;
+
+  endform;
+
+endformset;
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
new file mode 100644
index 000000000000..a04f789530c0
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
@@ -0,0 +1,1046 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/PcieDeviceConfigHii.h>
+#include <IndustryStandard/Pci.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/PciIo.h>
+
+#include "PcieDeviceConfigDxe.h"
+#include "PcieHelper.h"
+
+VOID          *mPciProtocolNotifyRegistration;
+CHAR16        *mVariableName = VARSTORE_NAME;
+PCIE_NODE     *mDeviceBuf[MAX_DEVICE] = {NULL};
+
+HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+      }
+    },
+    PCIE_DEVICE_CONFIG_FORMSET_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    {
+      (UINT8)(END_DEVICE_PATH_LENGTH),
+      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
+    }
+  }
+};
+
+VOID
+FlushDeviceData (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_STATUS    Status;
+  PCIE_NODE     *Node;
+  PRIVATE_DATA  *PrivateData;
+  UINT8         Index;
+  VARSTORE_DATA *LastVarStoreConfig;
+  VARSTORE_DATA *VarStoreConfig;
+
+  PrivateData = (PRIVATE_DATA *)Context;
+  LastVarStoreConfig = &PrivateData->LastVarStoreConfig;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+
+  //
+  // If config has changed, update NVRAM
+  //
+  if (CompareMem (VarStoreConfig, LastVarStoreConfig, sizeof (VARSTORE_DATA)) != 0) {
+    DEBUG ((DEBUG_INFO, "%a Update Device Config Variable\n", __FUNCTION__));
+    Status = gRT->SetVariable (
+                    mVariableName,
+                    &gPcieDeviceConfigFormSetGuid,
+                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+                    sizeof (VARSTORE_DATA),
+                    VarStoreConfig
+                    );
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: Failed to set variable status %r",
+        __FUNCTION__,
+        Status
+        ));
+      return;
+    }
+  }
+
+  // Iterate through the list, then write corresponding MPS MRR
+  for (Index = 0; Index < MAX_DEVICE; Index++) {
+    if (mDeviceBuf[Index] == NULL) {
+      continue;
+    }
+
+    // Write MPS value
+    WriteMps (mDeviceBuf[Index], VarStoreConfig->MPS[Index]);
+
+    FOR_EACH (Node, mDeviceBuf[Index], Parent) {
+      WriteMps (Node, VarStoreConfig->MPS[Index]);
+    }
+
+    FOR_EACH (Node, mDeviceBuf[Index], Brother) {
+      WriteMps (Node, VarStoreConfig->MPS[Index]);
+    }
+
+    // Write MRR value
+    // FIXME: No need to update MRR of parent node
+    WriteMrr (mDeviceBuf[Index], VarStoreConfig->MRR[Index]);
+
+    FOR_EACH (Node, mDeviceBuf[Index], Brother) {
+      WriteMrr (Node, VarStoreConfig->MRR[Index]);
+    }
+  }
+
+  gBS->CloseEvent (Event);
+}
+
+EFI_STATUS
+UpdateDeviceForm (
+  UINT8        Index,
+  PRIVATE_DATA *PrivateData
+  )
+{
+  CHAR16 Str[MAX_STRING_SIZE];
+  UINT8  MaxMps;
+
+  VOID               *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *EndLabel;
+  VOID               *MpsOpCodeHandle;
+  VOID               *MrrOpCodeHandle;
+  PCIE_NODE          *Node;
+
+  if (mDeviceBuf[Index] == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MaxMps = mDeviceBuf[Index]->MaxMps;
+  FOR_EACH (Node, mDeviceBuf[Index], Parent) {
+    if (Node->MaxMps < MaxMps) {
+      MaxMps = Node->MaxMps;
+    }
+  }
+
+  UnicodeSPrint (
+    Str,
+    sizeof (Str),
+    L"PCIe Device 0x%04x:0x%04x",
+    mDeviceBuf[Index]->Vid,
+    mDeviceBuf[Index]->Did
+    );
+
+  HiiSetString (
+    PrivateData->HiiHandle,
+    STRING_TOKEN (STR_DEVICE_FORM),
+    Str,
+    NULL
+    );
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = DEVICE_LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = DEVICE_LABEL_END;
+
+  // Create Option OpCode for MPS selection
+  MpsOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (MpsOpCodeHandle != NULL);
+
+  switch (MaxMps) {
+  case 5:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_4096),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      5
+      );
+
+  case 4:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_2048),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      4
+      );
+
+  case 3:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_1024),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      3
+      );
+
+  case 2:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_512),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      2
+      );
+
+  case 1:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_256),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      1
+      );
+
+  case 0:
+    HiiCreateOneOfOptionOpCode (
+      MpsOpCodeHandle,
+      STRING_TOKEN (STR_128),
+      0,
+      EFI_IFR_NUMERIC_SIZE_1,
+      0
+      );
+  }
+
+  // Create MPS OneOf
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                // Container for dynamic created opcodes
+    (MPS_ONE_OF_KEY + Index),         // Question ID (or call it "key")
+    VARSTORE_ID,                      // VarStore ID
+    Index,                            // Offset in Buffer Storage
+    STRING_TOKEN (STR_PCIE_MPS),      // Question prompt text
+    STRING_TOKEN (STR_PCIE_MPS_HELP), // Question help text
+    EFI_IFR_FLAG_CALLBACK,            // Question flag
+    EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
+    MpsOpCodeHandle,                  // Option Opcode list
+    NULL                              // Default Opcode is NULl
+    );
+
+  // Create Option OpCode for MRR selection
+  MrrOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (MrrOpCodeHandle != NULL);
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_4096),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    5
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_2048),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    4
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_1024),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    3
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_512),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    2
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_256),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    1
+    );
+
+  HiiCreateOneOfOptionOpCode (
+    MrrOpCodeHandle,
+    STRING_TOKEN (STR_128),
+    0,
+    EFI_IFR_NUMERIC_SIZE_1,
+    0
+    );
+
+  // Create MRR OneOf
+  HiiCreateOneOfOpCode (
+    StartOpCodeHandle,                // Container for dynamic created opcodes
+    (MRR_ONE_OF_KEY + Index),         // Question ID (or call it "key")
+    VARSTORE_ID,                      // VarStore ID
+    MAX_DEVICE + Index,               // Offset in Buffer Storage
+    STRING_TOKEN (STR_PCIE_MRR),      // Question prompt text
+    STRING_TOKEN (STR_PCIE_MRR_HELP), // Question help text
+    EFI_IFR_FLAG_CALLBACK,            // Question flag
+    EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
+    MrrOpCodeHandle,                  // Option Opcode list
+    NULL                              // Default Opcode is NULl
+    );
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,        // HII handle
+    &gPcieDeviceConfigFormSetGuid, // Formset GUID
+    DEVICE_FORM_ID,                // Form ID
+    StartOpCodeHandle,             // Label for where to insert opcodes
+    EndOpCodeHandle                // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+  HiiFreeOpCodeHandle (MpsOpCodeHandle);
+  HiiFreeOpCodeHandle (MrrOpCodeHandle);
+  return EFI_SUCCESS;
+}
+
+VOID
+OnPciIoProtocolNotify (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  EFI_STATUS          Status;
+  EFI_HANDLE          HandleBuffer;
+  PCI_TYPE00          Pci;
+
+  UINTN BufferSize;
+  UINTN PciBusNumber;
+  UINTN PciDeviceNumber;
+  UINTN PciFunctionNumber;
+  UINTN PciSegment;
+
+  UINT8  Idx;
+  UINT8  CapabilityPtr;
+  UINT16 TmpValue;
+  UINT64 SlotInfo;
+
+  PCIE_NODE        *Node;
+  PRIVATE_DATA     *PrivateData;
+  STATIC PCIE_NODE *LastNode;
+  STATIC UINT8     Index;
+  STATIC UINT8     LastBus;
+
+  VARSTORE_DATA    *LastVarStoreConfig;
+  VARSTORE_DATA    *VarStoreConfig;
+
+  PrivateData = (PRIVATE_DATA *)Context;
+  LastVarStoreConfig = &PrivateData->LastVarStoreConfig;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+
+  while (TRUE) {
+    BufferSize = sizeof (EFI_HANDLE);
+    Status = gBS->LocateHandle (
+                    ByRegisterNotify,
+                    NULL,
+                    mPciProtocolNotifyRegistration,
+                    &BufferSize,
+                    &HandleBuffer
+                    );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    Status = gBS->HandleProtocol (
+                    HandleBuffer,
+                    &gEfiPciIoProtocolGuid,
+                    (VOID **)&PciIo
+                    );
+    if (EFI_ERROR (Status)) {
+      break;
+    }
+
+    // Get device bus location
+    Status = PciIo->GetLocation (
+                      PciIo,
+                      &PciSegment,
+                      &PciBusNumber,
+                      &PciDeviceNumber,
+                      &PciFunctionNumber
+                      );
+    if (EFI_ERROR (Status) ||
+        ((PciBusNumber == 0) && (PciDeviceNumber == 0)))
+    {
+      // Filter out Host Bridge
+      DEBUG ((DEBUG_INFO, "Filter out Host Bridge %x\n", PciSegment));
+      continue;
+    }
+
+    DEBUG ((
+      DEBUG_INFO,
+      ">> Dev 0x%04x:0x%02x:0x%02x:0x%02x\n",
+      PciSegment,
+      PciBusNumber,
+      PciDeviceNumber,
+      PciFunctionNumber
+      ));
+
+    Status = FindCapabilityPtr (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP, &CapabilityPtr);
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "%a: PCI Express Capability not found\n",
+        __FUNCTION__
+        ));
+      continue;
+    }
+
+    // Get Device's max MPS support
+    Status = PciIo->Pci.Read (
+                          PciIo,
+                          EfiPciIoWidthUint16,
+                          CapabilityPtr + PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG,
+                          1,
+                          &TmpValue
+                          );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+
+    // Read device's VID:PID
+    Status = PciIo->Pci.Read (
+                          PciIo,
+                          EfiPciIoWidthUint32,
+                          0,
+                          sizeof (Pci) / sizeof (UINT32),
+                          &Pci
+                          );
+    if (EFI_ERROR (Status)) {
+      continue;
+    }
+    DEBUG ((
+      DEBUG_INFO,
+      "VendorId 0x%04x - DeviceId 0x%04x\n",
+      Pci.Hdr.VendorId,
+      Pci.Hdr.DeviceId
+      ));
+
+    Node = AllocateZeroPool (sizeof (*Node));
+    Node->MaxMps = TmpValue & PCIE_MAX_PAYLOAD_MASK;
+    Node->PcieCapOffset = CapabilityPtr;
+    Node->PciIo = PciIo;
+    Node->Seg = PciSegment;
+    Node->Bus = PciBusNumber;
+    Node->Dev = PciDeviceNumber;
+    Node->Fun = PciFunctionNumber;
+    Node->Vid = Pci.Hdr.VendorId;
+    Node->Did = Pci.Hdr.DeviceId;
+    SlotInfo = PCIE_ADD (Node->Vid, Node->Did, Node->Seg, Node->Bus, Node->Dev);
+
+    // Presume child devices were registered follow root port
+    if (PciBusNumber != 0) {
+      if (LastBus == 0) {
+        Node->Parent = LastNode;
+        mDeviceBuf[Index] = Node;
+
+        VarStoreConfig->MPS[Index] = DEFAULT_MPS;
+        VarStoreConfig->MRR[Index] = DEFAULT_MRR;
+        VarStoreConfig->SlotInfo[Index] = SlotInfo;
+
+        // Retrieve setting from previous variable
+        for (Idx = 0; Idx < MAX_DEVICE; Idx++) {
+          if (SlotInfo == LastVarStoreConfig->SlotInfo[Idx]) {
+            VarStoreConfig->MPS[Index] = LastVarStoreConfig->MPS[Idx];
+            VarStoreConfig->MRR[Index] = LastVarStoreConfig->MRR[Idx];
+            break;
+          }
+        }
+
+        Index++;
+      } else if (PciBusNumber == LastBus) {
+        LastNode->Brother = Node;
+      } else {
+        // Ignore devices don't stay under root port
+        continue;
+      }
+    }
+
+    LastBus = PciBusNumber;
+    LastNode = Node;
+  }
+}
+
+VOID
+UpdateMainForm (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  UINTN              Index;
+  EFI_STRING_ID      StrId;
+  CHAR16             Str[MAX_STRING_SIZE];
+  VOID               *StartOpCodeHandle;
+  EFI_IFR_GUID_LABEL *StartLabel;
+  VOID               *EndOpCodeHandle;
+  EFI_IFR_GUID_LABEL *EndLabel;
+  PRIVATE_DATA       *PrivateData;
+
+  DEBUG ((DEBUG_INFO, "%a Entry ...\n", __FUNCTION__));
+
+  PrivateData = (PRIVATE_DATA *)Context;
+
+  //
+  // Initialize the container for dynamic opcodes
+  //
+  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (StartOpCodeHandle != NULL);
+
+  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+  ASSERT (EndOpCodeHandle != NULL);
+
+  //
+  // Create Hii Extend Label OpCode as the start opcode
+  //
+  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                       StartOpCodeHandle,
+                                       &gEfiIfrTianoGuid,
+                                       NULL,
+                                       sizeof (EFI_IFR_GUID_LABEL)
+                                       );
+  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  StartLabel->Number       = MAIN_LABEL_UPDATE;
+
+  //
+  // Create Hii Extend Label OpCode as the end opcode
+  //
+  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
+                                     EndOpCodeHandle,
+                                     &gEfiIfrTianoGuid,
+                                     NULL,
+                                     sizeof (EFI_IFR_GUID_LABEL)
+                                     );
+  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+  EndLabel->Number       = MAIN_LABEL_END;
+
+  for (Index = 0; Index < MAX_DEVICE; Index++) {
+    if (mDeviceBuf[Index] == NULL) {
+      break;
+    }
+    DEBUG ((DEBUG_INFO, ">> Add item %d\n", Index));
+
+    // TODO: convert and store in SlotID ex:SystemSlot(seg, bus, dev)
+    UnicodeSPrint (
+      Str,
+      sizeof (Str),
+      L"PCIe Device 0x%04x:0x%04x - %04x:%02x:%02x",
+      mDeviceBuf[Index]->Vid,
+      mDeviceBuf[Index]->Did,
+      mDeviceBuf[Index]->Seg,
+      mDeviceBuf[Index]->Bus,
+      mDeviceBuf[Index]->Dev
+      );
+
+    StrId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
+
+    //
+    // Create a Goto OpCode to device configuration
+    //
+    HiiCreateGotoOpCode (
+      StartOpCodeHandle,                   // Container for dynamic created opcodes
+      DEVICE_FORM_ID,                      // Target Form ID
+      StrId,                               // Prompt text
+      STRING_TOKEN (STR_DEVICE_GOTO_HELP), // Help text
+      EFI_IFR_FLAG_CALLBACK,               // Question flag
+      (DEVICE_KEY + Index)                 // Question ID
+      );
+  }
+
+  HiiUpdateForm (
+    PrivateData->HiiHandle,         // HII handle
+    &gPcieDeviceConfigFormSetGuid,  // Formset GUID
+    MAIN_FORM_ID,                   // Form ID
+    StartOpCodeHandle,              // Label for where to insert opcodes
+    EndOpCodeHandle                 // Insert data
+    );
+
+  HiiFreeOpCodeHandle (StartOpCodeHandle);
+  HiiFreeOpCodeHandle (EndOpCodeHandle);
+
+  gBS->CloseEvent (Event);
+}
+
+EFI_STATUS
+EFIAPI
+ExtractConfig (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN CONST EFI_STRING                     Request,
+  OUT      EFI_STRING                     *Progress,
+  OUT      EFI_STRING                     *Results
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  PRIVATE_DATA                    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_STRING                      ConfigRequest;
+  EFI_STRING                      ConfigRequestHdr;
+  UINTN                           Size;
+  CHAR16                          *StrPointer;
+  BOOLEAN                         AllocatedRequest;
+  VARSTORE_DATA                   *VarStoreConfig;
+
+  if (Progress == NULL || Results == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // Initialize the local variables.
+  //
+  ConfigRequestHdr  = NULL;
+  ConfigRequest     = NULL;
+  Size              = 0;
+  *Progress         = Request;
+  AllocatedRequest  = FALSE;
+
+  PrivateData = PRIVATE_DATA_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+  ASSERT (VarStoreConfig != NULL);
+
+  BufferSize = sizeof (VARSTORE_DATA);
+
+  if (Request == NULL) {
+    //
+    // Request is set to NULL, construct full request string.
+    //
+
+    //
+    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
+    // Null-terminator
+    //
+    ConfigRequestHdr = HiiConstructConfigHdr (
+                         &gPcieDeviceConfigFormSetGuid,
+                         mVariableName,
+                         PrivateData->DriverHandle
+                         );
+    if (ConfigRequestHdr == NULL) {
+      return EFI_OUT_OF_RESOURCES;
+    }
+    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+    ConfigRequest = AllocateZeroPool (Size);
+    ASSERT (ConfigRequest != NULL);
+    AllocatedRequest = TRUE;
+    UnicodeSPrint (
+      ConfigRequest,
+      Size,
+      L"%s&OFFSET=0&WIDTH=%016LX",
+      ConfigRequestHdr,
+      (UINT64)BufferSize
+      );
+    FreePool (ConfigRequestHdr);
+    ConfigRequestHdr = NULL;
+  } else {
+    //
+    // Check routing data in <ConfigHdr>.
+    // Note: if only one Storage is used, then this checking could be skipped.
+    //
+    if (!HiiIsConfigHdrMatch (Request, &gPcieDeviceConfigFormSetGuid, NULL)) {
+      return EFI_NOT_FOUND;
+    }
+    //
+    // Set Request to the unified request string.
+    //
+    ConfigRequest = Request;
+
+    //
+    // Check whether Request includes Request Element.
+    //
+    if (StrStr (Request, L"OFFSET") == NULL) {
+      //
+      // Check Request Element does exist in Request String
+      //
+      StrPointer = StrStr (Request, L"PATH");
+      if (StrPointer == NULL) {
+        return EFI_INVALID_PARAMETER;
+      }
+      if (StrStr (StrPointer, L"&") == NULL) {
+        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
+        ConfigRequest    = AllocateZeroPool (Size);
+        ASSERT (ConfigRequest != NULL);
+        AllocatedRequest = TRUE;
+        UnicodeSPrint (
+          ConfigRequest,
+          Size,
+          L"%s&OFFSET=0&WIDTH=%016LX",
+          Request,
+          (UINT64)BufferSize
+          );
+      }
+    }
+  }
+  //
+  // Check if requesting Name/Value storage
+  //
+  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    Status = EFI_SUCCESS;
+  } else {
+    //
+    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
+    //
+    Status = HiiConfigRouting->BlockToConfig (
+                                 HiiConfigRouting,
+                                 ConfigRequest,
+                                 (UINT8 *)VarStoreConfig,
+                                 BufferSize,
+                                 Results,
+                                 Progress
+                                 );
+  }
+  //
+  // Free the allocated config request string.
+  //
+  if (AllocatedRequest) {
+    FreePool (ConfigRequest);
+  }
+  if (ConfigRequestHdr != NULL) {
+    FreePool (ConfigRequestHdr);
+  }
+  //
+  // Set Progress string to the original request string.
+  //
+  if (Request == NULL) {
+    *Progress = NULL;
+  } else if (StrStr (Request, L"OFFSET") == NULL) {
+    *Progress = Request + StrLen (Request);
+  }
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
+                                 format.
+  @param  Progress               A pointer to a string filled in with the offset of
+                                 the most recent '&' before the first failing
+                                 name/value pair (or the beginning of the string if
+                                 the failure is in the first name/value pair) or
+                                 the terminating NULL if all was successful.
+  @retval EFI_SUCCESS            The Results is processed successfully.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
+                                 driver.
+**/
+EFI_STATUS
+EFIAPI
+RouteConfig (
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN  CONST EFI_STRING                     Configuration,
+  OUT EFI_STRING                           *Progress
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           BufferSize;
+  PRIVATE_DATA                    *PrivateData;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  VARSTORE_DATA                   *VarStoreConfig;
+
+  if (Configuration == NULL || Progress == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+  PrivateData = PRIVATE_DATA_FROM_THIS (This);
+  HiiConfigRouting = PrivateData->HiiConfigRouting;
+  *Progress = Configuration;
+  VarStoreConfig = &PrivateData->VarStoreConfig;
+  ASSERT (VarStoreConfig != NULL);
+
+  //
+  // Check routing data in <ConfigHdr>.
+  // Note: if only one Storage is used, then this checking could be skipped.
+  //
+  if (!HiiIsConfigHdrMatch (
+         Configuration,
+         &gPcieDeviceConfigFormSetGuid,
+         NULL
+         ))
+  {
+    return EFI_NOT_FOUND;
+  }
+
+  //
+  // Check if configuring Name/Value storage
+  //
+  if (StrStr (Configuration, L"OFFSET") == NULL) {
+    //
+    // Don't have any Name/Value storage names
+    //
+    return EFI_SUCCESS;
+  }
+  //
+  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
+  //
+  BufferSize = sizeof (VARSTORE_DATA);
+  Status = HiiConfigRouting->ConfigToBlock (
+                               HiiConfigRouting,
+                               Configuration,
+                               (UINT8 *)VarStoreConfig,
+                               &BufferSize,
+                               Progress
+                               );
+
+  return Status;
+}
+
+/**
+  This function processes the results of changes in configuration.
+  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+  @param  Action                 Specifies the type of action taken by the browser.
+  @param  QuestionId             A unique value which is sent to the original
+                                 exporting driver so that it can identify the type
+                                 of data to expect.
+  @param  Type                   The type of value for the question.
+  @param  Value                  A pointer to the data being sent to the original
+                                 exporting driver.
+  @param  ActionRequest          On return, points to the action requested by the
+                                 callback function.
+  @retval EFI_SUCCESS            The callback successfully handled the action.
+  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
+  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
+                                 callback.
+**/
+EFI_STATUS
+EFIAPI
+DriverCallback (
+  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+  IN       EFI_BROWSER_ACTION             Action,
+  IN       EFI_QUESTION_ID                QuestionId,
+  IN       UINT8                          Type,
+  IN       EFI_IFR_TYPE_VALUE             *Value,
+  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
+  )
+{
+  EFI_STATUS   Status;
+  PRIVATE_DATA *PrivateData;
+
+  if (((Value == NULL) &&
+       (Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
+       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
+      (ActionRequest == NULL))
+  {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PrivateData = PRIVATE_DATA_FROM_THIS (This);
+
+  switch (Action) {
+  case EFI_BROWSER_ACTION_CHANGING:
+    if ((QuestionId >= DEVICE_KEY)
+        & (QuestionId <= (DEVICE_KEY + MAX_DEVICE)))
+    {
+      Status = UpdateDeviceForm (QuestionId - DEVICE_KEY, PrivateData);
+      if (EFI_ERROR (Status)) {
+        return Status;
+      }
+    }
+    break;
+
+  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
+  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
+    if ((QuestionId >= MPS_ONE_OF_KEY)
+        & (QuestionId <= (MPS_ONE_OF_KEY + MAX_DEVICE)))
+    {
+      Value->u8 = DEFAULT_MPS;
+    }
+
+    if ((QuestionId >= MRR_ONE_OF_KEY)
+        & (QuestionId <= (MRR_ONE_OF_KEY + MAX_DEVICE)))
+    {
+      Value->u8 = DEFAULT_MRR;
+    }
+    break;
+
+  case EFI_BROWSER_ACTION_SUBMITTED:
+    break;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PcieDeviceConfigEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_HANDLE                      DriverHandle;
+  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
+  EFI_HII_HANDLE                  HiiHandle;
+  EFI_STATUS                      Status;
+  EFI_EVENT                       PlatformUiEntryEvent;
+  EFI_EVENT                       FlushDeviceEvent;
+  EFI_EVENT                       PciProtocolNotifyEvent;
+  PRIVATE_DATA                    *PrivateData;
+  UINTN                           BufferSize;
+
+  DriverHandle = NULL;
+  PrivateData = AllocateZeroPool (sizeof (*PrivateData));
+  if (PrivateData == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PrivateData->Signature = PRIVATE_DATA_SIGNATURE;
+
+  PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
+  PrivateData->ConfigAccess.RouteConfig = RouteConfig;
+  PrivateData->ConfigAccess.Callback = DriverCallback;
+
+  //
+  // Locate ConfigRouting protocol
+  //
+  Status = gBS->LocateProtocol (
+                  &gEfiHiiConfigRoutingProtocolGuid,
+                  NULL,
+                  (VOID **)&HiiConfigRouting
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+  PrivateData->HiiConfigRouting = HiiConfigRouting;
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &DriverHandle,
+                  &gEfiDevicePathProtocolGuid,
+                  &mHiiVendorDevicePath,
+                  &gEfiHiiConfigAccessProtocolGuid,
+                  &PrivateData->ConfigAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  PrivateData->DriverHandle = DriverHandle;
+
+  //
+  // Publish our HII data
+  //
+  HiiHandle = HiiAddPackages (
+                &gPcieDeviceConfigFormSetGuid,
+                DriverHandle,
+                PcieDeviceConfigDxeStrings,
+                VfrBin,
+                NULL
+                );
+  if (HiiHandle == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto Exit;
+  }
+  PrivateData->HiiHandle = HiiHandle;
+
+  // Event to fixup screen
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  UpdateMainForm,
+                  (VOID *)PrivateData,
+                  &gPlatformManagerEntryEventGuid,
+                  &PlatformUiEntryEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  // Event to collect PciIo
+  PciProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
+                             &gEfiPciIoProtocolGuid,
+                             TPL_CALLBACK,
+                             OnPciIoProtocolNotify,
+                             (VOID *)PrivateData,
+                             &mPciProtocolNotifyRegistration
+                             );
+  ASSERT (PciProtocolNotifyEvent != NULL);
+
+  // Event to flush device data
+  Status = gBS->CreateEventEx (
+                  EVT_NOTIFY_SIGNAL,
+                  TPL_CALLBACK,
+                  FlushDeviceData,
+                  (VOID *)PrivateData,
+                  &gEfiEventReadyToBootGuid,
+                  &FlushDeviceEvent
+                  );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  // Verify varstore
+  BufferSize = sizeof (VARSTORE_DATA);
+  Status = gRT->GetVariable (
+                  mVariableName,
+                  &gPcieDeviceConfigFormSetGuid,
+                  NULL,
+                  &BufferSize,
+                  &PrivateData->LastVarStoreConfig
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Last config is not found\n", __FUNCTION__));
+  }
+
+  return EFI_SUCCESS;
+
+Exit:
+  FreePool (PrivateData);
+  return Status;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
new file mode 100644
index 000000000000..b4e918e2b786
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
@@ -0,0 +1,191 @@
+/** @file
+
+  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <IndustryStandard/Pci.h>
+#include <Protocol/PciIo.h>
+
+#include "PcieDeviceConfigDxe.h"
+#include "PcieHelper.h"
+
+EFI_STATUS
+FindCapabilityPtr (
+  IN  EFI_PCI_IO_PROTOCOL *PciIo,
+  IN  UINT8               CapabilityId,
+  OUT UINT8               *CapabilityPtr
+  )
+{
+  EFI_STATUS Status;
+  UINT8      NextPtr;
+  UINT16     TmpValue;
+
+  ASSERT (PciIo != NULL);
+
+  //
+  // Get pointer to first PCI Capability header
+  //
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint8,
+                        PCI_CAPBILITY_POINTER_OFFSET,
+                        1,
+                        &NextPtr
+                        );
+  if (EFI_ERROR (Status)) {
+    goto Exit;
+  }
+
+  while (TRUE) {
+    if (NextPtr == 0x00) {
+      Status = EFI_NOT_FOUND;
+      goto Exit;
+    }
+
+    //
+    // Retrieve PCI Capability header
+    //
+    Status = PciIo->Pci.Read (
+                          PciIo,
+                          EfiPciIoWidthUint16,
+                          NextPtr,
+                          1,
+                          &TmpValue
+                          );
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+
+    if ((TmpValue & 0xFF) == CapabilityId) {
+      *CapabilityPtr = NextPtr;
+      Status = EFI_SUCCESS;
+      goto Exit;
+    }
+
+    NextPtr = (TmpValue >> 8) & 0xFF;
+  }
+
+Exit:
+  return Status;
+}
+
+EFI_STATUS
+WriteMps (
+  PCIE_NODE *Node,
+  UINT8     Value
+  )
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  EFI_STATUS          Status;
+  UINT16              TmpValue;
+  UINT8               PcieCapOffset;
+
+  if (Node == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PciIo = Node->PciIo;
+  PcieCapOffset = Node->PcieCapOffset;
+
+  // Get current device control reg
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
+                        1,
+                        &TmpValue
+                        );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Update value and write to device
+  TmpValue = (TmpValue & ~(PCIE_MAX_PAYLOAD_MASK << PCIE_CONTROL_MAX_PAYLOAD_OFF))
+             | Value << PCIE_CONTROL_MAX_PAYLOAD_OFF;
+  Status = PciIo->Pci.Write (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
+                        1,
+                        &TmpValue
+                        );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: Write MPS %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n",
+    __FUNCTION__,
+    Value,
+    Node->Seg,
+    Node->Bus,
+    Node->Dev,
+    Node->Fun
+    ));
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WriteMrr (
+  PCIE_NODE *Node,
+  UINT8     Value
+  )
+{
+  EFI_PCI_IO_PROTOCOL *PciIo;
+  EFI_STATUS          Status;
+  UINT16              TmpValue;
+  UINT8               PcieCapOffset;
+
+  if (Node == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  PciIo = Node->PciIo;
+  PcieCapOffset = Node->PcieCapOffset;
+
+  // Get current device control reg
+  Status = PciIo->Pci.Read (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
+                        1,
+                        &TmpValue
+                        );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Update value and write to device
+  TmpValue = (TmpValue & ~(PCIE_MAX_READ_REQUEST_MASK << PCIE_CONTROL_READ_REQUEST_OFF))
+             | Value << PCIE_CONTROL_READ_REQUEST_OFF;
+  Status = PciIo->Pci.Write (
+                        PciIo,
+                        EfiPciIoWidthUint16,
+                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
+                        1,
+                        &TmpValue
+                        );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  DEBUG ((
+    DEBUG_INFO,
+    "%a: Write MRR %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n",
+    __FUNCTION__,
+    Value,
+    Node->Seg,
+    Node->Bus,
+    Node->Dev,
+    Node->Fun
+    ));
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
new file mode 100644
index 000000000000..f07b70c746a6
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
@@ -0,0 +1,24 @@
+//
+// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
+//
+// SPDX-License-Identifier: BSD-2-Clause-Patent
+//
+
+#langdef   en-US "English"    // English
+
+#string STR_PCIE_DEVICE_CONFIG_FORM #language en-US "PCIE Device Configuration"
+#string STR_PCIE_DEVICE_CONFIG_HELP #language en-US "PCIE Device Configuration"
+
+#string STR_DEVICE_FORM             #language en-US "PCIE Device Form"
+#string STR_DEVICE_GOTO_HELP        #language en-US "PCIE Device Configuration"
+
+#string STR_PCIE_MPS            #language en-US "Max Payload Size"
+#string STR_PCIE_MPS_HELP       #language en-US "Max Payload Size"
+#string STR_PCIE_MRR            #language en-US "Max Read Request Size"
+#string STR_PCIE_MRR_HELP       #language en-US "Max Read Request Size"
+#string STR_128                 #language en-US "128 bytes"
+#string STR_256                 #language en-US "256 bytes"
+#string STR_512                 #language en-US "512 bytes"
+#string STR_1024                #language en-US "1024 bytes"
+#string STR_2048                #language en-US "2048 bytes"
+#string STR_4096                #language en-US "4096 bytes"
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (28 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:46   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
                   ` (4 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

From: Vu Nguyen <vunguyen@os.amperecomputing.com>

Due to recent changes in EDK2, system without a valid boot options list
in NVRAM will enter Platform Recovery mode. As ReadyToBoot event is not
triggered in this mode, services like ACPI and PCIe won't be able to do
some finalization settings and cause OS fails to boot.
This change is to prevent the issue by recovery boot options list each
time NVRAM is cleared.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
---
 Platform/Ampere/JadePkg/Jade.dsc                                                  |  5 ++
 Platform/Ampere/JadePkg/Jade.fdf                                                  |  5 ++
 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf | 39 +++++++++++++
 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c   | 58 ++++++++++++++++++++
 4 files changed, 107 insertions(+)

diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 9d787113e3b5..023f2e898d7f 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -185,3 +185,8 @@ [Components.common]
   Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
   Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
+
+  #
+  # Misc
+  #
+  Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
index b0c2894d00f8..edbead046572 100755
--- a/Platform/Ampere/JadePkg/Jade.fdf
+++ b/Platform/Ampere/JadePkg/Jade.fdf
@@ -361,4 +361,9 @@ [FV.FvMain]
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
   INF Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
 
+  #
+  # Misc
+  #
+  INF Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
+
 !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
new file mode 100644
index 000000000000..624332339beb
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x0001001B
+  BASE_NAME                      = BootOptionsRecoveryDxe
+  FILE_GUID                      = FDCDDC91-4F9E-400C-9BB4-1FE4BE9565B3
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = BootOptionsRecoveryDxeEntry
+
+[Sources]
+  BootOptionsRecoveryDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  PcdLib
+  PrintLib
+  UefiBootManagerLib
+  UefiDriverEntryPoint
+  UefiLib
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+
+[Pcd]
+  gAmpereTokenSpaceGuid.PcdNvramErased
+
+[Depex]
+  gEfiFaultTolerantWriteProtocolGuid
diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
new file mode 100644
index 000000000000..cd9637ec704e
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
@@ -0,0 +1,58 @@
+/** @file
+
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+
+VOID
+EFIAPI
+RecoveryCallback (
+  IN EFI_EVENT Event,
+  IN VOID      *Context
+  )
+{
+  DEBUG ((DEBUG_INFO, "%a: Do recover boot options\n", __FUNCTION__));
+
+  EfiBootManagerConnectAll ();
+  EfiBootManagerRefreshAllBootOption ();
+
+  gBS->CloseEvent (Event);
+}
+
+EFI_STATUS
+EFIAPI
+BootOptionsRecoveryDxeEntry (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  EFI_STATUS Status;
+  EFI_EVENT  EndOfDxeEvent;
+
+  DEBUG ((DEBUG_INFO, "%a: NVRAM Clear is %d\n", PcdGetBool (PcdNvramErased), __FUNCTION__));
+
+  if (PcdGetBool (PcdNvramErased)) {
+    DEBUG ((DEBUG_INFO, "%a: Register event to recover boot options\n", __FUNCTION__));
+    Status = gBS->CreateEventEx (
+                    EVT_NOTIFY_SIGNAL,
+                    TPL_CALLBACK,
+                    RecoveryCallback,
+                    NULL,
+                    &gEfiEndOfDxeEventGroupGuid,
+                    &EndOfDxeEvent
+                    );
+    ASSERT_EFI_ERROR (Status);
+  }
+
+  return Status;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (29 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:50   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
                   ` (3 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

The PlatformBootManagerLib library derived from
ArmPkg/Library/PlatformBootManagerLib.

This implementation registers only a common GUID for LinuxBoot Payload
("D834A5AD-459C-4AED-B0D0-8CBCB28838D7") as a active boot option. This
allows BDS to jump to the LinuxBoot Shell immediately without entering
the UiApp Setup Screen or UEFI Shell.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf |  54 ++++++
 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c               | 173 ++++++++++++++++++++
 2 files changed, 227 insertions(+)

diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
new file mode 100644
index 000000000000..cb4ade210117
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
@@ -0,0 +1,54 @@
+## @file
+#  Implementation for PlatformBootManagerLib library class interfaces.
+#
+#  Copyright (C) 2015-2016, Red Hat, Inc.
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = LinuxBootBootManagerLib
+  FILE_GUID                      = 1FA91547-DB23-4F6A-8AF8-3B9782A7F917
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = ARM AARCH64
+#
+
+[Sources]
+  LinuxBootBm.c
+
+[Packages]
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  ShellPkg/ShellPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  DebugLib
+  MemoryAllocationLib
+  PrintLib
+  UefiBootManagerLib
+  UefiBootServicesTableLib
+  UefiLib
+  UefiRuntimeServicesTableLib
+
+[Pcd]
+
+[Guids]
+  gEfiEndOfDxeEventGroupGuid
+  gUefiShellFileGuid
+
+[Protocols]
+  gEfiLoadedImageProtocolGuid
diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
new file mode 100644
index 000000000000..2d0f087477d6
--- /dev/null
+++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
@@ -0,0 +1,173 @@
+/** @file
+  Implementation for PlatformBootManagerLib library class interfaces.
+
+  Copyright (C) 2015-2016, Red Hat, Inc.
+  Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Guid/EventGroup.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootManagerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/PlatformBootManager.h>
+
+// This GUID must match the FILE_GUID in the LinuxBootPkg/LinuxBoot.inf file.
+// GUID: D834A5AD-459C-4AED-B0D0-8CBCB28838D7
+EFI_GUID mLinuxBootFileGuid = { 0xD834A5AD, 0x459C, 0x4AED, { 0xB0, 0xD0, 0x8C, 0xBC, 0xB2, 0x88, 0x38, 0xD7 } };
+
+STATIC
+VOID
+RegisterFvBootOption (
+  CONST EFI_GUID *FileGuid,
+  CHAR16         *Description,
+  UINT32         Attributes
+  )
+{
+  EFI_STATUS                        Status;
+  INTN                              OptionIndex;
+  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
+  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
+  UINTN                             BootOptionCount;
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
+  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
+
+  Status = gBS->HandleProtocol (
+                  gImageHandle,
+                  &gEfiLoadedImageProtocolGuid,
+                  (VOID **)&LoadedImage
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
+  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
+  ASSERT (DevicePath != NULL);
+  DevicePath = AppendDevicePathNode (
+                 DevicePath,
+                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
+                 );
+  ASSERT (DevicePath != NULL);
+
+  Status = EfiBootManagerInitializeLoadOption (
+             &NewOption,
+             LoadOptionNumberUnassigned,
+             LoadOptionTypeBoot,
+             Attributes,
+             Description,
+             DevicePath,
+             NULL,
+             0
+             );
+  ASSERT_EFI_ERROR (Status);
+  FreePool (DevicePath);
+
+  BootOptions = EfiBootManagerGetLoadOptions (
+                  &BootOptionCount,
+                  LoadOptionTypeBoot
+                  );
+
+  OptionIndex = EfiBootManagerFindLoadOption (
+                  &NewOption,
+                  BootOptions,
+                  BootOptionCount
+                  );
+
+  if (OptionIndex == -1) {
+    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
+    ASSERT_EFI_ERROR (Status);
+  }
+  EfiBootManagerFreeLoadOption (&NewOption);
+  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
+}
+
+/**
+  Do the platform specific action before the console is connected.
+
+  Such as:
+    Update console variable;
+    Register new Driver#### or Boot####;
+    Signal ReadyToLock event.
+**/
+VOID
+EFIAPI
+PlatformBootManagerBeforeConsole (
+  VOID
+  )
+{
+  //
+  // Signal EndOfDxe PI Event
+  //
+  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
+}
+
+/**
+  Do the platform specific action after the console is connected.
+
+  Such as:
+    Dynamically switch output mode;
+    Signal console ready platform customized event;
+    Run diagnostics like memory testing;
+    Connect certain devices;
+    Dispatch additional option roms.
+**/
+VOID
+EFIAPI
+PlatformBootManagerAfterConsole (
+  VOID
+  )
+{
+  //
+  // Register LinuxBoot
+  //
+  RegisterFvBootOption (
+    &mLinuxBootFileGuid,
+    L"LinuxBoot",
+    LOAD_OPTION_ACTIVE
+    );
+}
+
+/**
+  This function is called each second during the boot manager waits the
+  timeout.
+
+  @param TimeoutRemain  The remaining timeout.
+**/
+VOID
+EFIAPI
+PlatformBootManagerWaitCallback (
+  UINT16 TimeoutRemain
+  )
+{
+  return;
+}
+
+/**
+  The function is called when no boot option could be launched,
+  including platform recovery options and options pointing to applications
+  built into firmware volumes.
+
+  If this function returns, BDS attempts to enter an infinite loop.
+**/
+VOID
+EFIAPI
+PlatformBootManagerUnableToBoot (
+  VOID
+  )
+{
+  return;
+}
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (30 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:51   ` Leif Lindholm
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
                   ` (2 subsequent siblings)
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

LinuxBoot is a firmware that replaces specific firmware functionality
like the UEFI DXE phase with a Linux kernel and runtime. At the end of
the DXE phase, UEFI will hand over the control to the LinuxBoot kernel.

This package contains the LinuxBoot binary (flashkernel) which is built
and added manually by following the instructions in the Readme.md
("Platform/Ampere/LinuxBootPkg/AArch64/Readme.md").

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Platform/Ampere/LinuxBootPkg/LinuxBoot.inf     | 17 ++++++++++++
 Platform/Ampere/LinuxBootPkg/AArch64/Readme.md | 29 ++++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf b/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
new file mode 100644
index 000000000000..5e8f6f83dfb2
--- /dev/null
+++ b/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
@@ -0,0 +1,17 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+  INF_VERSION                   = 0x0001001B
+  BASE_NAME                     = LinuxBoot
+  FILE_GUID                     = D834A5AD-459C-4AED-B0D0-8CBCB28838D7
+  MODULE_TYPE                   = UEFI_APPLICATION
+  VERSION_STRING                = 1.0
+
+[Binaries.AArch64]
+  PE32|AArch64/flashkernel|*
diff --git a/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md b/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
new file mode 100644
index 000000000000..92c6c3165eac
--- /dev/null
+++ b/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
@@ -0,0 +1,29 @@
+# flashkernel
+
+The LinuxBoot image, named flashkernel, is required to build the final EDK2 image with LinuxBoot support.
+The flashkernel image consists of [Linux](https://kernel.org) kernel and initramfs generated using [u-root](https://github.com/u-root/u-root).
+
+## Overview
+
+LinuxBoot is a firmware that replaces specific firmware functionality
+like the UEFI DXE phase with a Linux kernel and runtime. It is built-in
+UEFI image like an application as it will be executed at the end of DXE phase.
+
+The flashkernel is built completely from the [linuxboot/mainboards](https://github.com/linuxboot/mainboards) repository.
+
+## How to build
+
+1. Clone the `linuxboot/mainboards` repository:
+
+    ```Bash
+    git clone https://github.com/linuxboot/mainboards.git
+    ```
+
+2. Build with the following command:
+
+    ```Bash
+    cd ampere/jade
+    make fetch flashkernel
+    ```
+
+Once the build is done, copy the flashkernel into the edk2-platform under the `Platform/Ampere/LinuxBootPkg/AArch64` directory.
-- 
2.17.1


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

* [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (31 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
@ 2021-05-26 10:07 ` Nhi Pham
  2021-06-07 23:58   ` Leif Lindholm
  2021-05-27 12:56 ` [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. " Leif Lindholm
  2021-06-04 13:54 ` Leif Lindholm
  34 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:07 UTC (permalink / raw)
  To: devel
  Cc: Nhi Pham, Thang Nguyen, Chuong Tran, Phong Vo, Leif Lindholm,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Adds DSC and FDF files to support the LinuxBoot build. Some PEI/DXE
drivers are not added into the target build as they are not required for
booting to the LinuxBoot Shell.

Please note that we MUST have the LinuxBoot binary in the
Platform/Ampere/LinuxBootPkg/AArch64 directory before compiling.

Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc | 550 ++++++++++++++++++++
 Platform/Ampere/JadePkg/JadeLinuxBoot.dsc                     |  90 ++++
 Platform/Ampere/JadePkg/JadeLinuxBoot.fdf                     | 201 +++++++
 3 files changed, 841 insertions(+)

diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
new file mode 100755
index 000000000000..06b2bb928fe8
--- /dev/null
+++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
@@ -0,0 +1,550 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
+
+[BuildOptions]
+  GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
+
+[LibraryClasses.common]
+!if $(TARGET) == RELEASE
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+!else
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+!endif
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
+  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
+  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+  #
+  # Allow dynamic PCDs
+  #
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+
+  #
+  # ARM Architectural Libraries
+  #
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
+  ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
+  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
+
+  #
+  # Ampere Altra specific Libraries
+  #
+  ArmPlatformLib|Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
+  PlatformPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
+  NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
+  MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
+  SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
+  PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf
+  PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
+  AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
+  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
+  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
+  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
+  MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
+
+  #
+  # ARM PL011 UART Driver
+  #
+  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
+  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
+  PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
+
+  #
+  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
+  # in the debugger will show load and unload commands for symbols. You can cut and paste this
+  # into the command window to load symbols. We should be able to use a script to do this, but
+  # the version of RVD I have does not support scripts accessing system memory.
+  #
+  #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
+  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
+  #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
+
+  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
+
+  #
+  # BDS Libraries
+  #
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
+  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
+
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
+
+!ifdef $(EDK2_SKIP_PEICORE)
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+!endif
+
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
+
+[LibraryClasses.common.PEI_CORE]
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.PEIM]
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
+  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+
+[LibraryClasses.common.SEC, LibraryClasses.common.PEIM]
+  MemoryInitPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
+!if $(TARGET) != RELEASE
+  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
+!endif
+  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
+
+  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
+
+[LibraryClasses.ARM,LibraryClasses.AARCH64]
+  #
+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+  # This library provides the instrinsic functions generate by a given compiler.
+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+  #
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+
+  #
+  # Add support for GCC stack protector
+  #
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+[PcdsFeatureFlag.common]
+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+  #
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
+  #
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+  #
+  # If TRUE, Graphics Output Protocol will be installed on virtual handle
+  # created by ConsplitterDxe. It could be set FALSE to save size.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
+
+[PcdsFixedAtBuild.common]
+!ifdef $(FIRMWARE_VER)
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
+!endif
+
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+!if $(TARGET) == RELEASE
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
+!else
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2A
+!endif
+
+  #
+  # SBSA Watchdog Count
+  #
+!ifndef DISABLE_SBSA_WATCHDOG
+  gArmPlatformTokenSpaceGuid.PcdWatchdogCount|1
+!endif
+
+  #  DEBUG_INIT      0x00000001  // Initialization
+  #  DEBUG_WARN      0x00000002  // Warnings
+  #  DEBUG_LOAD      0x00000004  // Load events
+  #  DEBUG_FS        0x00000008  // EFI File system
+  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  #  DEBUG_INFO      0x00000040  // Informational debug messages
+  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  #  DEBUG_VARIABLE  0x00000100  // Variable
+  #  DEBUG_BM        0x00000400  // Boot Manager
+  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  #  DEBUG_NET       0x00004000  // SNP Driver
+  #  DEBUG_UNDI      0x00010000  // UNDI Driver
+  #  DEBUG_LOADFILE  0x00020000  // LoadFile
+  #  DEBUG_EVENT     0x00080000  // Event messages
+  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                              // significantly impact boot performance
+  #  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
+
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragements for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  gArmTokenSpaceGuid.PcdArmPrimaryCore|0x0
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
+
+  #
+  # Stacks for MPCores in Normal World
+  #
+  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x91100000
+  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x20000
+  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000
+
+  #
+  # System Memory Base
+  #
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x90000000
+
+  #
+  # UEFI region size
+  #
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000
+
+  #
+  # Ampere Altra Core-Cluster profile
+  #
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|80
+  gArmPlatformTokenSpaceGuid.PcdClusterCount|40
+
+  #
+  # PL011 - Serial Terminal
+  # Ampere Altra UART0
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x100002600000
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|32
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
+  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
+
+  gArmPlatformTokenSpaceGuid.PL011UartClkInHz|1843200
+  gArmPlatformTokenSpaceGuid.PL011UartInterrupt|0x62
+
+  #
+  # PL011 - Serial Debug UART
+  # Ampere Altra UART2
+  #
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|0x100002620000
+  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|115200
+
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+
+  #
+  # ARM SBSA Watchdog
+  #
+  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x1000027c0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x1000027d0000
+  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|92
+
+  #
+  # ARM Generic Interrupt Controller
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x100100000000
+  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x100100140000
+
+  #
+  # ARM Architectural Timer Frequency
+  #
+  # Set it to 0 so that the code will read frequence from register
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
+  gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
+
+  #
+  # use the TTY terminal type
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+
+  #
+  # GUID of the UI app
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+  #
+  # ACPI table
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
+  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
+
+  #
+  # Enable strict image permissions for all images. (This applies
+  # only to images that were built with >= 4 KB section alignment.)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
+
+  #
+  # Enable NX memory protection for all non-code regions, including OEM and OS
+  # reserved ones, with the exception of LoaderData regions, of which OS loaders
+  # (i.e., GRUB) may assume that its contents are executable.
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1
+
+  #
+  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
+  #
+  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
+
+  #
+  # MmCommunication
+  #
+  gArmTokenSpaceGuid.PcdMmBufferBase|0x88300000
+  gArmTokenSpaceGuid.PcdMmBufferSize|0x100000
+
+[PcdsDynamicHii.common.DEFAULT]
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
+
+[PcdsDynamicDefault.common]
+  #
+  # Fist DRAM Memory region under 4GB address range
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x70000000
+
+################################################################################
+#
+# Component Section - list of all EDK II Component Entries defined by this Platform
+#
+################################################################################
+
+[Components.common]
+  #
+  # PEI Phase modules
+  #
+  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  MdeModulePkg/Core/Pei/PeiMain.inf
+  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
+  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  ArmPkg/Drivers/CpuPei/CpuPei.inf
+  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  }
+
+  #
+  # DXE Phase modules
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+
+  #
+  # PCD
+  #
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  #
+  # Architectural Protocols
+  #
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  #
+  # Environment Variables Protocol
+  #
+  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
+    <PcdsFixedAtBuild>
+      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
+    <LibraryClasses>
+      AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
+      TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
+      VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
+  }
+
+  #
+  # Timer
+  #
+  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  #
+  # ARM GIC Dxe
+  #
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  #
+  # Console
+  #
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+
+  #
+  # Hii Database
+  #
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # PCIe Support
+  #
+  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  #
+  # Bds
+  #
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
new file mode 100755
index 000000000000..d3c7328fb7ed
--- /dev/null
+++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
@@ -0,0 +1,90 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Jade
+  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x0001001B
+  OUTPUT_DIRECTORY               = Build/Jade
+  SUPPORTED_ARCHITECTURES        = AARCH64
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  FLASH_DEFINITION               = Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
+
+  #
+  # Defines for default states.  These can be changed on the command line.
+  # -D FLAG=VALUE
+  #
+  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
+  DEFINE FIRMWARE_VER            = 0.01.001
+  DEFINE EDK2_SKIP_PEICORE       = TRUE
+
+# Include default Ampere Platform DSC file
+!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
+
+#
+# Specific Platform Library
+#
+[LibraryClasses.common]
+  #
+  # RTC Library: Common RTC
+  #
+  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
+
+  #
+  # Library for FailSafe support
+  #
+  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
+
+  #
+  # ACPI Libraries
+  #
+  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
+  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
+  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
+
+  #
+  # Pcie Board
+  #
+  PcieBoardLib|Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
+
+[PcdsDynamicDefault.common.DEFAULT]
+  # SMBIOS Type 0 - BIOS Information
+  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
+
+#
+# Specific Platform Component
+#
+[Components.common]
+
+  #
+  # ACPI
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
+  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
+
+  #
+  # SMBIOS
+  #
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
+
+  #
+  # FailSafeDxe added to prevent watchdog from resetting the system
+  #
+  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
new file mode 100755
index 000000000000..aa5817ec6f4a
--- /dev/null
+++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
@@ -0,0 +1,201 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+[FD.BL33_JADE_UEFI]
+BaseAddress   = 0x92000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
+Size          = 0x00AC0000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
+ErasePolarity = 1
+
+# This one is tricky, it must be: BlockSize * NumBlocks = Size
+BlockSize     = 0x10000
+NumBlocks     = 0xAC
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+
+0x00000000|0x00AC0000
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+
+[FV.FvMain]
+BlockSize          = 0x10000
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 16        # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+FvNameGuid         = 5C60F367-A505-419A-859E-2A4FF6CA6FE5
+
+APRIORI DXE {
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+}
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+
+  #
+  # Environment Variables Protocol
+  #
+  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
+
+  #
+  # Multiple Console IO support
+  #
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+
+  #
+  # Timer
+  #
+  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
+
+  #
+  # ARM GIC Dxe
+  #
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+
+  #
+  # PCIe Support
+  #
+  INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
+
+  #
+  # Linuxboot in Flash Support
+  #
+  INF Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+
+  #
+  # Driver to handle HW Watchdog
+  #
+  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
+
+  #
+  # ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
+  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
+
+  #
+  # SMBIOS
+  #
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
+  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 16
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+APRIORI PEI {
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+}
+
+  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
+  INF MdeModulePkg/Core/Pei/PeiMain.inf
+  INF UefiCpuPkg/CpuIoPei/CpuIoPei.inf
+  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
+  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
+  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
+  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
+  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
+
+  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
-- 
2.17.1


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

* Re: [edk2-devel] [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus
  2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
@ 2021-05-26 10:23   ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-05-26 10:23 UTC (permalink / raw)
  To: devel@edk2.groups.io, Nhi Pham OS

[-- Attachment #1: Type: text/plain, Size: 1875 bytes --]

My fault, please ignore this patch.

Thanks,
Nhi
________________________________
From: devel@edk2.groups.io <devel@edk2.groups.io> on behalf of Nhi Pham via groups.io <nhi=os.amperecomputing.com@groups.io>
Sent: Wednesday, May 26, 2021 5:06 PM
To: devel@edk2.groups.io <devel@edk2.groups.io>
Cc: Nhi Pham OS <nhi@os.amperecomputing.com>
Subject: [edk2-devel] [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus

Only read the Ethernet connection status at the initialization of SNP.

Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
 .../Drivers/UsbCdcNetDxe/SimpleNetwork.c             | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c b/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
index 05c31f4bad9e..e44898cbda47 100644
--- a/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
+++ b/Platform/Ampere/AmperePlatformPkg/Drivers/UsbCdcNetDxe/SimpleNetwork.c
@@ -116,8 +116,6 @@ SnpGetStatus (
   EFI_STATUS              Status;
   EFI_TPL                 OldTpl;

-  DEBUG ((DEBUG_ERROR, "%a %d Entry \n", __FUNCTION__, __LINE__));
-
   if (SimpleNetwork == NULL || SimpleNetwork->Mode == NULL) {
     return EFI_INVALID_PARAMETER;
   }
@@ -154,16 +152,6 @@ SnpGetStatus (
     *InterruptStatus = 0;
   }

-  Status = UsbCdcGetLinkStatus (PrivateData);
-  if (EFI_ERROR (Status)) {
-    Mode->MediaPresent = FALSE;
-  } else {
-    Mode->MediaPresent = PrivateData->LinkUp;
-    DEBUG ((EFI_D_INFO, "%a %d Mode->MediaPresent = %d \n", __FUNCTION__, __LINE__, (UINT8)Mode->MediaPresent));
-  }
-
-  DEBUG ((DEBUG_ERROR, "%a %d End - %r \n", __FUNCTION__, __LINE__, Status));
-
   //
   // Restore TPL and return the operation status
   //
--
2.17.1







[-- Attachment #2: Type: text/html, Size: 3758 bytes --]

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

* Re: [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (32 preceding siblings ...)
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
@ 2021-05-27 12:56 ` Leif Lindholm
  2021-06-04 13:54 ` Leif Lindholm
  34 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-05-27 12:56 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Hi Nhi,

Many thanks for this. Just as a warning - Monday is a bank holiday in the UK,
and I have a personal holiday tomorrow. So I'm unlikely to get to it until
Tuesday. It is kind of big :)

Best Regards,

Leif

On Wed, May 26, 2021 at 17:06:51 +0700, Nhi Pham wrote:
> This patch series adds the support for the Mt. Jade platform based on Ampere's
> Altra Family Processor.
> 
> Notes:
>   + The current patch series was tested with the edk2-stable202102 tag.
>   + The IASL compiler version 20201217 is required to build.
>   + The edk2-non-osi source is required to build.
> 
> You can get code from
> https://github.com/AmpereComputing/edk2-platforms/tree/ampere-upstream-wip-v2
> 
> Cc: Vu Nguyen <vunguyen@os.amperecomputing.com>
> Cc: Nhi Pham <nhi@os.amperecomputing.com>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> 
> Changes since v1:
>   + Addressed all Leif's feedback in the thread
>   https://edk2.groups.io/g/devel/message/70356.
>   + Removed the LinuxBoot image as Leif's feedback in the thread
>   https://edk2.groups.io/g/devel/message/68717. The image will be
>   pre-produced by users as the instruction in the README before compiling.
>   + Other major code improvements from in-house review:
>     * Create new AmperePlatformPkg and AmpereSiliconPkg packages for
>     containing common Platform/Silicon modules.
>     * Remove SMProLib and PMProLib libraries which are replaced by the
>     MailboxInterfaceLib and SystemFirmwareInterfaceLib libraries for the
>     communication interface between UEFI and System Firmware.
>     * Clean up and fix coding styles to conform to EDK II C Coding
>     Standards Specification.
> 
> Nhi Pham (10):
>   AmperePlatformPkg: Implement FailSafe library
>   AmperePlatformPkg: Add FailSafe and WDT support
>   AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table
>   AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table
>   AmpereAltraPkg, JadePkg: Add ACPI support
>   JadePkg: Add ASpeed GOP driver
>   AmpereAltraPkg: Add configuration screen for ACPI
>   AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
>   Platform/Ampere: Introduce the LinuxBootPkg
>   AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade
>     platform
> 
> Quan Nguyen (3):
>   AmpereAltraPkg: Add BootProgress support
>   JadePkg: Add SMBIOS tables support
>   AmpereAltraPkg: Add configuration screen for RAS
> 
> Vu Nguyen (19):
>   Ampere: Initial support for Ampere Altra processor and Mt. Jade
>     platform
>   AmpereAltraPkg: Add MmCommunication modules
>   AmpereAltraPkg: Add DwI2cLib library
>   AmpereAltraPkg: Add DwGpioLib library
>   JadePkg: Implement RealTimeClockLib for PCF85063
>   AmpereAltraPkg: Support non-volatile variables
>   AmpereSiliconPkg: Add PlatformManagerUiLib library instance
>   AmpereAltraPkg: Add PcieCoreLib library instance
>   JadePkg: Add PcieBoardLib library instance
>   AmpereAltraPkg: Add PciHostBridge driver
>   JadePkg: Enable PCIe-related libraries and device drivers
>   AmpereAltraPkg: Add Random Number Generator Support
>   AmpereAltraPkg: Add DebugInfoPei module
>   AmpereAltraPkg: Add platform info screen
>   AmpereAltraPkg: Add configuration screen for memory
>   AmpereAltraPkg: Add configuration screen for CPU
>   AmpereAltraPkg: Add configuration screen for Watchdog timer
>   AmpereAltraPkg: Add configuration screen for Pcie Devices
>   JadePkg: Recover boot options when NVRAM cleared
> 
>  .../AmperePlatformPkg/AmperePlatformPkg.dec   |   31 +
>  .../Ampere/AmpereAltraPkg/AmpereAltraPkg.dec  |   72 +
>  .../AmpereSiliconPkg/AmpereSiliconPkg.dec     |   85 +
>  .../AmpereAltraLinuxBootPkg.dsc.inc           |  550 ++
>  .../AmpereAltraPkg/AmpereAltraPkg.dsc.inc     |  736 +++
>  Platform/Ampere/JadePkg/Jade.dsc              |  192 +
>  Platform/Ampere/JadePkg/JadeLinuxBoot.dsc     |   90 +
>  Platform/Ampere/JadePkg/Jade.fdf              |  369 ++
>  Platform/Ampere/JadePkg/JadeLinuxBoot.fdf     |  201 +
>  .../Drivers/FailSafeDxe/FailSafeDxe.inf       |   54 +
>  .../Library/AcpiHelperLib/AcpiHelperLib.inf   |   33 +
>  .../Library/AcpiPccLib/AcpiPccLib.inf         |   41 +
>  .../Library/FailSafeLib/FailSafeLib.inf       |   41 +
>  .../Ampere/JadePkg/AcpiTables/AcpiTables.inf  |   20 +
>  .../AcpiPlatformDxe/AcpiPlatformDxe.inf       |   76 +
>  .../BootOptionsRecoveryDxe.inf                |   39 +
>  .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf     |   45 +
>  .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf     |   45 +
>  .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf   |   52 +
>  .../PCF85063RealTimeClockLib.inf              |   44 +
>  .../Library/PcieBoardLib/PcieBoardLib.inf     |   60 +
>  Platform/Ampere/LinuxBootPkg/LinuxBoot.inf    |   17 +
>  .../AcpiCommonTables/AcpiCommonTables.inf     |   44 +
>  .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   56 +
>  .../Drivers/ATFHobPei/ATFHobPeim.inf          |   41 +
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.inf   |   56 +
>  .../BootProgressDxe/BootProgressDxe.inf       |   51 +
>  .../BootProgressPeim/BootProgressPeim.inf     |   49 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.inf     |   58 +
>  .../Drivers/DebugInfoPei/DebugInfoPei.inf     |   41 +
>  .../Drivers/FlashFvbDxe/FlashFvbDxe.inf       |   54 +
>  .../Drivers/FlashPei/FlashPei.inf             |   51 +
>  .../Drivers/MemInfoDxe/MemInfoDxe.inf         |   59 +
>  .../Drivers/MemoryInitPeim/MemoryInitPeim.inf |   64 +
>  .../MmCommunicationDxe/MmCommunication.inf    |   57 +
>  .../MmCommunicationPei/MmCommunicationPei.inf |   34 +
>  .../PcieDeviceConfigDxe.inf                   |   59 +
>  .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>  .../Drivers/RasConfigDxe/RasConfigDxe.inf     |   56 +
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf  |   43 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.inf   |   50 +
>  .../Library/AmpereCpuLib/AmpereCpuLib.inf     |   44 +
>  .../Library/ArmPlatformLib/ArmPlatformLib.inf |   57 +
>  .../Library/DwGpioLib/DwGpioLib.inf           |   33 +
>  .../Library/DwI2cLib/DwI2cLib.inf             |   38 +
>  .../Library/FlashLib/FlashLib.inf             |   36 +
>  .../MailboxInterfaceLib.inf                   |   37 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   63 +
>  .../MmCommunicationLib/MmCommunicationLib.inf |   35 +
>  .../Library/NVParamLib/NVParamLib.inf         |   32 +
>  .../Library/PcieCoreLib/PcieCoreLib.inf       |   68 +
>  .../Library/PlatformPeiLib/PlatformPeiLib.inf |   42 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.inf  |   29 +
>  .../SystemFirmwareInterfaceLib.inf            |   30 +
>  .../Library/TrngLib/TrngLib.inf               |   29 +
>  .../LinuxBootBootManagerLib.inf               |   54 +
>  .../PlatformUiLib/PlatformManagerUiLib.inf    |   47 +
>  .../Drivers/FailSafeDxe/FailSafe.h            |   20 +
>  .../Drivers/FailSafeDxe/Watchdog.h            |   29 +
>  .../Include/Library/FailSafeLib.h             |   62 +
>  .../Drivers/AcpiPlatformDxe/AcpiApei.h        |  123 +
>  .../Drivers/AcpiPlatformDxe/AcpiNfit.h        |   49 +
>  .../Drivers/AcpiPlatformDxe/AcpiPlatform.h    |   76 +
>  .../PCF85063RealTimeClockLib/PCF85063.h       |   91 +
>  .../Library/PcieBoardLib/NVDataStruc.h        |   89 +
>  .../Library/PcieBoardLib/PcieBoardScreen.h    |  138 +
>  .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h  |  451 ++
>  .../Pci/PciHostBridgeDxe/PciRootBridgeIo.h    |  554 ++
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.h     |   85 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.h       |   74 +
>  .../Drivers/CpuConfigDxe/NVDataStruc.h        |   19 +
>  .../Drivers/MemInfoDxe/MemInfoScreen.h        |  168 +
>  .../Drivers/MemInfoDxe/NVDataStruc.h          |   47 +
>  .../MmCommunicationDxe/MmCommunicate.h        |   22 +
>  .../Drivers/PcieDeviceConfigDxe/NVDataStruc.h |   56 +
>  .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.h |   78 +
>  .../Drivers/PcieDeviceConfigDxe/PcieHelper.h  |   58 +
>  .../Drivers/PlatformInfoDxe/PlatformInfoHii.h |   22 +
>  .../Drivers/RasConfigDxe/NVDataStruc.h        |   46 +
>  .../Drivers/RasConfigDxe/RasConfigDxe.h       |   82 +
>  .../Drivers/WatchdogConfigDxe/NVDataStruc.h   |   27 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.h     |   82 +
>  .../AmpereAltraPkg/Include/AcpiHeader.h       |   37 +
>  .../AmpereAltraPkg/Include/AcpiNVDataStruc.h  |   28 +
>  .../Include/Guid/AcpiConfigFormSet.h          |   19 +
>  .../Include/Guid/CpuConfigHii.h               |   19 +
>  .../Include/Guid/PcieDeviceConfigHii.h        |   19 +
>  .../Include/Guid/PlatformInfoHobGuid.h        |   17 +
>  .../Include/Guid/WatchdogConfigHii.h          |   19 +
>  .../Include/Library/AmpereCpuLib.h            |  282 +
>  .../AmpereAltraPkg/Include/Library/FlashLib.h |   42 +
>  .../AmpereAltraPkg/Include/Library/GpioLib.h  |   76 +
>  .../AmpereAltraPkg/Include/Library/I2cLib.h   |  100 +
>  .../Include/Library/MailboxInterfaceLib.h     |  172 +
>  .../Include/Library/MmCommunicationLib.h      |   19 +
>  .../Include/Library/NVParamLib.h              |  133 +
>  .../Include/Library/PcieBoardLib.h            |  102 +
>  .../Include/Library/PcieCoreLib.h             |  164 +
>  .../Library/SystemFirmwareInterfaceLib.h      |  282 +
>  .../AmpereAltraPkg/Include/Library/TrngLib.h  |   31 +
>  Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h |   79 +
>  .../AmpereAltraPkg/Include/NVParamDef.h       |  515 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h  |  203 +
>  .../AmpereAltraPkg/Include/Platform/Ac01.h    |  146 +
>  .../AmpereAltraPkg/Include/PlatformInfoHob.h  |  182 +
>  .../Library/PcieCoreLib/PcieCore.h            |  582 ++
>  .../Library/PcieCoreLib/PcieCoreCapCfg.h      |   64 +
>  .../Library/PcieCoreLib/PciePatchAcpi.h       |   30 +
>  .../Include/Guid/PlatformManagerHii.h         |   31 +
>  .../Include/Library/AcpiHelperLib.h           |  109 +
>  .../Include/Library/AcpiPccLib.h              |  166 +
>  .../Library/PlatformUiLib/PlatformManager.h   |   51 +
>  .../PlatformUiLib/PlatformManagerVfr.h        |   28 +
>  .../JadePkg/Library/PcieBoardLib/Vfr.vfr      |  212 +
>  .../Drivers/AcpiConfigDxe/Vfr.vfr             |   69 +
>  .../Drivers/CpuConfigDxe/Vfr.vfr              |   43 +
>  .../AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr |   62 +
>  .../Drivers/PcieDeviceConfigDxe/Vfr.vfr       |   50 +
>  .../Drivers/PlatformInfoDxe/Vfr.vfr           |  112 +
>  .../Drivers/RasConfigDxe/Vfr.vfr              |  105 +
>  .../Drivers/WatchdogConfigDxe/Vfr.vfr         |   58 +
>  .../Drivers/FailSafeDxe/FailSafeDxe.c         |  184 +
>  .../Drivers/FailSafeDxe/Watchdog.c            |  357 ++
>  .../Library/AcpiHelperLib/AcpiHelperLib.c     |  246 +
>  .../Library/AcpiPccLib/AcpiPccLib.c           |  241 +
>  .../Library/FailSafeLib/FailSafeLib.c         |  320 +
>  .../Drivers/AcpiPlatformDxe/AcpiApei.c        |  476 ++
>  .../Drivers/AcpiPlatformDxe/AcpiDsdt.c        |  445 ++
>  .../Drivers/AcpiPlatformDxe/AcpiMadt.c        |  351 +
>  .../Drivers/AcpiPlatformDxe/AcpiNfit.c        |  599 ++
>  .../Drivers/AcpiPlatformDxe/AcpiPcct.c        |  196 +
>  .../Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c |  178 +
>  .../Drivers/AcpiPlatformDxe/AcpiPptt.c        |  378 ++
>  .../Drivers/AcpiPlatformDxe/AcpiSlit.c        |  190 +
>  .../Drivers/AcpiPlatformDxe/AcpiSrat.c        |  274 +
>  .../BootOptionsRecoveryDxe.c                  |   58 +
>  .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c       |  709 +++
>  .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.c       |  705 +++
>  .../SmbiosPlatformDxe/SmbiosPlatformDxe.c     | 1049 +++
>  .../PCF85063RealTimeClockLib/PCF85063.c       |  317 +
>  .../PCF85063RealTimeClockLib.c                |  257 +
>  .../JadePkg/Library/PcieBoardLib/PcieBoard.c  |  438 ++
>  .../Library/PcieBoardLib/PcieBoardCommon.c    |  327 +
>  .../Library/PcieBoardLib/PcieBoardScreen.c    | 1120 ++++
>  .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 1419 +++++
>  .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 1582 +++++
>  .../Drivers/ATFHobPei/ATFHobPeim.c            |   52 +
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.c     |  733 +++
>  .../BootProgressDxe/BootProgressDxe.c         |  211 +
>  .../BootProgressPeim/BootProgressPeim.c       |  210 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.c       |  508 ++
>  .../Drivers/DebugInfoPei/DebugInfoPei.c       |  230 +
>  .../Drivers/FlashFvbDxe/FlashFvbDxe.c         |  525 ++
>  .../Drivers/FlashPei/FlashPei.c               |  283 +
>  .../Drivers/MemInfoDxe/MemInfoNvramLib.c      |  394 ++
>  .../Drivers/MemInfoDxe/MemInfoScreen.c        | 1325 ++++
>  .../Drivers/MemoryInitPeim/MemoryInitPeim.c   |  151 +
>  .../MmCommunicationDxe/MmCommunication.c      |  454 ++
>  .../MmCommunicationPei/MmCommunicationPei.c   |   37 +
>  .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.c | 1046 +++
>  .../Drivers/PcieDeviceConfigDxe/PcieHelper.c  |  191 +
>  .../Drivers/PlatformInfoDxe/PlatformInfoDxe.c |  391 ++
>  .../Drivers/RasConfigDxe/RasConfigDxe.c       |  762 +++
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.c    |  164 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.c     |  460 ++
>  .../Library/AmpereCpuLib/AmpereCpuLib.c       |  706 +++
>  .../Library/ArmPlatformLib/ArmPlatformLib.c   |  169 +
>  .../ArmPlatformLib/ArmPlatformLibMemory.c     |  399 ++
>  .../Library/DwGpioLib/DwGpioLib.c             |  314 +
>  .../Library/DwI2cLib/DwI2cLib.c               |  883 +++
>  .../Library/FlashLib/FlashLib.c               |  358 ++
>  .../MailboxInterfaceLib/MailboxInterfaceLib.c |  282 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.c       |   93 +
>  .../MmCommunicationLib/MmCommunicationLib.c   |  184 +
>  .../Library/NVParamLib/NVParamLib.c           |  202 +
>  .../Library/PcieCoreLib/PcieCore.c            | 1266 ++++
>  .../Library/PcieCoreLib/PcieCoreLib.c         |  536 ++
>  .../Library/PcieCoreLib/PciePatchAcpi.c       |  610 ++
>  .../Library/PlatformPeiLib/PlatformPeiLib.c   |   40 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.c    |  141 +
>  .../SystemFirmwareInterfaceLib.c              |  328 +
>  .../AmpereAltraPkg/Library/TrngLib/TrngLib.c  |   63 +
>  .../LinuxBootBootManagerLib/LinuxBootBm.c     |  173 +
>  .../Library/PlatformUiLib/PlatformManager.c   |  354 ++
>  .../Ampere/AmperePlatformPkg/FvRules.fdf.inc  |  176 +
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi | 5639 +++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi | 5639 +++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU.asi    |  127 +
>  Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl   |  575 ++
>  .../Ampere/JadePkg/AcpiTables/PCI-PDRC.asi    |  217 +
>  .../JadePkg/AcpiTables/PCI-S0.Rca01.asi       |  681 ++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi | 2078 ++++++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi | 2087 ++++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi | 1303 ++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi | 1303 ++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU.asi    |   10 +
>  Platform/Ampere/JadePkg/JadeBoardSetting.cfg  |  209 +
>  .../Library/PcieBoardLib/PcieBoardScreen.uni  |   99 +
>  .../Ampere/LinuxBootPkg/AArch64/Readme.md     |   29 +
>  .../AmpereAltraPkg/AcpiCommonTables/Bert.aslc |   33 +
>  .../AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc |   87 +
>  .../AmpereAltraPkg/AcpiCommonTables/Einj.asl  |  165 +
>  .../AmpereAltraPkg/AcpiCommonTables/Fadt.aslc |   87 +
>  .../AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc |  180 +
>  .../AmpereAltraPkg/AcpiCommonTables/Hest.asl  |  330 +
>  .../AmpereAltraPkg/AcpiCommonTables/Sdei.asl  |   17 +
>  .../AmpereAltraPkg/AcpiCommonTables/Spcr.aslc |   81 +
>  .../AmpereAltraPkg/AcpiCommonTables/Ssdt.asl  |   15 +
>  .../Drivers/AcpiConfigDxe/VfrStrings.uni      |   27 +
>  .../BootProgressDxe/BootProgressDxe.uni       |   16 +
>  .../BootProgressPeim/BootProgressPeim.uni     |   18 +
>  .../Drivers/CpuConfigDxe/VfrStrings.uni       |   17 +
>  .../Drivers/MemInfoDxe/MemInfoDxe.uni         |    9 +
>  .../Drivers/MemInfoDxe/MemInfoDxeExtra.uni    |    9 +
>  .../MemInfoDxe/MemInfoScreenStrings.uni       |   64 +
>  .../PcieDeviceConfigDxe.uni                   |   24 +
>  .../Drivers/PlatformInfoDxe/VfrStrings.uni    |   56 +
>  .../Drivers/RasConfigDxe/VfrStrings.uni       |   38 +
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni  |   10 +
>  .../Drivers/RngDxe/RngDxeExtra.uni            |    9 +
>  .../Drivers/WatchdogConfigDxe/VfrStrings.uni  |   26 +
>  .../ArmPlatformLib/ArmPlatformHelper.S        |   45 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.uni  |   13 +
>  .../PlatformUiLib/PlatformManagerStrings.uni  |   21 +
>  .../PlatformUiLib/PlatformManagerUiLib.uni    |   13 +
>  .../PlatformUiLib/PlatformManagerVfr.Vfr      |   29 +
>  226 files changed, 60803 insertions(+)
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>  create mode 100755 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>  create mode 100755 Platform/Ampere/JadePkg/Jade.dsc
>  create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
>  create mode 100755 Platform/Ampere/JadePkg/Jade.fdf
>  create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>  create mode 100755 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
>  create mode 100644 Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
>  create mode 100755 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PMU.asi
>  create mode 100644 Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
>  create mode 100644 Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
> 
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform
  2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
                   ` (33 preceding siblings ...)
  2021-05-27 12:56 ` [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. " Leif Lindholm
@ 2021-06-04 13:54 ` Leif Lindholm
  34 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 13:54 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Hi Nhi,

Apologies, this dragged out a bit longer than I intended.

Some high-level comments before I get into the contents:
In order to build this against current upstream, I needed to go back
to edk2 commit
c1aa3bab1259 ("BaseTools: Add ClangBase.lds for CLANG8 tool chain with
max-page-size")
That is not a bug with this platform, and affects other existing
platforms as well.

I noticed some of the source files have been added with execute
permissions (100755):
Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
Platform/Ampere/JadePkg/AcpiTables/CPU.asi
Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
Platform/Ampere/JadePkg/Jade.dsc
Platform/Ampere/JadePkg/Jade.fdf
Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec

Can this please be addressed for a v3?
Everything not executable should be created as 100644.


Next, the following delta is required:
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 023f2e898d7f..e8bda38ce0d1 100755
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -62,6 +62,8 @@ [Defines]
   DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS      = TRUE
   DEFINE NETWORK_TLS_ENABLE                  = FALSE

+!include MdePkg/MdeLibs.dsc.inc
+
 # Include default Ampere Platform DSC file
  !include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc


this should also protect against further breakdown of MdePkg libraries.


Finally, building with clang (the CLANG38 profile) reveals a few
genuine used-but-not-set issues in the code, which GCC lets through.
I would recommend test building also with CLANG38 for v3.

Best Regards,

Leif

On Wed, May 26, 2021 at 17:06:51 +0700, Nhi Pham wrote:
> This patch series adds the support for the Mt. Jade platform based on Ampere's
> Altra Family Processor.
> 
> Notes:
>   + The current patch series was tested with the edk2-stable202102 tag.
>   + The IASL compiler version 20201217 is required to build.
>   + The edk2-non-osi source is required to build.
> 
> You can get code from
> https://github.com/AmpereComputing/edk2-platforms/tree/ampere-upstream-wip-v2
> 
> Cc: Vu Nguyen <vunguyen@os.amperecomputing.com>
> Cc: Nhi Pham <nhi@os.amperecomputing.com>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> 
> Changes since v1:
>   + Addressed all Leif's feedback in the thread
>   https://edk2.groups.io/g/devel/message/70356.
>   + Removed the LinuxBoot image as Leif's feedback in the thread
>   https://edk2.groups.io/g/devel/message/68717. The image will be
>   pre-produced by users as the instruction in the README before compiling.
>   + Other major code improvements from in-house review:
>     * Create new AmperePlatformPkg and AmpereSiliconPkg packages for
>     containing common Platform/Silicon modules.
>     * Remove SMProLib and PMProLib libraries which are replaced by the
>     MailboxInterfaceLib and SystemFirmwareInterfaceLib libraries for the
>     communication interface between UEFI and System Firmware.
>     * Clean up and fix coding styles to conform to EDK II C Coding
>     Standards Specification.
> 
> Nhi Pham (10):
>   AmperePlatformPkg: Implement FailSafe library
>   AmperePlatformPkg: Add FailSafe and WDT support
>   AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table
>   AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table
>   AmpereAltraPkg, JadePkg: Add ACPI support
>   JadePkg: Add ASpeed GOP driver
>   AmpereAltraPkg: Add configuration screen for ACPI
>   AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
>   Platform/Ampere: Introduce the LinuxBootPkg
>   AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade
>     platform
> 
> Quan Nguyen (3):
>   AmpereAltraPkg: Add BootProgress support
>   JadePkg: Add SMBIOS tables support
>   AmpereAltraPkg: Add configuration screen for RAS
> 
> Vu Nguyen (19):
>   Ampere: Initial support for Ampere Altra processor and Mt. Jade
>     platform
>   AmpereAltraPkg: Add MmCommunication modules
>   AmpereAltraPkg: Add DwI2cLib library
>   AmpereAltraPkg: Add DwGpioLib library
>   JadePkg: Implement RealTimeClockLib for PCF85063
>   AmpereAltraPkg: Support non-volatile variables
>   AmpereSiliconPkg: Add PlatformManagerUiLib library instance
>   AmpereAltraPkg: Add PcieCoreLib library instance
>   JadePkg: Add PcieBoardLib library instance
>   AmpereAltraPkg: Add PciHostBridge driver
>   JadePkg: Enable PCIe-related libraries and device drivers
>   AmpereAltraPkg: Add Random Number Generator Support
>   AmpereAltraPkg: Add DebugInfoPei module
>   AmpereAltraPkg: Add platform info screen
>   AmpereAltraPkg: Add configuration screen for memory
>   AmpereAltraPkg: Add configuration screen for CPU
>   AmpereAltraPkg: Add configuration screen for Watchdog timer
>   AmpereAltraPkg: Add configuration screen for Pcie Devices
>   JadePkg: Recover boot options when NVRAM cleared
> 
>  .../AmperePlatformPkg/AmperePlatformPkg.dec   |   31 +
>  .../Ampere/AmpereAltraPkg/AmpereAltraPkg.dec  |   72 +
>  .../AmpereSiliconPkg/AmpereSiliconPkg.dec     |   85 +
>  .../AmpereAltraLinuxBootPkg.dsc.inc           |  550 ++
>  .../AmpereAltraPkg/AmpereAltraPkg.dsc.inc     |  736 +++
>  Platform/Ampere/JadePkg/Jade.dsc              |  192 +
>  Platform/Ampere/JadePkg/JadeLinuxBoot.dsc     |   90 +
>  Platform/Ampere/JadePkg/Jade.fdf              |  369 ++
>  Platform/Ampere/JadePkg/JadeLinuxBoot.fdf     |  201 +
>  .../Drivers/FailSafeDxe/FailSafeDxe.inf       |   54 +
>  .../Library/AcpiHelperLib/AcpiHelperLib.inf   |   33 +
>  .../Library/AcpiPccLib/AcpiPccLib.inf         |   41 +
>  .../Library/FailSafeLib/FailSafeLib.inf       |   41 +
>  .../Ampere/JadePkg/AcpiTables/AcpiTables.inf  |   20 +
>  .../AcpiPlatformDxe/AcpiPlatformDxe.inf       |   76 +
>  .../BootOptionsRecoveryDxe.inf                |   39 +
>  .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf     |   45 +
>  .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf     |   45 +
>  .../SmbiosPlatformDxe/SmbiosPlatformDxe.inf   |   52 +
>  .../PCF85063RealTimeClockLib.inf              |   44 +
>  .../Library/PcieBoardLib/PcieBoardLib.inf     |   60 +
>  Platform/Ampere/LinuxBootPkg/LinuxBoot.inf    |   17 +
>  .../AcpiCommonTables/AcpiCommonTables.inf     |   44 +
>  .../Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   56 +
>  .../Drivers/ATFHobPei/ATFHobPeim.inf          |   41 +
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.inf   |   56 +
>  .../BootProgressDxe/BootProgressDxe.inf       |   51 +
>  .../BootProgressPeim/BootProgressPeim.inf     |   49 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.inf     |   58 +
>  .../Drivers/DebugInfoPei/DebugInfoPei.inf     |   41 +
>  .../Drivers/FlashFvbDxe/FlashFvbDxe.inf       |   54 +
>  .../Drivers/FlashPei/FlashPei.inf             |   51 +
>  .../Drivers/MemInfoDxe/MemInfoDxe.inf         |   59 +
>  .../Drivers/MemoryInitPeim/MemoryInitPeim.inf |   64 +
>  .../MmCommunicationDxe/MmCommunication.inf    |   57 +
>  .../MmCommunicationPei/MmCommunicationPei.inf |   34 +
>  .../PcieDeviceConfigDxe.inf                   |   59 +
>  .../PlatformInfoDxe/PlatformInfoDxe.inf       |   52 +
>  .../Drivers/RasConfigDxe/RasConfigDxe.inf     |   56 +
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf  |   43 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.inf   |   50 +
>  .../Library/AmpereCpuLib/AmpereCpuLib.inf     |   44 +
>  .../Library/ArmPlatformLib/ArmPlatformLib.inf |   57 +
>  .../Library/DwGpioLib/DwGpioLib.inf           |   33 +
>  .../Library/DwI2cLib/DwI2cLib.inf             |   38 +
>  .../Library/FlashLib/FlashLib.inf             |   36 +
>  .../MailboxInterfaceLib.inf                   |   37 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.inf     |   63 +
>  .../MmCommunicationLib/MmCommunicationLib.inf |   35 +
>  .../Library/NVParamLib/NVParamLib.inf         |   32 +
>  .../Library/PcieCoreLib/PcieCoreLib.inf       |   68 +
>  .../Library/PlatformPeiLib/PlatformPeiLib.inf |   42 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.inf  |   29 +
>  .../SystemFirmwareInterfaceLib.inf            |   30 +
>  .../Library/TrngLib/TrngLib.inf               |   29 +
>  .../LinuxBootBootManagerLib.inf               |   54 +
>  .../PlatformUiLib/PlatformManagerUiLib.inf    |   47 +
>  .../Drivers/FailSafeDxe/FailSafe.h            |   20 +
>  .../Drivers/FailSafeDxe/Watchdog.h            |   29 +
>  .../Include/Library/FailSafeLib.h             |   62 +
>  .../Drivers/AcpiPlatformDxe/AcpiApei.h        |  123 +
>  .../Drivers/AcpiPlatformDxe/AcpiNfit.h        |   49 +
>  .../Drivers/AcpiPlatformDxe/AcpiPlatform.h    |   76 +
>  .../PCF85063RealTimeClockLib/PCF85063.h       |   91 +
>  .../Library/PcieBoardLib/NVDataStruc.h        |   89 +
>  .../Library/PcieBoardLib/PcieBoardScreen.h    |  138 +
>  .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h  |  451 ++
>  .../Pci/PciHostBridgeDxe/PciRootBridgeIo.h    |  554 ++
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.h     |   85 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.h       |   74 +
>  .../Drivers/CpuConfigDxe/NVDataStruc.h        |   19 +
>  .../Drivers/MemInfoDxe/MemInfoScreen.h        |  168 +
>  .../Drivers/MemInfoDxe/NVDataStruc.h          |   47 +
>  .../MmCommunicationDxe/MmCommunicate.h        |   22 +
>  .../Drivers/PcieDeviceConfigDxe/NVDataStruc.h |   56 +
>  .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.h |   78 +
>  .../Drivers/PcieDeviceConfigDxe/PcieHelper.h  |   58 +
>  .../Drivers/PlatformInfoDxe/PlatformInfoHii.h |   22 +
>  .../Drivers/RasConfigDxe/NVDataStruc.h        |   46 +
>  .../Drivers/RasConfigDxe/RasConfigDxe.h       |   82 +
>  .../Drivers/WatchdogConfigDxe/NVDataStruc.h   |   27 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.h     |   82 +
>  .../AmpereAltraPkg/Include/AcpiHeader.h       |   37 +
>  .../AmpereAltraPkg/Include/AcpiNVDataStruc.h  |   28 +
>  .../Include/Guid/AcpiConfigFormSet.h          |   19 +
>  .../Include/Guid/CpuConfigHii.h               |   19 +
>  .../Include/Guid/PcieDeviceConfigHii.h        |   19 +
>  .../Include/Guid/PlatformInfoHobGuid.h        |   17 +
>  .../Include/Guid/WatchdogConfigHii.h          |   19 +
>  .../Include/Library/AmpereCpuLib.h            |  282 +
>  .../AmpereAltraPkg/Include/Library/FlashLib.h |   42 +
>  .../AmpereAltraPkg/Include/Library/GpioLib.h  |   76 +
>  .../AmpereAltraPkg/Include/Library/I2cLib.h   |  100 +
>  .../Include/Library/MailboxInterfaceLib.h     |  172 +
>  .../Include/Library/MmCommunicationLib.h      |   19 +
>  .../Include/Library/NVParamLib.h              |  133 +
>  .../Include/Library/PcieBoardLib.h            |  102 +
>  .../Include/Library/PcieCoreLib.h             |  164 +
>  .../Library/SystemFirmwareInterfaceLib.h      |  282 +
>  .../AmpereAltraPkg/Include/Library/TrngLib.h  |   31 +
>  Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h |   79 +
>  .../AmpereAltraPkg/Include/NVParamDef.h       |  515 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h  |  203 +
>  .../AmpereAltraPkg/Include/Platform/Ac01.h    |  146 +
>  .../AmpereAltraPkg/Include/PlatformInfoHob.h  |  182 +
>  .../Library/PcieCoreLib/PcieCore.h            |  582 ++
>  .../Library/PcieCoreLib/PcieCoreCapCfg.h      |   64 +
>  .../Library/PcieCoreLib/PciePatchAcpi.h       |   30 +
>  .../Include/Guid/PlatformManagerHii.h         |   31 +
>  .../Include/Library/AcpiHelperLib.h           |  109 +
>  .../Include/Library/AcpiPccLib.h              |  166 +
>  .../Library/PlatformUiLib/PlatformManager.h   |   51 +
>  .../PlatformUiLib/PlatformManagerVfr.h        |   28 +
>  .../JadePkg/Library/PcieBoardLib/Vfr.vfr      |  212 +
>  .../Drivers/AcpiConfigDxe/Vfr.vfr             |   69 +
>  .../Drivers/CpuConfigDxe/Vfr.vfr              |   43 +
>  .../AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr |   62 +
>  .../Drivers/PcieDeviceConfigDxe/Vfr.vfr       |   50 +
>  .../Drivers/PlatformInfoDxe/Vfr.vfr           |  112 +
>  .../Drivers/RasConfigDxe/Vfr.vfr              |  105 +
>  .../Drivers/WatchdogConfigDxe/Vfr.vfr         |   58 +
>  .../Drivers/FailSafeDxe/FailSafeDxe.c         |  184 +
>  .../Drivers/FailSafeDxe/Watchdog.c            |  357 ++
>  .../Library/AcpiHelperLib/AcpiHelperLib.c     |  246 +
>  .../Library/AcpiPccLib/AcpiPccLib.c           |  241 +
>  .../Library/FailSafeLib/FailSafeLib.c         |  320 +
>  .../Drivers/AcpiPlatformDxe/AcpiApei.c        |  476 ++
>  .../Drivers/AcpiPlatformDxe/AcpiDsdt.c        |  445 ++
>  .../Drivers/AcpiPlatformDxe/AcpiMadt.c        |  351 +
>  .../Drivers/AcpiPlatformDxe/AcpiNfit.c        |  599 ++
>  .../Drivers/AcpiPlatformDxe/AcpiPcct.c        |  196 +
>  .../Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c |  178 +
>  .../Drivers/AcpiPlatformDxe/AcpiPptt.c        |  378 ++
>  .../Drivers/AcpiPlatformDxe/AcpiSlit.c        |  190 +
>  .../Drivers/AcpiPlatformDxe/AcpiSrat.c        |  274 +
>  .../BootOptionsRecoveryDxe.c                  |   58 +
>  .../Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c       |  709 +++
>  .../SmbiosMemInfoDxe/SmbiosMemInfoDxe.c       |  705 +++
>  .../SmbiosPlatformDxe/SmbiosPlatformDxe.c     | 1049 +++
>  .../PCF85063RealTimeClockLib/PCF85063.c       |  317 +
>  .../PCF85063RealTimeClockLib.c                |  257 +
>  .../JadePkg/Library/PcieBoardLib/PcieBoard.c  |  438 ++
>  .../Library/PcieBoardLib/PcieBoardCommon.c    |  327 +
>  .../Library/PcieBoardLib/PcieBoardScreen.c    | 1120 ++++
>  .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 1419 +++++
>  .../Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 1582 +++++
>  .../Drivers/ATFHobPei/ATFHobPeim.c            |   52 +
>  .../Drivers/AcpiConfigDxe/AcpiConfigDxe.c     |  733 +++
>  .../BootProgressDxe/BootProgressDxe.c         |  211 +
>  .../BootProgressPeim/BootProgressPeim.c       |  210 +
>  .../Drivers/CpuConfigDxe/CpuConfigDxe.c       |  508 ++
>  .../Drivers/DebugInfoPei/DebugInfoPei.c       |  230 +
>  .../Drivers/FlashFvbDxe/FlashFvbDxe.c         |  525 ++
>  .../Drivers/FlashPei/FlashPei.c               |  283 +
>  .../Drivers/MemInfoDxe/MemInfoNvramLib.c      |  394 ++
>  .../Drivers/MemInfoDxe/MemInfoScreen.c        | 1325 ++++
>  .../Drivers/MemoryInitPeim/MemoryInitPeim.c   |  151 +
>  .../MmCommunicationDxe/MmCommunication.c      |  454 ++
>  .../MmCommunicationPei/MmCommunicationPei.c   |   37 +
>  .../PcieDeviceConfigDxe/PcieDeviceConfigDxe.c | 1046 +++
>  .../Drivers/PcieDeviceConfigDxe/PcieHelper.c  |  191 +
>  .../Drivers/PlatformInfoDxe/PlatformInfoDxe.c |  391 ++
>  .../Drivers/RasConfigDxe/RasConfigDxe.c       |  762 +++
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.c    |  164 +
>  .../WatchdogConfigDxe/WatchdogConfigDxe.c     |  460 ++
>  .../Library/AmpereCpuLib/AmpereCpuLib.c       |  706 +++
>  .../Library/ArmPlatformLib/ArmPlatformLib.c   |  169 +
>  .../ArmPlatformLib/ArmPlatformLibMemory.c     |  399 ++
>  .../Library/DwGpioLib/DwGpioLib.c             |  314 +
>  .../Library/DwI2cLib/DwI2cLib.c               |  883 +++
>  .../Library/FlashLib/FlashLib.c               |  358 ++
>  .../MailboxInterfaceLib/MailboxInterfaceLib.c |  282 +
>  .../MemoryInitPeiLib/MemoryInitPeiLib.c       |   93 +
>  .../MmCommunicationLib/MmCommunicationLib.c   |  184 +
>  .../Library/NVParamLib/NVParamLib.c           |  202 +
>  .../Library/PcieCoreLib/PcieCore.c            | 1266 ++++
>  .../Library/PcieCoreLib/PcieCoreLib.c         |  536 ++
>  .../Library/PcieCoreLib/PciePatchAcpi.c       |  610 ++
>  .../Library/PlatformPeiLib/PlatformPeiLib.c   |   40 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.c    |  141 +
>  .../SystemFirmwareInterfaceLib.c              |  328 +
>  .../AmpereAltraPkg/Library/TrngLib/TrngLib.c  |   63 +
>  .../LinuxBootBootManagerLib/LinuxBootBm.c     |  173 +
>  .../Library/PlatformUiLib/PlatformManager.c   |  354 ++
>  .../Ampere/AmperePlatformPkg/FvRules.fdf.inc  |  176 +
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi | 5639 +++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi | 5639 +++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU.asi    |  127 +
>  Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl   |  575 ++
>  .../Ampere/JadePkg/AcpiTables/PCI-PDRC.asi    |  217 +
>  .../JadePkg/AcpiTables/PCI-S0.Rca01.asi       |  681 ++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi | 2078 ++++++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi | 2087 ++++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi | 1303 ++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi | 1303 ++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU.asi    |   10 +
>  Platform/Ampere/JadePkg/JadeBoardSetting.cfg  |  209 +
>  .../Library/PcieBoardLib/PcieBoardScreen.uni  |   99 +
>  .../Ampere/LinuxBootPkg/AArch64/Readme.md     |   29 +
>  .../AmpereAltraPkg/AcpiCommonTables/Bert.aslc |   33 +
>  .../AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc |   87 +
>  .../AmpereAltraPkg/AcpiCommonTables/Einj.asl  |  165 +
>  .../AmpereAltraPkg/AcpiCommonTables/Fadt.aslc |   87 +
>  .../AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc |  180 +
>  .../AmpereAltraPkg/AcpiCommonTables/Hest.asl  |  330 +
>  .../AmpereAltraPkg/AcpiCommonTables/Sdei.asl  |   17 +
>  .../AmpereAltraPkg/AcpiCommonTables/Spcr.aslc |   81 +
>  .../AmpereAltraPkg/AcpiCommonTables/Ssdt.asl  |   15 +
>  .../Drivers/AcpiConfigDxe/VfrStrings.uni      |   27 +
>  .../BootProgressDxe/BootProgressDxe.uni       |   16 +
>  .../BootProgressPeim/BootProgressPeim.uni     |   18 +
>  .../Drivers/CpuConfigDxe/VfrStrings.uni       |   17 +
>  .../Drivers/MemInfoDxe/MemInfoDxe.uni         |    9 +
>  .../Drivers/MemInfoDxe/MemInfoDxeExtra.uni    |    9 +
>  .../MemInfoDxe/MemInfoScreenStrings.uni       |   64 +
>  .../PcieDeviceConfigDxe.uni                   |   24 +
>  .../Drivers/PlatformInfoDxe/VfrStrings.uni    |   56 +
>  .../Drivers/RasConfigDxe/VfrStrings.uni       |   38 +
>  .../AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni  |   10 +
>  .../Drivers/RngDxe/RngDxeExtra.uni            |    9 +
>  .../Drivers/WatchdogConfigDxe/VfrStrings.uni  |   26 +
>  .../ArmPlatformLib/ArmPlatformHelper.S        |   45 +
>  .../AmpereAltraPkg/Library/RngLib/RngLib.uni  |   13 +
>  .../PlatformUiLib/PlatformManagerStrings.uni  |   21 +
>  .../PlatformUiLib/PlatformManagerUiLib.uni    |   13 +
>  .../PlatformUiLib/PlatformManagerVfr.Vfr      |   29 +
>  226 files changed, 60803 insertions(+)
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>  create mode 100755 Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>  create mode 100755 Platform/Ampere/JadePkg/Jade.dsc
>  create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
>  create mode 100755 Platform/Ampere/JadePkg/Jade.fdf
>  create mode 100755 Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>  create mode 100755 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
>  create mode 100644 Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>  create mode 100755 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
>  create mode 100755 Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
>  create mode 100644 Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/CPU.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
>  create mode 100755 Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
>  create mode 100644 Platform/Ampere/JadePkg/AcpiTables/PMU.asi
>  create mode 100644 Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>  create mode 100644 Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
>  create mode 100644 Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
>  create mode 100755 Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S
>  create mode 100644 Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
>  create mode 100644 Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
> 
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and Mt. Jade platform
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
@ 2021-06-04 23:04   ` Leif Lindholm
  2021-06-09  4:50     ` Nhi Pham
  2021-06-15 16:46     ` Nhi Pham
  0 siblings, 2 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:04 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:52 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This commit adds the support for Ampere’s Altra processor-based Mt. Jade
> platform that provides up to 160 processor cores in a dual socket
> configuration. The essential modules are wired up enough to boot system
> to EDK2 UiApp.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec                                         |  28 +
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                                |  42 ++
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                                            |  46 ++
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                            | 674 +++++++++++++++++++
>  Platform/Ampere/JadePkg/Jade.dsc                                                                | 100 +++
>  Platform/Ampere/JadePkg/Jade.fdf                                                                | 225 +++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf                                  |  41 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf                         |  64 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf                             |  44 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf                         |  57 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf               |  37 +
>  Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf                     |  63 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf                 |  35 +
>  Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf                                 |  32 +
>  Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf                         |  42 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf                                         |  29 +
>  Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf |  30 +
>  Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf                                       |  29 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h                                |  17 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h                                    | 282 ++++++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h                             | 172 +++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h                              |  19 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h                                      | 133 ++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h                      | 282 ++++++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h                                         |  31 +
>  Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h                                                   |  79 +++
>  Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h                                              | 515 ++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h                                           | 146 ++++
>  Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h                                         | 182 +++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c                                    |  52 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c                           | 151 +++++
>  Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c                               | 706 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c                           | 169 +++++
>  Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c                     | 399 +++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c                 | 282 ++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c                       |  93 +++
>  Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c                   | 184 +++++
>  Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c                                   | 202 ++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c                           |  40 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c                                           | 141 ++++
>  Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c   | 328 +++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c                                         |  63 ++
>  Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc                                               | 176 +++++
>  Platform/Ampere/JadePkg/JadeBoardSetting.cfg                                                    | 209 ++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S                        |  45 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni                                         |  13 +
>  46 files changed, 6729 insertions(+)
> 

> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> new file mode 100755
> index 000000000000..f68af24a0d78
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -0,0 +1,100 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = Jade
> +  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x0001001B
> +  OUTPUT_DIRECTORY               = Build/Jade
> +  SUPPORTED_ARCHITECTURES        = AARCH64
> +  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
> +  SKUID_IDENTIFIER               = DEFAULT
> +  FLASH_DEFINITION               = Platform/Ampere/JadePkg/Jade.fdf
> +
> +  #
> +  # Defines for default states. These can be changed on the command line.
> +  # -D FLAG=VALUE
> +  #
> +
> +  #  DEBUG_INIT      0x00000001  // Initialization
> +  #  DEBUG_WARN      0x00000002  // Warnings
> +  #  DEBUG_LOAD      0x00000004  // Load events
> +  #  DEBUG_FS        0x00000008  // EFI File system
> +  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
> +  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
> +  #  DEBUG_INFO      0x00000040  // Informational debug messages
> +  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
> +  #  DEBUG_VARIABLE  0x00000100  // Variable
> +  #  DEBUG_BM        0x00000400  // Boot Manager
> +  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
> +  #  DEBUG_NET       0x00004000  // SNP Driver
> +  #  DEBUG_UNDI      0x00010000  // UNDI Driver
> +  #  DEBUG_LOADFILE  0x00020000  // LoadFile
> +  #  DEBUG_EVENT     0x00080000  // Event messages
> +  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
> +  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
> +  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
> +  #                              // significantly impact boot performance
> +  #  DEBUG_ERROR     0x80000000  // Error
> +  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
> +  DEFINE FIRMWARE_VER            = 0.01.001
> +  DEFINE EDK2_SKIP_PEICORE       = TRUE
> +  DEFINE SECURE_BOOT_ENABLE      = FALSE
> +  DEFINE INCLUDE_TFTP_COMMAND    = TRUE
> +
> +  #
> +  # Network definition
> +  #
> +  DEFINE NETWORK_IP6_ENABLE                  = FALSE
> +  DEFINE NETWORK_HTTP_BOOT_ENABLE            = TRUE
> +  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS      = TRUE
> +  DEFINE NETWORK_TLS_ENABLE                  = FALSE
> +

You'll want to include that !include MdePkg/MdeLibs.dsc.inc bit
somewhere here.

> +# Include default Ampere Platform DSC file
> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +
> +################################################################################
> +#
> +# Specific Platform Library
> +#
> +################################################################################
> +[LibraryClasses]
> +  #
> +  # RTC Library: Common RTC
> +  #
> +  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
> +
> +################################################################################
> +#
> +# Specific Platform Pcds
> +#
> +################################################################################
> +[PcdsFeatureFlag.common]
> +[PcdsFixedAtBuild.common]
> +
> +!if $(SECURE_BOOT_ENABLE) == TRUE
> +  # Override the default values from SecurityPkg to ensure images
> +  # from all sources are verified in secure boot
> +  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
> +  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
> +  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
> +!endif
> +
> +
> +################################################################################
> +#
> +# Specific Platform Component
> +#
> +################################################################################
> +[Components.common]



> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
> new file mode 100644
> index 000000000000..de576474fb48
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
> @@ -0,0 +1,282 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef AMPERE_CPU_LIB_H_
> +#define AMPERE_CPU_LIB_H_
> +
> +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
> +#define CLIDR_CTYPE_SHIFT(Level)    (3 * (Level - 1))
> +#define CLIDR_CTYPE_MASK(Level)     (7 << CLIDR_CTYPE_SHIFT(Level))
> +#define CLIDR_CTYPE(Clidr, Level) \
> +  (((Clidr) & CLIDR_CTYPE_MASK(Level)) >> CLIDR_CTYPE_SHIFT(Level))
> +
> +#define CCSIDR_NUMSETS_SHIFT        13
> +#define CCSIDR_NUMSETS_MASK         0xFFFE000
> +#define CCSIDR_NUMSETS(Ccsidr) \
> +  (((Ccsidr) & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT)
> +#define CCSIDR_ASSOCIATIVITY_SHIFT  3
> +#define CCSIDR_ASSOCIATIVITY_MASK   0x1FF8
> +#define CCSIDR_ASSOCIATIVITY(Ccsidr) \
> +  (((Ccsidr) & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_SHIFT)
> +#define CCSIDR_LINE_SIZE_SHIFT      0
> +#define CCSIDR_LINE_SIZE_MASK       0x7
> +#define CCSIDR_LINE_SIZE(Ccsidr) \
> +  (((Ccsidr) & CCSIDR_LINE_SIZE_MASK) >> CCSIDR_LINE_SIZE_SHIFT)

All of the above (CLIDR/CCSIDR) are architectural.
We've also developed some new accessors and stuff for these, as part
of ArmPkg/Universal/SmbiosDxe work that's gone on since v1 of this set.
We may need to clean some interfaces up, but ideally I'd prefer if you
could use some accessors from ArmLib or such.

> +
> +#define SUBNUMA_MODE_MONOLITHIC        0
> +#define SUBNUMA_MODE_HEMISPHERE        1
> +#define SUBNUMA_MODE_QUADRANT          2
> +
> +#define MONOLITIC_NUM_OF_REGION        1
> +#define HEMISPHERE_NUM_OF_REGION       2
> +#define QUADRANT_NUM_OF_REGION         4
> +#define SUBNUMA_CPM_REGION_SIZE        4
> +#define NUM_OF_CPM_PER_MESH_ROW        8
> +
> +#define CPM_PER_ROW_OFFSET(CpmId)      ((CpmId) % NUM_OF_CPM_PER_MESH_ROW)
> +#define CPM_ROW_NUMBER(CpmId)          ((CpmId) / NUM_OF_CPM_PER_MESH_ROW)
> +
> +#define SOCKET_ID(CpuId)               ((CpuId) / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM))
> +#define CLUSTER_ID(CpuId)              (((CpuId) / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM)
> +
> +
> +/**
> +  Get the SubNUMA mode.
> +
> +  @return   UINT8      The SubNUMA mode.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetSubNumaMode (
> +  VOID
> +  );
> +
> +/**
> +  Get the number of SubNUMA region.
> +
> +  @return   UINT8      The number of SubNUMA region.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetNumberOfSubNumaRegion (
> +  VOID
> +  );
> +
> +/**
> +  Get the SubNUMA node of a CPM.
> +
> +  @param    SocketId    Socket index.
> +  @param    Cpm         CPM index.
> +  @return   UINT8       The SubNUMA node of a CPM.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetSubNumNode (
> +  UINT8  Socket,
> +  UINT16 Cpm
> +  );
> +
> +/**
> +  Get the associativity of cache.
> +
> +  @param    Level       Cache level.
> +  @return   UINT32      Associativity of cache.
> +
> +**/
> +UINT32
> +EFIAPI
> +CpuGetAssociativity (
> +  UINT32 Level
> +  );
> +
> +/**
> +  Get the cache size.
> +
> +  @param    Level       Cache level.
> +  @return   UINT32      Cache size.
> +
> +**/
> +UINT32
> +EFIAPI
> +CpuGetCacheSize (
> +  UINT32 Level
> +  );
> +
> +/**
> +  Get the number of supported socket.
> +
> +  @return   UINT8      Number of supported socket.
> +
> +**/
> +UINT8
> +EFIAPI
> +GetNumberOfSupportedSockets (
> +  VOID
> +  );
> +
> +/**
> +  Get the number of active socket.
> +
> +  @return   UINT8      Number of active socket.
> +
> +**/
> +UINT8
> +EFIAPI
> +GetNumberOfActiveSockets (
> +  VOID
> +  );
> +
> +/**
> +  Get the number of active CPM per socket.
> +
> +  @param    SocketId    Socket index.
> +  @return   UINT16      Number of CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCPMsPerSocket (
> +  UINT8 SocketId
> +  );
> +
> +/**
> +  Get the number of configured CPM per socket.
> +
> +  @param    SocketId    Socket index.
> +  @return   UINT16      Number of configured CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfConfiguredCPMs (
> +  UINT8 SocketId
> +  );
> +
> +/**
> +  Set the number of configured CPM per socket.
> +
> +  @param    SocketId        Socket index.
> +  @param    NumberOfCPMs    Number of CPM to be configured.
> +  @return   EFI_SUCCESS     Operation succeeded.
> +  @return   Others          An error has occurred.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetNumberOfConfiguredCPMs (
> +  UINT8  SocketId,
> +  UINT16 NumberOfCPMs
> +  );
> +
> +/**
> +  Get the maximum number of core per socket. This number
> +  should be the same for all sockets.
> +
> +  @return   UINT16      Maximum number of core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetMaximumNumberOfCores (
> +  VOID
> +  );
> +
> +/**
> +  Get the maximum number of CPM per socket. This number
> +  should be the same for all sockets.
> +
> +  @return   UINT32      Maximum number of CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetMaximumNumberOfCPMs (
> +  VOID
> +  );
> +
> +/**
> +  Get the number of active cores of a sockets.
> +
> +  @return   UINT16      Number of active core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCoresPerSocket (
> +  UINT8 SocketId
> +  );
> +
> +/**
> +  Get the number of active cores of all socket.
> +
> +  @return   UINT16      Number of active core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCores (
> +  VOID
> +  );
> +
> +/**
> +  Check if the logical CPU is enabled or not.
> +
> +  @param    CpuId       The logical Cpu ID. Started from 0.
> +  @return   BOOLEAN     TRUE if the Cpu enabled
> +                        FALSE if the Cpu disabled.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsCpuEnabled (
> +  UINT16 CpuId
> +  );
> +
> +
> +/**
> +  Check if the slave socket is present
> +
> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
> +                        FALSE if the Slave Cpu is not present
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsSlaveSocketPresent (
> +  VOID
> +  );
> +
> +/**
> +  Check if the slave socket is active
> +
> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
> +                        FALSE if the Slave CPU Socket is not active.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsSlaveSocketActive (
> +  VOID
> +  );
> +
> +/**
> +  Check if the CPU product ID is Ac01
> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
> +                        FALSE otherwise.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsAc01Processor (
> +  VOID
> +  );
> +
> +#endif /* AMPERE_CPU_LIB_H_ */


> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
> new file mode 100644
> index 000000000000..8da698e0b855
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
> @@ -0,0 +1,706 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmLib/ArmLibPrivate.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NVParamLib.h>
> +#include <NVParamDef.h>
> +#include <Platform/Ac01.h>
> +#include <PlatformInfoHob.h>
> +
> +STATIC PLATFORM_INFO_HOB *mPlatformInfoHob = NULL;
> +
> +PLATFORM_INFO_HOB *
> +GetPlatformHob (
> +  VOID
> +  )
> +{
> +  VOID *Hob;
> +
> +  if (mPlatformInfoHob == NULL) {
> +    Hob = GetNextGuidHob (
> +            &gPlatformHobGuid,
> +            (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase)
> +            );
> +    ASSERT (Hob != NULL);
> +    if (Hob == NULL) {
> +      DEBUG ((DEBUG_ERROR, "%a: Failed to get gPlatformHobGuid!\n", __FUNCTION__));
> +      return NULL;
> +    }
> +
> +    mPlatformInfoHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +  }
> +
> +  return mPlatformInfoHob;
> +}
> +
> +/**
> +  Get the SubNUMA mode.
> +
> +  @return   UINT8      The SubNUMA mode.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetSubNumaMode (
> +  VOID
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    return SUBNUMA_MODE_MONOLITHIC;
> +  }
> +
> +  return PlatformHob->SubNumaMode[0];
> +}
> +
> +/**
> +  Get the number of SubNUMA region.
> +
> +  @return   UINT8      The number of SubNUMA region.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetNumberOfSubNumaRegion (
> +  VOID
> +  )
> +{
> +  UINT8 SubNumaMode;
> +  UINT8 NumberOfSubNumaRegion;
> +
> +  SubNumaMode = CpuGetSubNumaMode ();
> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
> +
> +  switch (SubNumaMode) {
> +  case SUBNUMA_MODE_MONOLITHIC:
> +    NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION;
> +    break;
> +
> +  case SUBNUMA_MODE_HEMISPHERE:
> +    NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION;
> +    break;
> +
> +  case SUBNUMA_MODE_QUADRANT:
> +    NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION;
> +    break;
> +
> +  default:
> +    // Should never reach there.
> +    ASSERT (FALSE);
> +    break;
> +  }
> +
> +  return NumberOfSubNumaRegion;
> +}
> +
> +/**
> +  Get the SubNUMA node of a CPM.
> +
> +  @param    SocketId    Socket index.
> +  @param    Cpm         CPM index.
> +  @return   UINT8       The SubNUMA node of a CPM.
> +
> +**/
> +UINT8
> +EFIAPI
> +CpuGetSubNumNode (
> +  UINT8  SocketId,
> +  UINT16 Cpm
> +  )
> +{
> +  BOOLEAN IsAsymMesh;
> +  UINT8   SubNumaNode;
> +  UINT16  MaxNumberOfCPM;
> +  UINT8   MiddleRow;
> +  UINT8   QuadrantHigherRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {1, 1, 1, 1, 3, 3, 3, 3};
> +  UINT8   QuadrantLowerRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW]  = {0, 0, 0, 0, 2, 2, 2, 2};
> +  UINT8   QuadrantMiddleRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 1, 1, 3, 3, 2, 2};
> +  UINT8   SubNumaMode;
> +
> +  MaxNumberOfCPM = GetMaximumNumberOfCPMs ();
> +  SubNumaMode = CpuGetSubNumaMode ();
> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
> +
> +  switch (SubNumaMode) {
> +  case SUBNUMA_MODE_MONOLITHIC:
> +    SubNumaNode = (SocketId == 0) ? 0 : 1;
> +    break;
> +
> +  case SUBNUMA_MODE_HEMISPHERE:
> +    if (CPM_PER_ROW_OFFSET (Cpm) >= SUBNUMA_CPM_REGION_SIZE) {
> +      SubNumaNode = 1;
> +    } else {
> +      SubNumaNode = 0;
> +    }
> +
> +    if (SocketId == 1) {
> +      SubNumaNode += HEMISPHERE_NUM_OF_REGION;
> +    }
> +    break;
> +
> +  case SUBNUMA_MODE_QUADRANT:
> +    //
> +    // CPM Mesh Rows
> +    //
> +    // |---------------------------------------|
> +    // | 00 ----------- 03 | 04 ----------- 07 | Row 0
> +    // |-------------------|-------------------|
> +    // | 08 ----------- 11 | 12 ----------- 15 | Row 1
> +    // |-------------------|-------------------|
> +    // | 16 - 17 | 18 - 19 | 20 - 21 | 22 - 23 | Middle Row
> +    // |-------------------|-------------------|
> +    // | 24 ----------- 27 | 28 ----------- 31 | Row 3
> +    // |-------------------|-------------------|
> +    // | 32 ----------- 35 | 36 ----------- 39 | Row 4
> +    // |---------------------------------------|
> +    //
> +
> +    IsAsymMesh = (BOOLEAN)(CPM_ROW_NUMBER (MaxNumberOfCPM) % 2 != 0);
> +    MiddleRow = CPM_ROW_NUMBER (MaxNumberOfCPM) / 2;
> +    if (IsAsymMesh
> +        && CPM_ROW_NUMBER (Cpm) == MiddleRow)
> +    {
> +      SubNumaNode = QuadrantMiddleRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
> +
> +    } else if (CPM_ROW_NUMBER (Cpm) >= MiddleRow) {
> +      SubNumaNode = QuadrantHigherRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
> +
> +    } else {
> +      SubNumaNode = QuadrantLowerRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
> +    }
> +
> +    if (SocketId == 1) {
> +      SubNumaNode += QUADRANT_NUM_OF_REGION;
> +    }
> +    break;
> +
> +  default:
> +    // Should never reach there.
> +    ASSERT (FALSE);
> +    break;
> +  }
> +
> +  return SubNumaNode;
> +}
> +
> +/**
> +  Get the associativity of cache.
> +
> +  @param    Level       Cache level.
> +  @return   UINT32      Associativity of cache.
> +
> +**/
> +UINT32
> +EFIAPI
> +CpuGetAssociativity (
> +  UINT32 Level
> +  )
> +{

I do feel some of this stuff could be replaced by the common functions
we now have in ArmLib (that we didn't when v1 went out).

> +  UINT64 CacheCCSIDR;
> +  UINT64 CacheCLIDR;
> +  UINT32 Value = 0x2; /* Unknown Set-Associativity */
> +
> +  CacheCLIDR = ReadCLIDR ();
> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
> +    return Value;
> +  }
> +
> +  CacheCCSIDR = ReadCCSIDR (Level);
> +  switch (CCSIDR_ASSOCIATIVITY (CacheCCSIDR)) {
> +  case 0:
> +    /* Direct mapped */
> +    Value = 0x3;
> +    break;
> +
> +  case 1:
> +    /* 2-way Set-Associativity */
> +    Value = 0x4;
> +    break;
> +
> +  case 3:
> +    /* 4-way Set-Associativity */
> +    Value = 0x5;
> +    break;
> +
> +  case 7:
> +    /* 8-way Set-Associativity */
> +    Value = 0x7;
> +    break;
> +
> +  case 15:
> +    /* 16-way Set-Associativity */
> +    Value = 0x8;
> +    break;
> +
> +  case 11:
> +    /* 12-way Set-Associativity */
> +    Value = 0x9;
> +    break;
> +
> +  case 23:
> +    /* 24-way Set-Associativity */
> +    Value = 0xA;
> +    break;
> +
> +  case 31:
> +    /* 32-way Set-Associativity */
> +    Value = 0xB;
> +    break;
> +
> +  case 47:
> +    /* 48-way Set-Associativity */
> +    Value = 0xC;
> +    break;
> +
> +  case 63:
> +    /* 64-way Set-Associativity */
> +    Value = 0xD;
> +    break;
> +
> +  case 19:
> +    /* 20-way Set-Associativity */
> +    Value = 0xE;
> +    break;
> +  }
> +
> +  return Value;
> +}
> +
> +/**
> +  Get the cache size.
> +
> +  @param    Level       Cache level.
> +  @return   UINT32      Cache size.
> +
> +**/
> +UINT32
> +EFIAPI
> +CpuGetCacheSize (
> +  UINT32 Level
> +  )
> +{
> +  UINT32 CacheLineSize;
> +  UINT32 Count;
> +  UINT64 CacheCCSIDR;
> +  UINT64 CacheCLIDR;
> +
> +  CacheCLIDR = ReadCLIDR ();
> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
> +    return 0;
> +  }
> +
> +  CacheCCSIDR = ReadCCSIDR (Level);
> +  CacheLineSize = 1;
> +  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
> +  while (Count-- > 0) {
> +    CacheLineSize *= 2;
> +  }
> +
> +  return ((CCSIDR_NUMSETS (CacheCCSIDR) + 1) *
> +          (CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1) *
> +          CacheLineSize);
> +}
> +
> +/**
> +  Get the number of supported socket.
> +
> +  @return   UINT8      Number of supported socket.
> +
> +**/
> +UINT8
> +EFIAPI
> +GetNumberOfSupportedSockets (
> +  VOID
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    //
> +    // By default, the number of supported sockets is 1.
> +    //
> +    return 1;
> +  }
> +
> +  return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN));
> +}
> +
> +/**
> +  Get the number of active socket.
> +
> +  @return   UINT8      Number of active socket.
> +
> +**/
> +UINT8
> +EFIAPI
> +GetNumberOfActiveSockets (
> +  VOID
> +  )
> +{
> +  UINT8               NumberOfActiveSockets, Count, Index, Index1;
> +  PLATFORM_CLUSTER_EN *Socket;
> +  PLATFORM_INFO_HOB   *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    //
> +    // By default, the number of active sockets is 1.
> +    //
> +    return 1;
> +  }
> +
> +  NumberOfActiveSockets = 0;
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    Socket = &PlatformHob->ClusterEn[Index];
> +    Count = ARRAY_SIZE (Socket->EnableMask);
> +    for (Index1 = 0; Index1 < Count; Index1++) {
> +      if (Socket->EnableMask[Index1] != 0) {
> +        NumberOfActiveSockets++;
> +        break;
> +      }
> +    }
> +  }
> +
> +  return NumberOfActiveSockets;
> +}
> +
> +/**
> +  Get the number of active CPM per socket.
> +
> +  @param    SocketId    Socket index.
> +  @return   UINT16      Number of CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCPMsPerSocket (
> +  UINT8 SocketId
> +  )
> +{
> +  UINT16              NumberOfCPMs, Count, Index;
> +  UINT32              Val32;
> +  PLATFORM_CLUSTER_EN *Socket;
> +  PLATFORM_INFO_HOB   *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    return 0;
> +  }
> +
> +  if (SocketId >= GetNumberOfActiveSockets ()) {
> +    return 0;
> +  }
> +
> +  NumberOfCPMs = 0;
> +  Socket = &PlatformHob->ClusterEn[SocketId];
> +  Count = ARRAY_SIZE (Socket->EnableMask);
> +  for (Index = 0; Index < Count; Index++) {
> +    Val32 = Socket->EnableMask[Index];
> +    while (Val32 > 0) {
> +      if ((Val32 & 0x1) != 0) {
> +        NumberOfCPMs++;
> +      }
> +      Val32 >>= 1;
> +    }
> +  }
> +
> +  return NumberOfCPMs;
> +}
> +
> +/**
> +  Get the number of configured CPM per socket. This number
> +  should be the same for all sockets.
> +
> +  @param    SocketId    Socket index.
> +  @return   UINT8       Number of configured CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfConfiguredCPMs (
> +  UINT8 SocketId
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +  UINT32     Param, ParamStart, ParamEnd;
> +  UINT16     Count;
> +
> +  Count = 0;
> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
> +    Status = NVParamGet (
> +               Param,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               &Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +    while (Value != 0) {
> +      if ((Value & 0x01) != 0) {
> +        Count++;
> +      }
> +      Value >>= 1;
> +    }
> +  }
> +
> +  return Count;
> +}
> +
> +/**
> +  Set the number of configured CPM per socket.
> +
> +  @param    SocketId        Socket index.
> +  @param    NumberOfCPMs    Number of CPM to be configured.
> +  @return   EFI_SUCCESS     Operation succeeded.
> +  @return   Others          An error has occurred.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetNumberOfConfiguredCPMs (
> +  UINT8  SocketId,
> +  UINT16 NumberOfCPMs
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +  UINT32     Param, ParamStart, ParamEnd;
> +  BOOLEAN    IsClear;
> +
> +  IsClear = FALSE;
> +  if (NumberOfCPMs == 0) {
> +    IsClear = TRUE;
> +  }
> +
> +  Status = EFI_SUCCESS;
> +
> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
> +    if (NumberOfCPMs >= 32) {
> +      Value = 0xffffffff;
> +      NumberOfCPMs -= 32;
> +    } else {
> +      Value = 0;
> +      while (NumberOfCPMs > 0) {
> +        Value |= (1 << (--NumberOfCPMs));
> +      }
> +    }
> +    if (IsClear) {
> +      /* Clear this param */
> +      Status = NVParamClr (
> +                 Param,
> +                 NV_PERM_BIOS | NV_PERM_MANU
> +                 );
> +    } else {
> +      Status = NVParamSet (
> +                 Param,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 Value
> +                 );
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Get the maximum number of core per socket.
> +
> +  @return   UINT16      Maximum number of core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetMaximumNumberOfCores (
> +  VOID
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    return 0;
> +  }
> +
> +  return PlatformHob->MaxNumOfCore[0];
> +}
> +
> +/**
> +  Get the maximum number of CPM per socket. This number
> +  should be the same for all sockets.
> +
> +  @return   UINT16      Maximum number of CPM.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetMaximumNumberOfCPMs (
> +  VOID
> +  )
> +{
> +  return GetMaximumNumberOfCores () / PLATFORM_CPU_NUM_CORES_PER_CPM;
> +}
> +
> +/**
> +  Get the number of active cores of a sockets.
> +
> +  @param    SocketId    Socket Index.
> +  @return   UINT16      Number of active core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCoresPerSocket (
> +  UINT8 SocketId
> +  )
> +{
> +  return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM;
> +}
> +
> +/**
> +  Get the number of active cores of all sockets.
> +
> +  @return   UINT16      Number of active core.
> +
> +**/
> +UINT16
> +EFIAPI
> +GetNumberOfActiveCores (
> +  VOID
> +  )
> +{
> +  UINT16 NumberOfActiveCores;
> +  UINT8  Index;
> +
> +  NumberOfActiveCores = 0;
> +
> +  for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) {
> +    NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index);
> +  }
> +
> +  return NumberOfActiveCores;
> +}
> +
> +/**
> +  Check if the logical CPU is enabled or not.
> +
> +  @param    CpuId       The logical Cpu ID. Started from 0.
> +  @return   BOOLEAN     TRUE if the Cpu enabled
> +                        FALSE if the Cpu disabled.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsCpuEnabled (
> +  UINT16 CpuId
> +  )
> +{
> +  PLATFORM_CLUSTER_EN *Socket;
> +  PLATFORM_INFO_HOB   *PlatformHob;
> +  UINT8               SocketId;
> +  UINT16              ClusterId;
> +
> +  SocketId = SOCKET_ID (CpuId);
> +  ClusterId = CLUSTER_ID (CpuId);
> +
> +  PlatformHob = GetPlatformHob ();
> +  if (PlatformHob == NULL) {
> +    return FALSE;
> +  }
> +
> +  if (SocketId >= GetNumberOfActiveSockets ()) {
> +    return FALSE;
> +  }
> +
> +  Socket = &PlatformHob->ClusterEn[SocketId];
> +  if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Check if the slave socket is present
> +
> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
> +                        FALSE if the Slave Cpu is not present
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsSlaveSocketPresent (
> +  VOID
> +  )
> +{
> +  UINT32 Value;
> +
> +  Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET);
> +
> +  return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE;
> +}
> +
> +/**
> +  Check if the slave socket is active
> +
> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
> +                        FALSE if the Slave CPU Socket is not active.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsSlaveSocketActive (
> +  VOID
> +  )
> +{
> +  return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE;
> +}
> +
> +/**
> +  Check if the CPU product ID is Ac01
> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
> +                        FALSE otherwise.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsAc01Processor (
> +  VOID
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  PlatformHob = GetPlatformHob ();
> +  ASSERT (PlatformHob != NULL);
> +
> +  if (PlatformHob != NULL) {
> +    if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) {
> +      return TRUE;
> +    }
> +  }
> +
> +  return FALSE;
> +}



> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
> new file mode 100644
> index 000000000000..8c1eb93f00fd
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
> @@ -0,0 +1,169 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PL011UartLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <Platform/Ac01.h>
> +#include <PlatformInfoHob.h>
> +#include <Ppi/ArmMpCoreInfo.h>
> +#include <Ppi/TemporaryRamSupport.h>
> +
> +ARM_CORE_INFO mArmPlatformMpCoreInfoTable[PLATFORM_CPU_MAX_NUM_CORES];
> +
> +/**
> +  Return the current Boot Mode
> +
> +  This function returns the boot reason on the platform
> +
> +  @return   Return the current Boot Mode of the platform
> +
> +**/
> +EFI_BOOT_MODE
> +ArmPlatformGetBootMode (
> +  VOID
> +  )
> +{
> +  return BOOT_WITH_FULL_CONFIGURATION;
> +}
> +
> +/**
> +  Initialize controllers that must setup in the normal world
> +
> +  This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
> +  in the PEI phase.
> +
> +**/
> +EFI_STATUS
> +ArmPlatformInitialize (
> +  IN UINTN MpId
> +  )
> +{
> +  RETURN_STATUS      Status;
> +  UINT64             BaudRate;
> +  UINT32             ReceiveFifoDepth;
> +  EFI_PARITY_TYPE    Parity;
> +  UINT8              DataBits;
> +  EFI_STOP_BITS_TYPE StopBits;
> +
> +  Status = EFI_SUCCESS;
> +
> +  if (FixedPcdGet64 (PcdSerialRegisterBase) != 0) {
> +    /* Debug port should use the same parameters with console */
> +    BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
> +    ReceiveFifoDepth = FixedPcdGet32 (PcdUartDefaultReceiveFifoDepth);
> +    Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
> +    DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
> +    StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
> +
> +    /* Initialize uart debug port */
> +    Status = PL011UartInitializePort (
> +               (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
> +               FixedPcdGet32 (PL011UartClkInHz),
> +               &BaudRate,
> +               &ReceiveFifoDepth,
> +               &Parity,
> +               &DataBits,
> +               &StopBits
> +               );
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +PrePeiCoreGetMpCoreInfo (
> +  OUT UINTN         *CoreCount,
> +  OUT ARM_CORE_INFO **ArmCoreTable
> +  )
> +{
> +  UINTN              mArmPlatformCoreCount;
> +  UINTN              ClusterId;
> +  UINTN              SocketId;
> +  UINTN              Index;
> +
> +  ASSERT (CoreCount != NULL);
> +  ASSERT (ArmCoreTable != NULL);
> +  ASSERT (*ArmCoreTable != NULL);
> +
> +  mArmPlatformCoreCount = 0;
> +  for  (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index++) {
> +    if (!IsCpuEnabled (Index)) {
> +      continue;
> +    }
> +    SocketId = SOCKET_ID (Index);
> +    ClusterId = CLUSTER_ID (Index);
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].ClusterId = SocketId;
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].CoreId =
> +      (ClusterId << 8) | (Index % PLATFORM_CPU_NUM_CORES_PER_CPM);
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearAddress = 0;
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearValue = 0;
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxGetAddress = 0;
> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxSetAddress = 0;
> +    mArmPlatformCoreCount++;
> +  }
> +
> +  *CoreCount = mArmPlatformCoreCount;
> +
> +  *ArmCoreTable = mArmPlatformMpCoreInfoTable;
> +  ASSERT (*ArmCoreTable != NULL);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
> +EFI_GUID             mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
> +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
> +
> +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
> +  {
> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
> +    &mArmMpCoreInfoPpiGuid,
> +    &mMpCoreInfoPpi
> +  },
> +};
> +
> +/**
> +  Return the Platform specific PPIs
> +
> +  This function exposes the Platform Specific PPIs. They can be used by any PrePi modules or passed
> +  to the PeiCore by PrePeiCore.
> +
> +  @param[out]   PpiListSize         Size in Bytes of the Platform PPI List
> +  @param[out]   PpiList             Platform PPI List
> +
> +**/
> +VOID
> +ArmPlatformGetPlatformPpiList (
> +  OUT UINTN                  *PpiListSize,
> +  OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
> +  )
> +{
> +  ASSERT (PpiListSize != NULL);
> +  ASSERT (PpiList != NULL);
> +  ASSERT (*PpiList != NULL);
> +
> +  if (ArmIsMpCore ()) {
> +    *PpiListSize = sizeof (gPlatformPpiTable);
> +    *PpiList = gPlatformPpiTable;
> +  } else {
> +    *PpiListSize = 0;
> +    *PpiList = NULL;
> +  }
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
> new file mode 100644
> index 000000000000..117c9cc56ac2
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
> @@ -0,0 +1,399 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmPlatformLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <PlatformInfoHob.h>
> +
> +/* Number of Virtual Memory Map Descriptors */
> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          50
> +
> +/* DDR attributes */
> +#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
> +#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
> +
> +/**
> +  Return the Virtual Memory Map of your platform
> +
> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
> +
> +  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
> +                                    Virtual Memory mapping. This array must be ended by a zero-filled
> +                                    entry
> +
> +**/
> +VOID
> +ArmPlatformGetVirtualMemoryMap (
> +  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
> +  )
> +{
> +  UINTN                        Index = 0;
> +  ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
> +  UINT32                       NumRegion;
> +  UINTN                        Count;
> +  VOID                         *Hob;
> +  PLATFORM_INFO_HOB            *PlatformHob;
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  ASSERT (Hob != NULL);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  ASSERT (VirtualMemoryMap != NULL);
> +
> +  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
> +  if (VirtualMemoryTable == NULL) {
> +    return;
> +  }
> +
> +  /* For Address space 0x1000_0000_0000 to 0x1001_00FF_FFFF
> +   *  - Device memory
> +   */
> +  VirtualMemoryTable[Index].PhysicalBase = 0x100000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x100000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x102000000ULL;

Please move all of these live-coded addresses/sizes to a private .h
and use symbolic names here.

> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /* For Address space 0x5000_0000_0000 to 0x5001_00FF_FFFF
> +   *  - Device memory
> +   */
> +  if (IsSlaveSocketActive ())
> +  {
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x500000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x500000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x101000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  }
> +
> +  /*
> +   *  - PCIe RCA0 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x300000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x300000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCA0 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x20000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x20000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCA1 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x340000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x340000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCA1 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x28000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x28000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCA2 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x380000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x380000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCA2 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x30000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x30000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCA3 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x3C0000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x3C0000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCA3 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x38000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x38000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCB0 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x200000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x200000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCB0 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x00000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x00000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCB1 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x240000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x240000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCB1 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x08000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x08000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCB2 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x280000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x280000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCB2 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x10000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x10000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - PCIe RCB3 Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x2C0000000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x2C0000000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket0 RCB3 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x18000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x18000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  if (IsSlaveSocketActive ()) {
> +    // Slave socket exist
> +    /*
> +     *  - PCIe RCA0 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x700000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x700000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCA1 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x740000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x740000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCA2 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x780000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x780000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCA3 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x7C0000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x7C0000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCB0 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x600000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x600000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCB1 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x640000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x640000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCB2 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x680000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x680000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +    /*
> +     *  - PCIe RCB3 Device memory
> +     */
> +    VirtualMemoryTable[++Index].PhysicalBase = 0x6C0000000000ULL;
> +    VirtualMemoryTable[Index].VirtualBase  = 0x6C0000000000ULL;
> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +  }
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCA0 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x60000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x60000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCA1 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x68000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x68000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCA2 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x70000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x70000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCA3 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x78000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x78000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCB0 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x40000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x40000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCB1 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x48000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x48000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCB2 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x50000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x50000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - 2P/PCIe Socket1 RCB3 32-bit Device memory
> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x58000000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x58000000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - BERT memory region
> +   */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0x88230000ULL;
> +  VirtualMemoryTable[Index].VirtualBase  = 0x88230000ULL;
> +  VirtualMemoryTable[Index].Length       = 0x50000ULL;
> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
> +
> +  /*
> +   *  - DDR memory region
> +   */
> +  NumRegion = PlatformHob->DramInfo.NumRegion;
> +  Count = 0;
> +  while (NumRegion-- > 0) {
> +    if (PlatformHob->DramInfo.NvdRegion[Count]) { /* Skip NVDIMM Region */
> +      Count++;
> +      continue;
> +    }
> +
> +    VirtualMemoryTable[++Index].PhysicalBase = PlatformHob->DramInfo.Base[Count];
> +    VirtualMemoryTable[Index].VirtualBase  = PlatformHob->DramInfo.Base[Count];
> +    VirtualMemoryTable[Index].Length       = PlatformHob->DramInfo.Size[Count];
> +    VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
> +    Count++;
> +  }
> +
> +  /* SPM MM NS Buffer for MmCommunicateDxe */
> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase);
> +  VirtualMemoryTable[Index].VirtualBase  = PcdGet64 (PcdMmBufferBase);
> +  VirtualMemoryTable[Index].Length       = PcdGet64 (PcdMmBufferSize);
> +  VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
> +
> +  /* End of Table */
> +  VirtualMemoryTable[++Index].PhysicalBase = 0;
> +  VirtualMemoryTable[Index].VirtualBase  = 0;
> +  VirtualMemoryTable[Index].Length       = 0;
> +  VirtualMemoryTable[Index].Attributes   = (ARM_MEMORY_REGION_ATTRIBUTES)0;
> +
> +  ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
> +
> +  *VirtualMemoryMap = VirtualMemoryTable;
> +}



> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
> new file mode 100644
> index 000000000000..0da1f90699f6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
> @@ -0,0 +1,282 @@
> +/** @file
> +  The library implements the hardware Mailbox (Doorbell) interface for communication
> +  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MailboxInterfaceLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/IoLib.h>
> +
> +//
> +// Hardware Doorbells
> +//
> +#define SMPRO_DB0_IRQ_OFST               40
> +#define SMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdSmproDbBaseReg))
> +
> +#define PMPRO_DB0_IRQ_OFST               56
> +#define PMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdPmproDbBaseReg))
> +
> +#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000
> +
> +//
> +// The base SPI interrupt number of the Slave socket
> +//
> +#define SLAVE_SOCKET_SPI_INTERRUPT 352
> +
> +#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32)
> +
> +//
> +// Doorbell base register stride size
> +//
> +#define DB_BASE_REG_STRIDE 0x00001000
> +
> +#define SMPRO_DBx_ADDRESS(socket, db) \
> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
> +
> +#define PMPRO_DBx_ADDRESS(socket, db) \
> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
> +
> +//
> +// Doorbell Status Bits
> +//
> +#define DB_STATUS_AVAIL_BIT       BIT16
> +#define DB_STATUS_ACK_BIT         BIT0
> +
> +/**
> +  Get the base address of a doorbell.
> +
> +  @param[in]  Socket            Active socket index.
> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
> +
> +  @retval UINT32                The base address of the doorbell.
> +                                The returned value is 0 indicate that the input parameters are invalid.
> +
> +**/
> +UINTN
> +EFIAPI
> +MailboxGetDoorbellAddress (
> +  IN UINT8             Socket,
> +  IN DOORBELL_CHANNELS Doorbell
> +  )
> +{
> +  UINTN DoorbellAddress;
> +
> +  if (Socket >= GetNumberOfActiveSockets ()
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
> +  {
> +    return 0;
> +  }

Coding style is
 if () {
 }

This file gets it consistently wrong.

> +
> +  if (Doorbell >= SMproDoorbellChannel0) {
> +    DoorbellAddress = SMPRO_DBx_ADDRESS (Socket, (UINT8)(Doorbell - SMproDoorbellChannel0));
> +  } else {
> +    DoorbellAddress = PMPRO_DBx_ADDRESS (Socket, (UINT8)Doorbell);
> +  }
> +
> +  return DoorbellAddress;
> +}
> +
> +/**
> +  Get the interrupt number of a doorbell.
> +
> +  @param[in]  Socket            Active socket index.
> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
> +
> +  @retval UINT32                The interrupt number.
> +                                The returned value is 0 indicate that the input parameters are invalid.
> +
> +**/
> +UINT32
> +EFIAPI
> +MailboxGetDoorbellInterruptNumber (
> +  IN UINT8             Socket,
> +  IN DOORBELL_CHANNELS Doorbell
> +  )
> +{
> +  UINT32 DoorbellInterruptNumber;
> +
> +  if (Socket >= GetNumberOfActiveSockets ()
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
> +  {
> +    return 0;
> +  }
> +
> +  DoorbellInterruptNumber = 0;
> +
> +  if (Socket > 0) {
> +    DoorbellInterruptNumber = SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE (Socket);
> +  }
> +
> +  if (Doorbell >= SMproDoorbellChannel0) {
> +    DoorbellInterruptNumber += SMPRO_DB0_IRQ_OFST + (UINT8)(Doorbell - SMproDoorbellChannel0);
> +  } else {
> +    DoorbellInterruptNumber += PMPRO_DB0_IRQ_OFST + (UINT8)Doorbell;
> +  }
> +
> +  return DoorbellInterruptNumber;
> +}
> +
> +/**
> +  Read a message via the hardware Doorbell interface.
> +
> +  @param[in]  Socket            Active socket index.
> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
> +  @param[out] Message           Pointer to the Mailbox message.
> +
> +  @retval EFI_SUCCESS           Read the message successfully.
> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for available message in the mailbox.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxRead (
> +  IN  UINT8                Socket,
> +  IN  DOORBELL_CHANNELS    Doorbell,
> +  OUT MAILBOX_MESSAGE_DATA *Message
> +  )
> +{
> +  UINTN TimeoutCount;
> +  UINTN DoorbellAddress;
> +
> +  if (Socket >= GetNumberOfActiveSockets ()
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
> +      || Message == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TimeoutCount = MAILBOX_POLL_COUNT;
> +
> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
> +  ASSERT (DoorbellAddress != 0);
> +
> +  //
> +  // Polling Doorbell status
> +  //
> +  while ((MmioRead32 ((DoorbellAddress + DB_STATUS_REG_OFST)) & DB_STATUS_AVAIL_BIT) == 0) {
> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
> +    if (--TimeoutCount == 0) {
> +      return EFI_TIMEOUT;
> +    }
> +  }
> +
> +  Message->ExtendedData[0] = MmioRead32 (DoorbellAddress + DB_DIN0_REG_OFST);
> +  Message->ExtendedData[1] = MmioRead32 (DoorbellAddress + DB_DIN1_REG_OFST);
> +  Message->Data = MmioRead32 (DoorbellAddress + DB_IN_REG_OFST);
> +
> +  //
> +  // Write 1 to clear the AVAIL status
> +  //
> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_AVAIL_BIT);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Write a message via the hardware Doorbell interface.
> +
> +  @param[in]  Socket            Active socket index.
> +  @param[in]  Doorbell          Doorbel channel for communication with the SMpro/PMpro.
> +  @param[in]  Message           Pointer to the Mailbox message.
> +
> +  @retval EFI_SUCCESS           Write the message successfully.
> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for acknowledge signal from the mailbox.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxWrite (
> +  IN UINT8                Socket,
> +  IN DOORBELL_CHANNELS    Doorbell,
> +  IN MAILBOX_MESSAGE_DATA *Message
> +  )
> +{
> +  UINTN TimeoutCount;
> +  UINTN DoorbellAddress;
> +
> +  if (Socket >= GetNumberOfActiveSockets ()
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
> +      || Message == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  TimeoutCount = MAILBOX_POLL_COUNT;
> +
> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
> +  ASSERT (DoorbellAddress != 0);
> +
> +  //
> +  // Clear previous pending ack if any
> +  //
> +  if ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) != 0) {
> +    MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
> +  }
> +
> +  //
> +  // Send message
> +  //
> +  MmioWrite32 (DoorbellAddress + DB_DOUT0_REG_OFST, Message->ExtendedData[0]);
> +  MmioWrite32 (DoorbellAddress + DB_DOUT1_REG_OFST, Message->ExtendedData[1]);
> +  MmioWrite32 (DoorbellAddress + DB_OUT_REG_OFST, Message->Data);
> +
> +  //
> +  // Wait for ACK
> +  //
> +  while ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) == 0) {
> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
> +    if (--TimeoutCount == 0) {
> +      return EFI_TIMEOUT;
> +    }
> +  }
> +
> +  //
> +  // Write 1 to clear the ACK status
> +  //
> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Unmask the Doorbell interrupt status.
> +
> +  @param  Socket    Active socket index.
> +  @param  Doorbell  Doorbel channel for communication with the SMpro/PMpro.
> +
> +  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
> +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MailboxUnmaskInterrupt (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell
> +  )
> +{
> +  UINTN DoorbellAddress;
> +
> +  if (Socket >= GetNumberOfActiveSockets ()
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
> +  ASSERT (DoorbellAddress != 0);
> +
> +  MmioWrite32 (DoorbellAddress + DB_STATUS_MASK_REG_OFST, ~DB_STATUS_AVAIL_BIT);
> +
> +  return EFI_SUCCESS;
> +}


> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
> new file mode 100644
> index 000000000000..bf400ec0a835
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
> @@ -0,0 +1,184 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <IndustryStandard/ArmStdSmc.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MmCommunicationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Protocol/MmCommunication.h>
> +
> +//
> +// Address, Length of the pre-allocated buffer for communication with the secure
> +// world.
> +//
> +STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
> +
> +EFI_STATUS
> +EFIAPI
> +MmCommunicationLibConstructor (
> +  VOID
> +  )
> +{
> +  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
> +  // During boot , Virtual and Physical are same

Ideally, use UEFI-defined terms. "During boot" is quite ambiguous.


> +  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
> +  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Communicates with a registered handler.
> +
> +  This function provides an interface to send and receive messages to the
> +  Standalone MM environment in UEFI PEI phase.
> +
> +  @param[in, out] CommBuffer          A pointer to the buffer to convey
> +                                      into MMRAM.
> +  @param[in, out] CommSize            The size of the data buffer being
> +                                      passed in. This is optional.
> +
> +  @retval EFI_SUCCESS                 The message was successfully posted.
> +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
> +  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
> +                                      implementation. If this error is
> +                                      returned, the MessageLength field in
> +                                      the CommBuffer header or the integer
> +                                      pointed by CommSize are updated to reflect
> +                                      the maximum payload size the
> +                                      implementation can accommodate.
> +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
> +                                      or CommSize parameter, if not omitted,
> +                                      are in address range that cannot be
> +                                      accessed by the MM environment
> +**/
> +EFI_STATUS
> +EFIAPI
> +MmCommunicationCommunicate (
> +  IN OUT VOID  *CommBuffer,
> +  IN OUT UINTN *CommSize OPTIONAL
> +  )
> +{
> +  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
> +  ARM_SMC_ARGS              CommunicateSmcArgs;
> +  EFI_STATUS                Status;
> +  UINTN                     BufferSize;
> +
> +  Status = EFI_ACCESS_DENIED;
> +  BufferSize = 0;
> +
> +  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
> +
> +  //
> +  // Check parameters
> +  //
> +  if (CommBuffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  CommunicateHeader = CommBuffer;
> +  // CommBuffer is a mandatory parameter. Hence, Rely on
> +  // MessageLength + Header to ascertain the
> +  // total size of the communication payload rather than
> +  // rely on optional CommSize parameter
> +  BufferSize = CommunicateHeader->MessageLength +
> +               sizeof (CommunicateHeader->HeaderGuid) +
> +               sizeof (CommunicateHeader->MessageLength);
> +
> +  // If the length of the CommBuffer is 0 then return the expected length.
> +  if (CommSize != NULL) {
> +    // This case can be used by the consumer of this driver to find out the
> +    // max size that can be used for allocating CommBuffer.
> +    if ((*CommSize == 0) ||
> +        (*CommSize > mNsCommBuffMemRegion.Length))
> +    {

{ at end of preceding line.
Please address throughout this file.

> +      *CommSize = mNsCommBuffMemRegion.Length;
> +      return EFI_BAD_BUFFER_SIZE;
> +    }
> +    //
> +    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
> +    //
> +    if (*CommSize != BufferSize) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  //
> +  // If the buffer size is 0 or greater than what can be tolerated by the MM
> +  // environment then return the expected size.
> +  //
> +  if ((BufferSize == 0) ||
> +      (BufferSize > mNsCommBuffMemRegion.Length))
> +  {
> +    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
> +                                       sizeof (CommunicateHeader->HeaderGuid) -
> +                                       sizeof (CommunicateHeader->MessageLength);
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // SMC Function ID
> +  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
> +
> +  // Cookie
> +  CommunicateSmcArgs.Arg1 = 0;
> +
> +  // Copy Communication Payload
> +  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
> +
> +  // comm_buffer_address (64-bit physical address)
> +  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
> +
> +  // comm_size_address (not used, indicated by setting to zero)
> +  CommunicateSmcArgs.Arg3 = 0;
> +
> +  // Call the Standalone MM environment.
> +  ArmCallSmc (&CommunicateSmcArgs);
> +
> +  switch (CommunicateSmcArgs.Arg0) {
> +  case ARM_SMC_MM_RET_SUCCESS:
> +    ZeroMem (CommBuffer, BufferSize);
> +    // On successful return, the size of data being returned is inferred from
> +    // MessageLength + Header.
> +    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
> +    BufferSize = CommunicateHeader->MessageLength +
> +                 sizeof (CommunicateHeader->HeaderGuid) +
> +                 sizeof (CommunicateHeader->MessageLength);
> +
> +    CopyMem (
> +      CommBuffer,
> +      (VOID *)mNsCommBuffMemRegion.VirtualBase,
> +      BufferSize
> +      );
> +    Status = EFI_SUCCESS;
> +    break;
> +
> +  case ARM_SMC_MM_RET_INVALID_PARAMS:
> +    Status = EFI_INVALID_PARAMETER;
> +    break;
> +
> +  case ARM_SMC_MM_RET_DENIED:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +
> +  case ARM_SMC_MM_RET_NO_MEMORY:
> +    // Unexpected error since the CommSize was checked for zero length
> +    // prior to issuing the SMC
> +    Status = EFI_OUT_OF_RESOURCES;
> +    ASSERT (0);
> +    break;
> +
> +  default:
> +    Status = EFI_ACCESS_DENIED;
> +    ASSERT (0);
> +  }
> +
> +  return Status;
> +}

> diff --git a/Platform/Ampere/JadePkg/JadeBoardSetting.cfg b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
> new file mode 100644
> index 000000000000..5a67e8fc6a75
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
> @@ -0,0 +1,209 @@
> +# Sample board setting
> +#
> +# This is a sample board setting as used for the
> +# Ampere Altra reference design.

What is a board setting?

> +#
> +# Name, offset (hex), value
> +# value can be hex or decimal
> +#
> +
> +NV_SI_RO_BOARD_VENDOR, 0x0000, 0x0000CD3A
> +NV_SI_RO_BOARD_TYPE, 0x0008, 0x00000000
> +NV_SI_RO_BOARD_REV, 0x0010, 0x00000000
> +NV_SI_RO_BOARD_CFG, 0x0018, 0x00000000
> +NV_SI_RO_BOARD_S0_DIMM_AVAIL, 0x0020, 0x0000FFFF
> +NV_SI_RO_BOARD_S1_DIMM_AVAIL, 0x0028, 0x0000FFFF
> +NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ, 0x0030, 0x000080E8
> +NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ, 0x0038, 0x000080E8
> +NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ, 0x0040, 0x00002710
> +NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ, 0x0048, 0x00002710
> +NV_SI_RO_BOARD_TPM_LOC, 0x0050, 0x00000000
> +NV_SI_RO_BOARD_I2C0_FREQ_KHZ, 0x0058, 0x00000190
> +NV_SI_RO_BOARD_I2C1_FREQ_KHZ, 0x0060, 0x00000190
> +NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ, 0x0068, 0x00000190
> +NV_SI_RO_BOARD_I2C3_FREQ_KHZ, 0x0070, 0x00000190
> +NV_SI_RO_BOARD_I2C9_FREQ_KHZ, 0x0078, 0x00000190
> +NV_SI_RO_BOARD_2P_CFG, 0x0080, 0xFFFFFF01
> +NV_SI_RO_BOARD_S0_RCA0_CFG, 0x0088, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA1_CFG, 0x0090, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA2_CFG, 0x0098, 0x00000004
> +NV_SI_RO_BOARD_S0_RCA3_CFG, 0x00A0, 0x00000004
> +NV_SI_RO_BOARD_S0_RCB0_LO_CFG, 0x00A8, 0x00020002
> +NV_SI_RO_BOARD_S0_RCB0_HI_CFG, 0x00B0, 0x00020002
> +NV_SI_RO_BOARD_S0_RCB1_LO_CFG, 0x00B8, 0x00020002
> +NV_SI_RO_BOARD_S0_RCB1_HI_CFG, 0x00C0, 0x00020002
> +NV_SI_RO_BOARD_S0_RCB2_LO_CFG, 0x00C8, 0x00020002
> +NV_SI_RO_BOARD_S0_RCB2_HI_CFG, 0x00D0, 0x00000003
> +NV_SI_RO_BOARD_S0_RCB3_LO_CFG, 0x00D8, 0x00000003
> +NV_SI_RO_BOARD_S0_RCB3_HI_CFG, 0x00E0, 0x00020002
> +NV_SI_RO_BOARD_S1_RCA0_CFG, 0x00E8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA1_CFG, 0x00F0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA2_CFG, 0x00F8, 0x02020202
> +NV_SI_RO_BOARD_S1_RCA3_CFG, 0x0100, 0x00030003
> +NV_SI_RO_BOARD_S1_RCB0_LO_CFG, 0x0108, 0x00000003
> +NV_SI_RO_BOARD_S1_RCB0_HI_CFG, 0x0110, 0x00020002
> +NV_SI_RO_BOARD_S1_RCB1_LO_CFG, 0x0118, 0x00020002
> +NV_SI_RO_BOARD_S1_RCB1_HI_CFG, 0x0120, 0x00000003
> +NV_SI_RO_BOARD_S1_RCB2_LO_CFG, 0x0128, 0x00020002
> +NV_SI_RO_BOARD_S1_RCB2_HI_CFG, 0x0130, 0x00020002
> +NV_SI_RO_BOARD_S1_RCB3_LO_CFG, 0x0138, 0x00020002
> +NV_SI_RO_BOARD_S1_RCB3_HI_CFG, 0x0140, 0x00020002
> +NV_SI_RO_BOARD_T_LTLM_DELTA_P0, 0x0148, 0x00000001
> +NV_SI_RO_BOARD_T_LTLM_DELTA_P1, 0x0150, 0x00000002
> +NV_SI_RO_BOARD_T_LTLM_DELTA_P2, 0x0158, 0x00000003
> +NV_SI_RO_BOARD_T_LTLM_DELTA_P3, 0x0160, 0x00000004
> +NV_SI_RO_BOARD_T_LTLM_DELTA_M1, 0x0168, 0xFFFFFFFF
> +NV_SI_RO_BOARD_T_LTLM_DELTA_M2, 0x0170, 0xFFFFFFFE
> +NV_SI_RO_BOARD_T_LTLM_DELTA_M3, 0x0178, 0xFFFFFFFD
> +NV_SI_RO_BOARD_P_LM_PID_P, 0x0180, 0x00000000
> +NV_SI_RO_BOARD_P_LM_PID_I, 0x0188, 0x00000000
> +NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD, 0x0190, 0x00000000
> +NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD, 0x0198, 0x00000000
> +NV_SI_RO_BOARD_P_LM_PID_D, 0x01A0, 0x00000000
> +NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST, 0x01A8, 0x00000000
> +NV_SI_RO_BOARD_TPM_ALG_ID, 0x01B0, 0x00000002
> +NV_SI_RO_BOARD_DDR_SPEED_GRADE, 0x01B8, 0x00000C80
> +NV_SI_RO_BOARD_DDR_S0_RTT_WR, 0x01C0, 0x00020000
> +NV_SI_RO_BOARD_DDR_S1_RTT_WR, 0x01C8, 0x00020000
> +NV_SI_RO_BOARD_DDR_S0_RTT_NOM, 0x01D0, 0xFF060177
> +NV_SI_RO_BOARD_DDR_S1_RTT_NOM, 0x01D8, 0xFF060177
> +NV_SI_RO_BOARD_DDR_S0_RTT_PARK, 0x01E0, 0x00060070
> +NV_SI_RO_BOARD_DDR_S1_RTT_PARK, 0x01E8, 0x00060070
> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC, 0x01F0, 0x00000000
> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC, 0x01F8, 0x00000000
> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC, 0x0200, 0x00000000
> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC, 0x0208, 0x00000000
> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC, 0x0210, 0x000C0CCC
> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC, 0x0218, 0x000C0CCC
> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC, 0x0220, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC, 0x0228, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC, 0x0230, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC, 0x0238, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC, 0x0240, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC, 0x0248, 0x00030333
> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC, 0x0250, 0x000EDEED
> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC, 0x0258, 0x000DEDDE
> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC, 0x0260, 0x000B7BB7
> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC, 0x0268, 0x0007B77B
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC, 0x0270, 0x00000005
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC, 0x0278, 0x0090DD90
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC, 0x0280, 0x00000005
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC, 0x0288, 0x0090DD90
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC, 0x0290, 0x00000005
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC, 0x0298, 0x0090DD90
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC, 0x02A0, 0x00000005
> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC, 0x02A8, 0x0090DD90
> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC, 0x02B0, 0x00000024
> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC, 0x02B8, 0x0000001A
> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC, 0x02C0, 0x00000050
> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC, 0x02C8, 0x00000020
> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT, 0x02D0, 0x02800280
> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT, 0x02D8, 0x90909090
> +NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT, 0x02E0, 0x00000000
> +NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT, 0x02E8, 0x00C000C0
> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ, 0x02F0, 0x00000000
> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ, 0x02F8, 0x00000000
> +NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ, 0x0300, 0x00000000
> +NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ, 0x0308, 0x00000000
> +NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE, 0x0310, 0x02010201
> +NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE, 0x0318, 0x00000000
> +NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO, 0x0320, 0x00000000
> +NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL, 0x0328, 0x00000000
> +NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS, 0x0330, 0x01050106
> +NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD, 0x0338, 0x000005F4
> +NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE, 0x0340, 0x00000000
> +NV_SI_RO_BOARD_S0_PCIE_CLK_CFG, 0x0348, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA4_CFG, 0x0350, 0x02020202
> +NV_SI_RO_BOARD_S0_RCA5_CFG, 0x0358, 0x02020202
> +NV_SI_RO_BOARD_S0_RCA6_CFG, 0x0360, 0x02020202
> +NV_SI_RO_BOARD_S0_RCA7_CFG, 0x0368, 0x02020003
> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET, 0x0370, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET, 0x0378, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET, 0x0380, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET, 0x0388, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET, 0x0390, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET, 0x0398, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET, 0x03A0, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET, 0x03A8, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET, 0x03B0, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET, 0x03B8, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET, 0x03C0, 0x00000000
> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET, 0x03C8, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET, 0x03D0, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET, 0x03D8, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET, 0x03E0, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET, 0x03E8, 0x00000000
> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET, 0x03F0, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET, 0x03F8, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET, 0x0400, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET, 0x0408, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET, 0x0410, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET, 0x0418, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET, 0x0420, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET, 0x0428, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET, 0x0430, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET, 0x0438, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET, 0x0440, 0x57575757
> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET, 0x0448, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET, 0x0450, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET, 0x0458, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET, 0x0460, 0x57575757
> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET, 0x0468, 0x57575757
> +NV_SI_RO_BOARD_S1_PCIE_CLK_CFG, 0x0470, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA4_CFG, 0x0478, 0x02020202
> +NV_SI_RO_BOARD_S1_RCA5_CFG, 0x0480, 0x02020202
> +NV_SI_RO_BOARD_S1_RCA6_CFG, 0x0488, 0x02020202
> +NV_SI_RO_BOARD_S1_RCA7_CFG, 0x0490, 0x02020003
> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET, 0x0498, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET, 0x04A0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET, 0x04A8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET, 0x04B0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET, 0x04B8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET, 0x04C0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET, 0x04C8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET, 0x04D0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET, 0x04D8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET, 0x04E0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET, 0x04E8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET, 0x04F0, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET, 0x04F8, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET, 0x0500, 0x00000000
> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET, 0x0508, 0x57575757
> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET, 0x0510, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET, 0x0518, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET, 0x0520, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET, 0x0528, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET, 0x0530, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET, 0x0538, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET, 0x0540, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET, 0x0548, 0x57575757
> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET, 0x0550, 0x57575757
> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET, 0x0558, 0x57575757
> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET, 0x0560, 0x57575757
> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET, 0x0568, 0x57575757
> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET, 0x0570, 0x57575757
> +NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD, 0x0578, 0x00000003
> +NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL, 0x0580, 0x000001A4
> +NV_SI_RO_BOARD_SX_PHY_CFG_SETTING, 0x0588, 0x00000000
> +NV_SI_RO_BOARD_DDR_PHY_DC_CLK, 0x0590, 0x00018000
> +NV_SI_RO_BOARD_DDR_PHY_DC_DATA, 0x0598, 0x80018000
> +NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET, 0x05A0, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET, 0x05A8, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET, 0x05B0, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET, 0x05B8, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET, 0x05C0, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET, 0x05C8, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET, 0x05D0, 0x00000000
> +NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET, 0x05D8, 0x00000000
> +NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD, 0x05E0, 0x00550055
> +NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US, 0x05E8, 0x00000064
> +NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV, 0x05F0, 0x00000005
> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN, 0x05F8, 0x00000001
> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME, 0x0600, 0x00000002
> +NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US, 0x0608, 0x00000005
> +NV_SI_RO_BOARD_PCIE_AER_FW_FIRST, 0x0610, 0x00000000
> +NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS, 0x0618, 0x00000000
> +NV_SI_RO_BOARD_TPM_DISABLE, 0x0620, 0x00000000
> +NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, 0x0628, 0x00000000
> +NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, 0x0630, 0x00000000
> +NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN, 0x0638, 0x00000000

There was also a few things in this patch where I felt names had
insufficient namespace - such as starting with TRNG_ or NV_.
I'm not going to insist on adding prefixes to those, I'm just going to
say I have warned you, and those might get you in trouble in the
future :)

Best Regards,

Leif

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

* Re: [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
@ 2021-06-04 23:05   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:05 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:54 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> The MmCommunicationDxe module is derived from
> ArmPkg/Drivers/MmCommunicationDxe/MmCommunication.inf.
> 
> The MmCommunication PEI and DXE modules implement the MM Communication
> protocol (EFI_MM_COMMUNICATION_PROTOCOL) as defined in the PI 1.5
> specification for the interface between UEFI and MM services in the
> secure world.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                |   3 +
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                            |   2 +
>  Platform/Ampere/JadePkg/Jade.fdf                                                |   3 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf    |  57 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf |  34 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h        |  22 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c      | 454 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c   |  37 ++
>  8 files changed, 612 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index f0a5bd04ec22..73097afaf841 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -38,5 +38,8 @@ [Guids]
>    ## NVParam MM GUID
>    gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
>  
> +  ## SPI NOR Proxy MM GUID
> +  gSpiNorMmGuid                = { 0xC8D76438, 0x4D3C, 0x4BEA, { 0xBF, 0x86, 0x92, 0x6B, 0x83, 0x07, 0xA2, 0x39 } }
> +
>    ## Include/Guid/PlatformInfoHobGuid.h
>    gPlatformHobGuid             = { 0x7f73e372, 0x7183, 0x4022, { 0xb3, 0x76, 0x78, 0x30, 0x32, 0x6d, 0x79, 0xb4 } }
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index af66c27822a3..0332473b59b0 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -517,6 +517,7 @@ [Components.common]
>    ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>    ArmPkg/Drivers/CpuPei/CpuPei.inf
>    UefiCpuPkg/CpuIoPei/CpuIoPei.inf
>    MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> @@ -565,6 +566,7 @@ [Components.common]
>    EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
>    EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>    EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>  
>    #
>    # Environment Variables Protocol
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 8ed6df381aed..905289844378 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -101,6 +101,7 @@ [FV.FVMAIN_COMPACT]
>    INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>    INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>    INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>    INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> @@ -141,6 +142,7 @@ [FV.FvMain]
>    INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>    INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>    INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>  }
>  
>    INF MdeModulePkg/Core/Dxe/DxeMain.inf
> @@ -163,6 +165,7 @@ [FV.FvMain]
>    INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>    INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
>    INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>  
>    #
>    # Environment Variables Protocol
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
> new file mode 100644
> index 000000000000..3efff142944f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
> @@ -0,0 +1,57 @@
> +#/** @file
> +#
> +#  This module implements the MM Communication Protocol (EFI_MM_COMMUNICATION_PROTOCOL)
> +#  as defined in the PI 1.5 specification.
> +#
> +#  Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +#**/
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = ArmMmCommunication
> +  FILE_GUID                      = 09EE81D3-F15E-43F4-85B4-CB9873DA5D6B
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MmCommunicationInitialize
> +
> +#
> +# The following is for reference only and not required by
> +# build tools
> +#
> +# VALID_ARCHITECTURES            = AARCH64
> +#
> +
> +[Sources.AARCH64]
> +  MmCommunicate.h
> +  MmCommunication.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  ArmLib
> +  ArmSmcLib
> +  BaseMemoryLib
> +  DebugLib
> +  DxeServicesTableLib
> +  HobLib
> +  UefiDriverEntryPoint
> +
> +[Protocols]
> +  gEfiMmCommunicationProtocolGuid              ## PRODUCES
> +
> +[Guids]
> +  gEfiEndOfDxeEventGroupGuid
> +  gEfiEventExitBootServicesGuid
> +  gEfiEventReadyToBootGuid
> +
> +[Pcd.common]
> +  gArmTokenSpaceGuid.PcdMmBufferBase
> +  gArmTokenSpaceGuid.PcdMmBufferSize
> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
> new file mode 100755
> index 000000000000..3a985840a0a0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
> @@ -0,0 +1,34 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = MmCommunicationPei
> +  FILE_GUID                      = B5AE0F80-DF81-11EA-8B6E-0800200C9A66
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = MmCommunicationPeiEntryPoint
> +
> +[Sources]
> +  MmCommunicationPei.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdePkg/MdePkg.dec
> +
> +[LibraryClasses]
> +  HobLib
> +  PcdLib
> +  PeimEntryPoint
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdMmBufferBase
> +  gArmTokenSpaceGuid.PcdMmBufferSize
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
> new file mode 100644
> index 000000000000..804ba58afb72
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunicate.h
> @@ -0,0 +1,22 @@
> +/** @file
> +
> +  Copyright (c) 2016-2018, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef MM_COMMUNICATE_H_
> +#define MM_COMMUNICATE_H_
> +
> +#define MM_MAJOR_VER_MASK        0xEFFF0000
> +#define MM_MINOR_VER_MASK        0x0000FFFF
> +#define MM_MAJOR_VER_SHIFT       16
> +
> +#define MM_MAJOR_VER(x) (((x) & MM_MAJOR_VER_MASK) >> MM_MAJOR_VER_SHIFT)
> +#define MM_MINOR_VER(x) ((x) & MM_MINOR_VER_MASK)
> +
> +#define MM_CALLER_MAJOR_VER      0x1UL
> +#define MM_CALLER_MINOR_VER      0x0
> +
> +#endif /* MM_COMMUNICATE_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
> new file mode 100644
> index 000000000000..271fc755548f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.c
> @@ -0,0 +1,454 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC
> +  Copyright (c) 2016-2018, ARM Limited. All rights reserved.
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <IndustryStandard/ArmStdSmc.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/MmCommunication.h>
> +
> +#include "MmCommunicate.h"
> +
> +#define MM_EARLY_MEM_ALLOCATE 1
> +
> +//
> +// Address, Length of the pre-allocated buffer for communication with the secure
> +// world.
> +//
> +STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
> +
> +// Notification event when virtual address map is set.
> +STATIC EFI_EVENT mSetVirtualAddressMapEvent;
> +
> +//
> +// Handle to install the MM Communication Protocol
> +//
> +STATIC EFI_HANDLE mMmCommunicateHandle;
> +
> +/**
> +  Communicates with a registered handler.
> +
> +  This function provides an interface to send and receive messages to the
> +  Standalone MM environment on behalf of UEFI services.  This function is part
> +  of the MM Communication Protocol that may be called in physical mode prior to
> +  SetVirtualAddressMap() and in virtual mode after SetVirtualAddressMap().
> +
> +  @param[in]      This                The EFI_MM_COMMUNICATION_PROTOCOL
> +                                      instance.
> +  @param[in, out] CommBuffer          A pointer to the buffer to convey
> +                                      into MMRAM.
> +  @param[in, out] CommSize            The size of the data buffer being
> +                                      passed in. This is optional.
> +
> +  @retval EFI_SUCCESS                 The message was successfully posted.
> +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
> +  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
> +                                      implementation. If this error is
> +                                      returned, the MessageLength field in
> +                                      the CommBuffer header or the integer
> +                                      pointed by CommSize are updated to reflect
> +                                      the maximum payload size the
> +                                      implementation can accommodate.
> +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
> +                                      or CommSize parameter, if not omitted,
> +                                      are in address range that cannot be
> +                                      accessed by the MM environment
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +MmCommunicationCommunicate (
> +  IN CONST EFI_MM_COMMUNICATION_PROTOCOL *This,
> +  IN OUT   VOID                          *CommBuffer,
> +  IN OUT   UINTN                         *CommSize OPTIONAL
> +  )
> +{
> +  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
> +  ARM_SMC_ARGS              CommunicateSmcArgs;
> +  EFI_STATUS                Status;
> +  UINTN                     BufferSize;
> +
> +  Status = EFI_ACCESS_DENIED;
> +  BufferSize = 0;
> +
> +  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
> +
> +  //
> +  // Check parameters
> +  //
> +  if (CommBuffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  CommunicateHeader = CommBuffer;
> +  // CommBuffer is a mandatory parameter. Hence, rely on
> +  // MessageLength + Header to ascertain the
> +  // total size of the communication payload rather than
> +  // relying on optional CommSize parameter
> +  BufferSize = CommunicateHeader->MessageLength +
> +               sizeof (CommunicateHeader->HeaderGuid) +
> +               sizeof (CommunicateHeader->MessageLength);
> +
> +  // If the length of the CommBuffer is 0 then return the expected length.
> +  if (CommSize != NULL) {
> +    // This case can be used by the consumer of this driver to find out the
> +    // max size that can be used for allocating CommBuffer.
> +    if ((*CommSize == 0) ||
> +        (*CommSize > mNsCommBuffMemRegion.Length))
> +    {
> +      *CommSize = mNsCommBuffMemRegion.Length;
> +      return EFI_BAD_BUFFER_SIZE;
> +    }
> +    //
> +    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
> +    //
> +    if (*CommSize != BufferSize) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  //
> +  // If the buffer size is 0 or greater than what can be tolerated by the MM
> +  // environment then return the expected size.
> +  //
> +  if ((BufferSize == 0) ||
> +      (BufferSize > mNsCommBuffMemRegion.Length))
> +  {
> +    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
> +                                       sizeof (CommunicateHeader->HeaderGuid) -
> +                                       sizeof (CommunicateHeader->MessageLength);
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  // SMC Function ID
> +  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
> +
> +  // Cookie
> +  CommunicateSmcArgs.Arg1 = 0;
> +
> +  // Copy Communication Payload
> +  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
> +
> +  // comm_buffer_address (64-bit physical address)
> +  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
> +
> +  // comm_size_address (not used, indicated by setting to zero)
> +  CommunicateSmcArgs.Arg3 = 0;
> +
> +  // Call the Standalone MM environment.
> +  ArmCallSmc (&CommunicateSmcArgs);
> +
> +  switch (CommunicateSmcArgs.Arg0) {
> +  case ARM_SMC_MM_RET_SUCCESS:
> +    ZeroMem (CommBuffer, BufferSize);
> +    // On successful return, the size of data being returned is inferred from
> +    // MessageLength + Header.
> +    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
> +    BufferSize = CommunicateHeader->MessageLength +
> +                 sizeof (CommunicateHeader->HeaderGuid) +
> +                 sizeof (CommunicateHeader->MessageLength);
> +
> +    CopyMem (
> +      CommBuffer,
> +      (VOID *)mNsCommBuffMemRegion.VirtualBase,
> +      BufferSize
> +      );
> +    Status = EFI_SUCCESS;
> +    break;
> +
> +  case ARM_SMC_MM_RET_INVALID_PARAMS:
> +    Status = EFI_INVALID_PARAMETER;
> +    break;
> +
> +  case ARM_SMC_MM_RET_DENIED:
> +    Status = EFI_ACCESS_DENIED;
> +    break;
> +
> +  case ARM_SMC_MM_RET_NO_MEMORY:
> +    // Unexpected error since the CommSize was checked for zero length
> +    // prior to issuing the SMC
> +    Status = EFI_OUT_OF_RESOURCES;
> +    ASSERT (0);
> +    break;
> +
> +  default:
> +    Status = EFI_ACCESS_DENIED;
> +    ASSERT (0);
> +  }
> +
> +  return Status;
> +}
> +
> +//
> +// MM Communication Protocol instance
> +//
> +EFI_MM_COMMUNICATION_PROTOCOL mMmCommunication = {
> +  MmCommunicationCommunicate
> +};
> +
> +/**
> +  Notification callback on SetVirtualAddressMap event.
> +
> +  This function notifies the MM communication protocol interface on
> +  SetVirtualAddressMap event and converts pointers used in this driver
> +  from physical to virtual address.
> +
> +  @param  Event          SetVirtualAddressMap event.
> +  @param  Context        A context when the SetVirtualAddressMap triggered.
> +
> +  @retval EFI_SUCCESS    The function executed successfully.
> +  @retval Other          Some error occurred when executing this function.
> +
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +NotifySetVirtualAddressMap (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = gRT->ConvertPointer (
> +                  EFI_OPTIONAL_PTR,
> +                  (VOID **)&mNsCommBuffMemRegion.VirtualBase
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Unable to convert MM runtime pointer. Status:0x%r\n",
> +      __FUNCTION__,
> +      Status
> +      ));
> +  }
> +
> +}
> +
> +STATIC
> +EFI_STATUS
> +GetMmCompatibility ()
> +{
> +  EFI_STATUS   Status;
> +  UINT32       MmVersion;
> +  ARM_SMC_ARGS MmVersionArgs;
> +
> +  // MM_VERSION uses SMC32 calling conventions
> +  MmVersionArgs.Arg0 = ARM_SMC_ID_MM_VERSION_AARCH32;
> +
> +  ArmCallSmc (&MmVersionArgs);
> +
> +  MmVersion = MmVersionArgs.Arg0;
> +
> +  if ((MM_MAJOR_VER (MmVersion) == MM_CALLER_MAJOR_VER) &&
> +      (MM_MINOR_VER (MmVersion) >= MM_CALLER_MINOR_VER))
> +  {
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "MM Version: Major=0x%x, Minor=0x%x\n",
> +      MM_MAJOR_VER (MmVersion),
> +      MM_MINOR_VER (MmVersion)
> +      ));
> +    Status = EFI_SUCCESS;
> +  } else {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "Incompatible MM Versions.\n Current Version: Major=0x%x, "
> +      "Minor=0x%x.\n Expected: Major=0x%x, Minor>=0x%x.\n",
> +      MM_MAJOR_VER (MmVersion),
> +      MM_MINOR_VER (MmVersion),
> +      MM_CALLER_MAJOR_VER,
> +      MM_CALLER_MINOR_VER
> +      ));
> +    Status = EFI_UNSUPPORTED;
> +  }
> +
> +  return Status;
> +}
> +
> +STATIC EFI_GUID *CONST mGuidedEventGuid[] = {
> +  &gEfiEndOfDxeEventGroupGuid,
> +  &gEfiEventExitBootServicesGuid,
> +  &gEfiEventReadyToBootGuid,
> +};
> +
> +STATIC EFI_EVENT mGuidedEvent[ARRAY_SIZE (mGuidedEventGuid)];
> +
> +/**
> +  Event notification that is fired when GUIDed Event Group is signaled.
> +
> +  @param  Event                 The Event that is being processed, not used.
> +  @param  Context               Event Context, not used.
> +
> +**/
> +STATIC
> +VOID
> +EFIAPI
> +MmGuidedEventNotify (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_MM_COMMUNICATE_HEADER Header;
> +  UINTN                     Size;
> +
> +  //
> +  // Use Guid to initialize EFI_SMM_COMMUNICATE_HEADER structure
> +  //
> +  CopyGuid (&Header.HeaderGuid, Context);
> +  Header.MessageLength = 1;
> +  Header.Data[0] = 0;
> +
> +  Size = sizeof (Header);
> +  MmCommunicationCommunicate (&mMmCommunication, &Header, &Size);
> +}
> +
> +/**
> +  The Entry Point for MM Communication
> +
> +  This function installs the MM communication protocol interface and finds out
> +  what type of buffer management will be required prior to invoking the
> +  communication SMC.
> +
> +  @param  ImageHandle    The firmware allocated handle for the EFI image.
> +  @param  SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS    The entry point is executed successfully.
> +  @retval Other          Some error occurred when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MmCommunicationInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN      Index;
> +
> +  // Check if we can make the MM call
> +  Status = GetMmCompatibility ();
> +  if (EFI_ERROR (Status)) {
> +    goto ReturnErrorStatus;
> +  }
> +
> +  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
> +  // During boot, virtual and physical are same
> +  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
> +  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
> +
> +  ASSERT (mNsCommBuffMemRegion.PhysicalBase != 0);
> +
> +  ASSERT (mNsCommBuffMemRegion.Length != 0);
> +
> +#if !defined(MM_EARLY_MEM_ALLOCATE)
> +  Status = gDS->AddMemorySpace (
> +                  EfiGcdMemoryTypeReserved,
> +                  mNsCommBuffMemRegion.PhysicalBase,
> +                  mNsCommBuffMemRegion.Length,
> +                  EFI_MEMORY_WB |
> +                  EFI_MEMORY_XP |
> +                  EFI_MEMORY_RUNTIME
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Failed to add MM-NS Buffer Memory Space\n",
> +      __FUNCTION__
> +      ));
> +    goto ReturnErrorStatus;
> +  }
> +
> +  Status = gDS->SetMemorySpaceAttributes (
> +                  mNsCommBuffMemRegion.PhysicalBase,
> +                  mNsCommBuffMemRegion.Length,
> +                  EFI_MEMORY_WB | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Failed to set MM-NS Buffer Memory attributes\n",
> +      __FUNCTION__
> +      ));
> +    goto CleanAddedMemorySpace;
> +  }
> +#endif
> +
> +  // Install the communication protocol
> +  Status = gBS->InstallProtocolInterface (
> +                  &mMmCommunicateHandle,
> +                  &gEfiMmCommunicationProtocolGuid,
> +                  EFI_NATIVE_INTERFACE,
> +                  &mMmCommunication
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Failed to install MM communication protocol\n",
> +      __FUNCTION__
> +      ));
> +    goto CleanAddedMemorySpace;
> +  }
> +
> +  // Register notification callback when virtual address is associated
> +  // with the physical address.
> +  // Create a Set Virtual Address Map event.
> +  Status = gBS->CreateEvent (
> +                  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
> +                  TPL_NOTIFY,
> +                  NotifySetVirtualAddressMap,
> +                  NULL,
> +                  &mSetVirtualAddressMapEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  for (Index = 0; Index < ARRAY_SIZE (mGuidedEventGuid); Index++) {
> +    Status = gBS->CreateEventEx (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    MmGuidedEventNotify,
> +                    mGuidedEventGuid[Index],
> +                    mGuidedEventGuid[Index],
> +                    &mGuidedEvent[Index]
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +    if (EFI_ERROR (Status)) {
> +      while (Index-- > 0) {
> +        gBS->CloseEvent (mGuidedEvent[Index]);
> +      }
> +      goto UninstallProtocol;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +
> +UninstallProtocol:
> +  gBS->UninstallProtocolInterface (
> +         mMmCommunicateHandle,
> +         &gEfiMmCommunicationProtocolGuid,
> +         &mMmCommunication
> +         );
> +
> +CleanAddedMemorySpace:
> +#if !defined(MM_EARLY_MEM_ALLOCATE)
> +  gDS->RemoveMemorySpace (
> +         mNsCommBuffMemRegion.PhysicalBase,
> +         mNsCommBuffMemRegion.Length
> +         );
> +#endif
> +
> +ReturnErrorStatus:
> +  return EFI_INVALID_PARAMETER;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
> new file mode 100644
> index 000000000000..d3925015612f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.c
> @@ -0,0 +1,37 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Uefi/UefiSpec.h>
> +
> +#include <Library/HobLib.h>
> +#include <Library/PeimEntryPoint.h>
> +
> +/**
> +  Entry point function for the PEIM
> +
> +  @param FileHandle      Handle of the file being invoked.
> +  @param PeiServices     Describes the list of possible PEI Services.
> +
> +  @return EFI_SUCCESS    If we installed our PPI
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +MmCommunicationPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS MmBufferBase = PcdGet64 (PcdMmBufferBase);
> +  UINT64               MmBufferSize = PcdGet64 (PcdMmBufferSize);
> +
> +  BuildMemoryAllocationHob (MmBufferBase, MmBufferSize, EfiRuntimeServicesData);
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
@ 2021-06-04 23:07   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:07 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:55 +0700, Nhi Pham wrote:
> The Ampere Altra System Firmware provides a fail-safe feature to help
> recover the system if there are setting changes such as Core voltage,
> DRAM parameters that cause the UEFI failed to boot.
> 
> The FailSafeLib supports API calls to Secure World to:
> * Get the FailSafe region information.
> * Get the current FailSafe status.
> * Inform to FailSafe monitor that the system boots successfully.
> * Simulate UEFI boot failure due to config wrong NVPARAM for
>   testing failsafe feature.
> 
> This library will be consumed by FailSafe DXE driver.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

> ---
>  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec               |   3 +
>  Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf |  41 +++
>  Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h       |  62 ++++
>  Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c   | 320 ++++++++++++++++++++
>  4 files changed, 426 insertions(+)
> 
> diff --git a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
> index 7c1d1f84f780..6e33d96c7ea5 100755
> --- a/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
> +++ b/Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
> @@ -22,7 +22,10 @@ [Defines]
>  #
>  ################################################################################
>  [Includes]
> +  Include                        # Root include for the package
>  
>  [LibraryClasses]
> +  ##  @libraryclass  Provides functions to support FailSafe operations.
> +  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
>  
>  [Guids]
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
> new file mode 100755
> index 000000000000..456b9d5fc85b
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = FailSafeLib
> +  FILE_GUID                      = 3403D080-6D76-11E7-907B-A6006AD3DBA0
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = FailSafeLib
> +
> +[Sources]
> +  FailSafeLib.c
> +
> +[Protocols]
> +  gEfiMmCommunicationProtocolGuid        ## CONSUMES
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmSmcLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  IoLib
> +  NVParamLib
> +
> +[Guids]
> +  gSpiNorMmGuid
> diff --git a/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
> new file mode 100644
> index 000000000000..7ebd1c8a74a2
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Include/Library/FailSafeLib.h
> @@ -0,0 +1,62 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef FAILSAFE_LIB_H_
> +#define FAILSAFE_LIB_H_
> +
> +enum {
> +  MM_SPINOR_FUNC_GET_INFO,
> +  MM_SPINOR_FUNC_READ,
> +  MM_SPINOR_FUNC_WRITE,
> +  MM_SPINOR_FUNC_ERASE,
> +  MM_SPINOR_FUNC_GET_NVRAM_INFO,
> +  MM_SPINOR_FUNC_GET_NVRAM2_INFO,
> +  MM_SPINOR_FUNC_GET_FAILSAFE_INFO
> +};
> +
> +#define MM_SPINOR_RES_SUCCESS           0xAABBCC00
> +#define MM_SPINOR_RES_FAIL              0xAABBCCFF
> +
> +enum {
> +  FAILSAFE_BOOT_NORMAL = 0,
> +  FAILSAFE_BOOT_LAST_KNOWN_SETTINGS,
> +  FAILSAFE_BOOT_DEFAULT_SETTINGS,
> +  FAILSAFE_BOOT_DDR_DOWNGRADE,
> +  FAILSAFE_BOOT_SUCCESSFUL
> +};
> +
> +/**
> +  Get the FailSafe region information.
> +**/
> +EFI_STATUS
> +EFIAPI
> +FailSafeGetRegionInfo (
> +  UINT64 *Offset,
> +  UINT64 *Size
> +  );
> +
> +/**
> +  Inform to FailSafe monitor that the system boots successfully.
> +**/
> +EFI_STATUS
> +EFIAPI
> +FailSafeBootSuccessfully (
> +  VOID
> +  );
> +
> +/**
> +  Simulate UEFI boot failure due to config wrong NVPARAM for
> +  testing failsafe feature
> +**/
> +EFI_STATUS
> +EFIAPI
> +FailSafeTestBootFailure (
> +  VOID
> +  );
> +
> +#endif /* FAILSAFE_LIB_H_ */
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
> new file mode 100644
> index 000000000000..a567ab91375f
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.c
> @@ -0,0 +1,320 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Uefi.h>
> +
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/FailSafeLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Platform/Ac01.h>
> +#include <Protocol/MmCommunication.h>
> +
> +#define EFI_MM_MAX_PAYLOAD_U64_E  10
> +#define EFI_MM_MAX_PAYLOAD_SIZE   (EFI_MM_MAX_PAYLOAD_U64_E * sizeof (UINT64))
> +
> +EFI_MM_COMMUNICATION_PROTOCOL *mFlashLibMmCommProtocol = NULL;
> +
> +typedef struct {
> +  /* Allows for disambiguation of the message format */
> +  EFI_GUID HeaderGuid;
> +  /*
> +   * Describes the size of Data (in bytes) and does not include the size
> +   * of the header
> +   */
> +  UINTN MsgLength;
> +} EFI_MM_COMM_HEADER_NOPAYLOAD;
> +
> +typedef struct {
> +  UINT64 Data[EFI_MM_MAX_PAYLOAD_U64_E];
> +} EFI_MM_COMM_SPINOR_PAYLOAD;
> +
> +typedef struct {
> +  EFI_MM_COMM_HEADER_NOPAYLOAD EfiMmHdr;
> +  EFI_MM_COMM_SPINOR_PAYLOAD   PayLoad;
> +} EFI_MM_COMM_REQUEST;
> +
> +typedef struct {
> +  UINT64 Status;
> +} EFI_MM_COMMUNICATE_SPINOR_RES;
> +
> +typedef struct {
> +  UINT64 Status;
> +  UINT64 FailSafeBase;
> +  UINT64 FailSafeSize;
> +} EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES;
> +
> +EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT8  ImgMajorVer;
> +  UINT8  ImgMinorVer;
> +  UINT32 NumRetry1;
> +  UINT32 NumRetry2;
> +  UINT32 MaxRetry;
> +  UINT8  Status;
> +  /*
> +   * Byte[3]: Reserved
> +   * Byte[2]: Slave MCU Failure Mask
> +   * Byte[1]: Reserved
> +   * Byte[0]: Master MCU Failure Mask
> +   */
> +  UINT32 MCUFailsMask;
> +  UINT16 CRC16;
> +  UINT8  Reserved[3];
> +} FAIL_SAFE_CONTEXT;
> +
> +#pragma pack()
> +
> +STATIC
> +EFI_STATUS
> +UefiMmCreateSpiNorReq (
> +  VOID   *Data,
> +  UINT64 Size
> +  )
> +{
> +  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
> +  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
> +
> +  if (Size != 0) {
> +    ASSERT (Data);
> +    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
> +
> +    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +INTN
> +CheckCrc16 (
> +  UINT8 *Pointer,
> +  INTN  Count
> +  )
> +{
> +  INTN Crc = 0;
> +  INTN Index;
> +
> +  while (--Count >= 0) {
> +    Crc = Crc ^ (INTN)*Pointer++ << 8;
> +    for (Index = 0; Index < 8; ++Index) {
> +      if ((Crc & 0x8000) != 0) {
> +        Crc = Crc << 1 ^ 0x1021;
> +      } else {
> +        Crc = Crc << 1;
> +      }
> +    }
> +  }
> +
> +  return Crc & 0xFFFF;
> +}
> +
> +BOOLEAN
> +FailSafeValidCRC (
> +  FAIL_SAFE_CONTEXT *FailSafeBuf
> +  )
> +{
> +  UINT8  Valid;
> +  UINT16 Crc;
> +  UINT32 Len;
> +
> +  Len = sizeof (FAIL_SAFE_CONTEXT);
> +  Crc = FailSafeBuf->CRC16;
> +  FailSafeBuf->CRC16 = 0;
> +
> +  Valid = (Crc == CheckCrc16 ((UINT8 *)FailSafeBuf, Len));
> +  FailSafeBuf->CRC16 = Crc;
> +
> +  return Valid;
> +}
> +
> +BOOLEAN
> +FailSafeFailureStatus (
> +  UINT8 Status
> +  )
> +{
> +  if ((Status == FAILSAFE_BOOT_LAST_KNOWN_SETTINGS) ||
> +      (Status == FAILSAFE_BOOT_DEFAULT_SETTINGS) ||
> +      (Status == FAILSAFE_BOOT_DDR_DOWNGRADE))
> +  {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FailSafeGetRegionInfo (
> +  UINT64 *Offset,
> +  UINT64 *Size
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *MmSpiNorFailSafeInfoRes;
> +  UINT64                                      MmData[5];
> +  UINTN                                       DataSize;
> +  EFI_STATUS                                  Status;
> +
> +  if (mFlashLibMmCommProtocol == NULL) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiMmCommunicationProtocolGuid,
> +                    NULL,
> +                    (VOID **)&mFlashLibMmCommProtocol
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: Can't locate gEfiMmCommunicationProtocolGuid\n", __FUNCTION__));
> +      return Status;
> +    }
> +  }
> +
> +  MmData[0] = MM_SPINOR_FUNC_GET_FAILSAFE_INFO;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  DataSize = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = mFlashLibMmCommProtocol->Communicate (
> +                                      mFlashLibMmCommProtocol,
> +                                      (VOID *)&mEfiMmSpiNorReq,
> +                                      &DataSize
> +                                      );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorFailSafeInfoRes = (EFI_MM_COMMUNICATE_SPINOR_FAILSAFE_INFO_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorFailSafeInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Get flash information failed: 0x%llx\n",
> +      __FUNCTION__,
> +      MmSpiNorFailSafeInfoRes->Status
> +      ));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  *Offset = MmSpiNorFailSafeInfoRes->FailSafeBase;
> +  *Size   = MmSpiNorFailSafeInfoRes->FailSafeSize;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FailSafeBootSuccessfully (
> +  VOID
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
> +  UINT64                        MmData[5];
> +  UINTN                         Size;
> +  EFI_STATUS                    Status;
> +  UINT64                        FailSafeStartOffset;
> +  UINT64                        FailSafeSize;
> +  FAIL_SAFE_CONTEXT             FailSafeBuf;
> +
> +  Status = FailSafeGetRegionInfo (&FailSafeStartOffset, &FailSafeSize);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to get context region information\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  MmData[0] = MM_SPINOR_FUNC_READ;
> +  MmData[1] = FailSafeStartOffset;
> +  MmData[2] = (UINT64)sizeof (FAIL_SAFE_CONTEXT);
> +  MmData[3] = (UINT64)&FailSafeBuf;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = mFlashLibMmCommProtocol->Communicate (
> +                                      mFlashLibMmCommProtocol,
> +                                      (VOID *)&mEfiMmSpiNorReq,
> +                                      &Size
> +                                      );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Read context failed: 0x%llx\n",
> +      __FUNCTION__,
> +      MmSpiNorRes->Status
> +      ));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  /*
> +   * If failsafe context is invalid, it is already indicate a successful boot
> +   * and don't need to be cleared
> +   */
> +  if (!FailSafeValidCRC (&FailSafeBuf)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  /*
> +   * If failsafe context is valid, and:
> +   *    - The status indicate non-failure, then don't clear it
> +   *    - The status indicate a failure, then go and clear it
> +   */
> +  if (!FailSafeFailureStatus (FailSafeBuf.Status)) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  MmData[0] = MM_SPINOR_FUNC_ERASE;
> +  MmData[1] = FailSafeStartOffset;
> +  MmData[2] = FailSafeSize;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = mFlashLibMmCommProtocol->Communicate (
> +                                      mFlashLibMmCommProtocol,
> +                                      (VOID *)&mEfiMmSpiNorReq,
> +                                      &Size
> +                                      );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a: Erase context failed: 0x%llx\n",
> +      __FUNCTION__,
> +      MmSpiNorRes->Status
> +      ));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FailSafeTestBootFailure (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value = 0;
> +
> +  /*
> +   * Simulate UEFI boot failure due to config wrong NVPARAM for
> +   * testing failsafe feature
> +   */
> +  Status = NVParamGet (NV_UEFI_FAILURE_FAILSAFE_OFFSET, NV_PERM_ALL, &Value);
> +  if (!EFI_ERROR (Status) && (Value == 1)) {
> +    while (1) {
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
@ 2021-06-04 23:12   ` Leif Lindholm
  2021-06-15 16:47     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:12 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:56 +0700, Nhi Pham wrote:
> The FailSafeDxe driver reverts the system's configuration to known good
> values if the system fails to boot up multiple times. It also implements
> the Watchdog Timer Architectural Protocol to reset the system if it
> hangs.
> 
> By default, when system starts, it configures the secure watchdog timer
> with a default value of 5 minutes. If the system boots up cleanly to the
> considered good stage, the counter is cleared as it indicates FailSafe
> monitor (ATF) that has booted up successfully. If the timer expires, it
> is considered a failed boot and system is rebooted.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                  |   1 -
>  Platform/Ampere/JadePkg/Jade.dsc                                      |   9 +
>  Platform/Ampere/JadePkg/Jade.fdf                                      |   6 +-
>  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf |  54 +++
>  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h      |  20 ++
>  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h      |  29 ++
>  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c   | 184 ++++++++++
>  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c      | 357 ++++++++++++++++++++
>  8 files changed, 658 insertions(+), 2 deletions(-)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 0332473b59b0..6a6f72e995af 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -585,7 +585,6 @@ [Components.common]
>    # Timer
>    #
>    ArmPkg/Drivers/TimerDxe/TimerDxe.inf
> -  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf

It's not clear from the commit message why this should happen.

>  
>    #
>    # ARM GIC Dxe
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index f68af24a0d78..f92855af99ab 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -75,6 +75,11 @@ [LibraryClasses]
>    #
>    RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>  
> +  #
> +  # Library for FailSafe support
> +  #
> +  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
> +
>  ################################################################################
>  #
>  # Specific Platform Pcds
> @@ -98,3 +103,7 @@ [PcdsFixedAtBuild.common]
>  #
>  ################################################################################
>  [Components.common]
> +  #
> +  # FailSafe and Watchdog Timer
> +  #
> +  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 905289844378..80a86d7c1156 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -185,7 +185,11 @@ [FV.FvMain]
>    # Timer
>    #
>    INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
> -  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf

It's not clear from the commit message why this should happen.

/
    Leif

> +
> +  #
> +  # FailSafe and Watchdog Timer
> +  #
> +  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>  
>    #
>    # ARM GIC Dxe
> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> new file mode 100755
> index 000000000000..60de10c95c85
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> @@ -0,0 +1,54 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = FailSafeDxe
> +  FILE_GUID                      = 7BC4F970-B1CF-11E6-80F5-76304DEC7EB7
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = FailSafeDxeEntryPoint
> +
> +[Sources]
> +  FailSafe.h
> +  FailSafeDxe.c
> +  Watchdog.c
> +  Watchdog.h
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmSmcLib
> +  DebugLib
> +  FailSafeLib
> +  NVParamLib
> +  PcdLib
> +  TimerLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Pcd]
> +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
> +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
> +
> +[Protocols]
> +  gEfiWatchdogTimerArchProtocolGuid             ## PRODUCES
> +  gHardwareInterrupt2ProtocolGuid               ## CONSUMES
> +
> +[Depex]
> +  gHardwareInterrupt2ProtocolGuid
> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
> new file mode 100644
> index 000000000000..8bf3a98f1d8e
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
> @@ -0,0 +1,20 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef FAILSAFE_H_
> +#define FAILSAFE_H_
> +
> +#include <Uefi.h>
> +
> +BOOLEAN
> +EFIAPI
> +IsFailSafeOff (
> +  VOID
> +  );
> +
> +#endif /* FAILSAFE_H_ */
> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
> new file mode 100755
> index 000000000000..6c9106fdbea5
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
> @@ -0,0 +1,29 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef GENERIC_WATCHDOG_H_
> +#define GENERIC_WATCHDOG_H_
> +
> +#include <Protocol/WatchdogTimer.h>
> +
> +/* The number of 100ns periods (the unit of time passed to these functions)
> +   in a second */
> +#define TIME_UNITS_PER_SECOND           10000000
> +
> +/**
> +  The function to install Watchdog timer protocol to the system
> +
> +  @retval  Return         EFI_SUCCESS if install Watchdog timer protocol successfully.
> + **/
> +EFI_STATUS
> +EFIAPI
> +WatchdogTimerInstallProtocol (
> +  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
> +  );
> +
> +#endif /* GENERIC_WATCHDOG_H_ */
> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
> new file mode 100644
> index 000000000000..1b8978b12ea7
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
> @@ -0,0 +1,184 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/FailSafeLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#include "FailSafe.h"
> +#include "Watchdog.h"
> +
> +STATIC UINTN                            gWatchdogOSTimeout;
> +STATIC BOOLEAN                          gFailSafeOff;
> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer;
> +
> +EFI_STATUS
> +EFIAPI
> +FailSafeTestBootFailure (
> +  VOID
> +  );
> +
> +STATIC VOID
> +FailSafeTurnOff (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (IsFailSafeOff ()) {
> +    return;
> +  }
> +
> +  Status = FailSafeBootSuccessfully ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  gFailSafeOff = TRUE;
> +
> +  /* Disable Watchdog timer */
> +  gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
> +}
> +
> +BOOLEAN
> +EFIAPI
> +IsFailSafeOff (
> +  VOID
> +  )
> +{
> +  return gFailSafeOff;
> +}
> +
> +/**
> +  The function to disable Watchdog timer when enter Setup screen
> + **/
> +VOID
> +WdtTimerEnterSetupScreenCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  /* Make sure FailSafe is turned off */
> +  FailSafeTurnOff ();
> +}
> +
> +/**
> +  The function to refresh Watchdog timer in the event before booting
> + **/
> +VOID
> +WdtTimerBeforeBootCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  /*
> +   * At this point, the system is considered boot successfully to BIOS
> +   */
> +  FailSafeTurnOff ();
> +
> +  /*
> +   * It is BIOS's responsibility to setup Watchdog when load an EFI application
> +   * after this step
> +   */
> +}
> +
> +/**
> +  The function to refresh Watchdog timer in the event before exiting boot services
> + **/
> +VOID
> +WdtTimerExitBootServiceCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +
> +  /* Enable Watchdog timer for OS booting */
> +  if (gWatchdogOSTimeout != 0) {
> +    gWatchdogTimer->SetTimerPeriod (
> +                      gWatchdogTimer,
> +                      gWatchdogOSTimeout * TIME_UNITS_PER_SECOND
> +                      );
> +  } else {
> +    /* Disable Watchdog timer */
> +    gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
> +  }
> +}
> +
> +/**
> +  This function is a hook called when user loads the manufacturing
> +  or optimal defaults.
> +
> +  @param Defaults : (NVRAM_VARIABLE *)optimal or manufacturing
> +  @Data           : Messagebox
> +
> +  @retval VOID
> +**/
> +VOID
> +LoadNVRAMDefaultConfig (
> +  IN VOID  *Defaults,
> +  IN UINTN Data
> +  )
> +{
> +  NVParamClrAll ();
> +}
> +
> +/**
> +  Main entry for this driver.
> +
> +  @param ImageHandle     Image handle this driver.
> +  @param SystemTable     Pointer to SystemTable.
> +
> +  @retval EFI_SUCESS     This function always complete successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FailSafeDxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_EVENT  ExitBootServicesEvent;
> +  EFI_STATUS Status;
> +
> +  gFailSafeOff = FALSE;
> +
> +  FailSafeTestBootFailure ();
> +
> +  /* We need to setup non secure Watchdog to ensure that the system will
> +   * boot to OS successfully.
> +   *
> +   * The BIOS doesn't handle Watchdog interrupt so we expect WS1 asserted EL3
> +   * when Watchdog timeout triggered
> +   */
> +
> +  Status = WatchdogTimerInstallProtocol (&gWatchdogTimer);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  // FIXME: We should register a callback function before entering to Setup screen
> +  // rather than always call it at DXE phase.
> +  FailSafeTurnOff ();
> +
> +  /* Register event before exit boot services */
> +  Status = gBS->CreateEvent (
> +                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
> +                  TPL_NOTIFY,
> +                  WdtTimerExitBootServiceCallback,
> +                  NULL,
> +                  &ExitBootServicesEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
> new file mode 100644
> index 000000000000..34329d04206a
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
> @@ -0,0 +1,357 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/ArmGenericTimerCounterLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/HardwareInterrupt2.h>
> +
> +#include "FailSafe.h"
> +#include "Watchdog.h"
> +
> +/* Watchdog timer controller registers */
> +#define WDT_CTRL_BASE_REG                     FixedPcdGet64 (PcdGenericWatchdogControlBase)
> +#define WDT_CTRL_WCS_OFF                      0x0
> +#define WDT_CTRL_WCS_ENABLE_MASK              0x1
> +#define WDT_CTRL_WOR_OFF                      0x8
> +#define WDT_CTRL_WCV_OFF                      0x10
> +#define WS0_INTERRUPT_SOURCE                  FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum)
> +
> +STATIC UINT64                           mNumTimerTicks;
> +STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
> +BOOLEAN                                 mInterruptWS0Enabled;
> +
> +STATIC
> +VOID
> +WatchdogTimerWriteOffsetRegister (
> +  UINT32 Value
> +  )
> +{
> +  MmioWrite32 (WDT_CTRL_BASE_REG + WDT_CTRL_WOR_OFF, Value);
> +}
> +
> +STATIC
> +VOID
> +WatchdogTimerWriteCompareRegister (
> +  UINT64 Value
> +  )
> +{
> +  MmioWrite64 (WDT_CTRL_BASE_REG + WDT_CTRL_WCV_OFF, Value);
> +}
> +
> +STATIC
> +EFI_STATUS
> +WatchdogTimerEnable (
> +  IN BOOLEAN Enable
> +  )
> +{
> +  UINT32 Val =  MmioRead32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF));
> +
> +  if (Enable) {
> +    Val |= WDT_CTRL_WCS_ENABLE_MASK;
> +  } else {
> +    Val &= ~WDT_CTRL_WCS_ENABLE_MASK;
> +  }
> +  MmioWrite32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF), Val);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +WatchdogTimerSetup (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  /* Disable Watchdog timer */
> +  WatchdogTimerEnable (FALSE);
> +
> +  if (!mInterruptWS0Enabled) {
> +    Status = mInterruptProtocol->EnableInterruptSource (
> +                                   mInterruptProtocol,
> +                                   WS0_INTERRUPT_SOURCE
> +                                   );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    mInterruptWS0Enabled = TRUE;
> +  }
> +
> +  if (mNumTimerTicks == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  /* If the number of required ticks is greater than the max the Watchdog's
> +     offset register (WOR) can hold, we need to manually compute and set
> +     the compare register (WCV) */
> +  if (mNumTimerTicks > MAX_UINT32) {
> +    /* We need to enable the Watchdog *before* writing to the compare register,
> +       because enabling the Watchdog causes an "explicit refresh", which
> +       clobbers the compare register (WCV). In order to make sure this doesn't
> +       trigger an interrupt, set the offset to max. */
> +    WatchdogTimerWriteOffsetRegister (MAX_UINT32);
> +    WatchdogTimerEnable (TRUE);
> +    WatchdogTimerWriteCompareRegister (ArmGenericTimerGetSystemCount () + mNumTimerTicks);
> +  } else {
> +    WatchdogTimerWriteOffsetRegister ((UINT32)mNumTimerTicks);
> +    WatchdogTimerEnable (TRUE);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/* This function is called when the Watchdog's first signal (WS0) goes high.
> +   It uses the ResetSystem Runtime Service to reset the board.
> +*/
> +VOID
> +EFIAPI
> +WatchdogTimerInterruptHandler (
> +  IN HARDWARE_INTERRUPT_SOURCE Source,
> +  IN EFI_SYSTEM_CONTEXT        SystemContext
> +  )
> +{
> +  STATIC CONST CHAR16 ResetString[]= L"The generic Watchdog timer ran out.";
> +
> +  mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
> +
> +  if (!IsFailSafeOff ()) {
> +    /* Not handling interrupt as ATF is monitoring it */
> +    return;
> +  }
> +
> +  WatchdogTimerEnable (FALSE);
> +
> +  gRT->ResetSystem (
> +         EfiResetCold,
> +         EFI_TIMEOUT,
> +         StrSize (ResetString),
> +         (VOID *)&ResetString
> +         );
> +
> +  /* If we got here then the reset didn't work */
> +  ASSERT (FALSE);
> +}
> +
> +/**
> +  This function registers the handler NotifyFunction so it is called every time
> +  the Watchdog timer expires.  It also passes the amount of time since the last
> +  handler call to the NotifyFunction.
> +  If NotifyFunction is not NULL and a handler is not already registered,
> +  then the new handler is registered and EFI_SUCCESS is returned.
> +  If NotifyFunction is NULL, and a handler is already registered,
> +  then that handler is unregistered.
> +  If an attempt is made to register a handler when a handler is already
> +  registered, then EFI_ALREADY_STARTED is returned.
> +  If an attempt is made to unregister a handler when a handler is not
> +  registered, then EFI_INVALID_PARAMETER is returned.
> +
> +  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param  NotifyFunction   The function to call when a timer interrupt fires.
> +                           This function executes at TPL_HIGH_LEVEL. The DXE
> +                           Core will register a handler for the timer interrupt,
> +                           so it can know how much time has passed. This
> +                           information is used to signal timer based events.
> +                           NULL will unregister the handler.
> +
> +  @retval EFI_UNSUPPORTED       The code does not support NotifyFunction.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogTimerRegisterHandler (
> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
> +  IN       EFI_WATCHDOG_TIMER_NOTIFY        NotifyFunction
> +  )
> +{
> +  /* Not support. Watchdog will reset the board */
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  This function sets the amount of time to wait before firing the Watchdog
> +  timer to TimerPeriod 100ns units.  If TimerPeriod is 0, then the Watchdog
> +  timer is disabled.
> +
> +  @param  This             The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
> +  @param  TimerPeriod      The amount of time in 100ns units to wait before
> +                           the Watchdog timer is fired. If TimerPeriod is zero,
> +                           then the Watchdog timer is disabled.
> +
> +  @retval EFI_SUCCESS           The Watchdog timer has been programmed to fire
> +                                in Time  100ns units.
> +  @retval EFI_DEVICE_ERROR      A Watchdog timer could not be programmed due
> +                                to a device error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogTimerSetPeriod (
> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
> +  IN       UINT64                           TimerPeriod   // In 100ns units
> +  )
> +{
> +  mNumTimerTicks  = (ArmGenericTimerGetTimerFreq () * TimerPeriod) / TIME_UNITS_PER_SECOND;
> +
> +  if (!IsFailSafeOff ()) {
> +    /* Not support Watchdog timer service until FailSafe is off as ATF is monitoring it */
> +    return EFI_SUCCESS;
> +  }
> +
> +  return WatchdogTimerSetup ();
> +}
> +
> +/**
> +  This function retrieves the period of timer interrupts in 100ns units,
> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
> +  returned, then the timer is currently disabled.
> +
> +  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
> +  @param  TimerPeriod      A pointer to the timer period to retrieve in
> +                           100ns units. If 0 is returned, then the timer is
> +                           currently disabled.
> +
> +
> +  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
> +  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogTimerGetPeriod (
> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
> +  OUT      UINT64                           *TimerPeriod
> +  )
> +{
> +  if (TimerPeriod == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *TimerPeriod = ((TIME_UNITS_PER_SECOND / ArmGenericTimerGetTimerFreq ()) * mNumTimerTicks);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Interface structure for the Watchdog Architectural Protocol.
> +
> +  @par Protocol Description:
> +  This protocol provides a service to set the amount of time to wait
> +  before firing the Watchdog timer, and it also provides a service to
> +  register a handler that is invoked when the Watchdog timer fires.
> +
> +  @par When the Watchdog timer fires, control will be passed to a handler
> +  if one has been registered.  If no handler has been registered,
> +  or the registered handler returns, then the system will be
> +  reset by calling the Runtime Service ResetSystem().
> +
> +  @param RegisterHandler
> +  Registers a handler that will be called each time the
> +  Watchdogtimer interrupt fires.  TimerPeriod defines the minimum
> +  time between timer interrupts, so TimerPeriod will also
> +  be the minimum time between calls to the registered
> +  handler.
> +  NOTE: If the Watchdog resets the system in hardware, then
> +        this function will not have any chance of executing.
> +
> +  @param SetTimerPeriod
> +  Sets the period of the timer interrupt in 100ns units.
> +  This function is optional, and may return EFI_UNSUPPORTED.
> +  If this function is supported, then the timer period will
> +  be rounded up to the nearest supported timer period.
> +
> +  @param GetTimerPeriod
> +  Retrieves the period of the timer interrupt in 100ns units.
> +
> +**/
> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
> +  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER)WatchdogTimerRegisterHandler,
> +  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)WatchdogTimerSetPeriod,
> +  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)WatchdogTimerGetPeriod
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +WatchdogTimerInstallProtocol (
> +  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_HANDLE Handle;
> +  EFI_TPL    CurrentTpl;
> +
> +  /* Make sure the Watchdog Timer Architectural Protocol has not been installed
> +     in the system yet.
> +     This will avoid conflicts with the universal Watchdog */
> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
> +
> +  ASSERT (ArmGenericTimerGetTimerFreq () != 0);
> +
> +  /* Install interrupt handler */
> +  Status = gBS->LocateProtocol (
> +                  &gHardwareInterrupt2ProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mInterruptProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  /*
> +   * We don't want to be interrupted while registering Watchdog interrupt source as the interrupt
> +   * may be trigger in the middle because the interrupt line already enabled in the EL3.
> +   */
> +  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
> +
> +  Status = mInterruptProtocol->RegisterInterruptSource (
> +                                 mInterruptProtocol,
> +                                 WS0_INTERRUPT_SOURCE,
> +                                 WatchdogTimerInterruptHandler
> +                                 );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  /* Don't enable interrupt until FailSafe off */
> +  mInterruptWS0Enabled = FALSE;
> +  Status = mInterruptProtocol->DisableInterruptSource (
> +                                 mInterruptProtocol,
> +                                 WS0_INTERRUPT_SOURCE
> +                                 );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  gBS->RestoreTPL (CurrentTpl);
> +
> +  Status = mInterruptProtocol->SetTriggerType (
> +                                 mInterruptProtocol,
> +                                 WS0_INTERRUPT_SOURCE,
> +                                 EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH
> +                                 );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  /* Install the Timer Architectural Protocol onto a new handle */
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gEfiWatchdogTimerArchProtocolGuid,
> +                  &gWatchdogTimer,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mNumTimerTicks = 0;
> +
> +  if (WatchdogTimerProtocol != NULL) {
> +    *WatchdogTimerProtocol = &gWatchdogTimer;
> +  }
> +
> +  return Status;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
@ 2021-06-04 23:21   ` Leif Lindholm
  2021-06-15 16:47     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:21 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:57 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> The DwI2cLib library provides basic functions to control the I2C
> controller on Ampere Altra processor.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>
(but I think this was one of the ones that have issues that should be
addressed - please ensure build with CLANG38 before v3)

/
    Leif

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec            |   3 +
>  Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf |  38 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h      | 100 +++
>  Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c   | 883 ++++++++++++++++++++
>  4 files changed, 1024 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 73097afaf841..8be6a329bb26 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -28,6 +28,9 @@ [LibraryClasses]
>    ##  @libraryclass  Defines a set of methods to communicate with SCP.
>    SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
>  
> +  ##  @libraryclass  Defines a set of methods to read/write to I2C devices.
> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> +
>    ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>    MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> new file mode 100644
> index 000000000000..091f5f9b310c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> @@ -0,0 +1,38 @@
> +## @file
> +# Component description for DwI2cLib library for the Designware I2C controller.
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = DwI2cLib
> +  FILE_GUID                      = 222609E2-C181-11E6-A4A6-CEC0C932CE01
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = I2cLib
> +  CONSTRUCTOR                    = I2cLibConstructor
> +
> +[Sources]
> +  DwI2cLib.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  IoLib
> +  TimerLib
> +
> +[Guids]
> +  gEfiEventVirtualAddressChangeGuid
> +  gPlatformHobGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> new file mode 100644
> index 000000000000..f13794171029
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
> @@ -0,0 +1,100 @@
> +/** @file
> +  Library implementation for the Designware I2C controller.
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef I2C_LIB_H_
> +#define I2C_LIB_H_
> +
> +#include <Uefi/UefiBaseType.h>
> +
> +/**
> +  Write to I2C bus.
> +
> +  @param[in]     Bus          I2C bus Id.
> +  @param[in]     SlaveAddr    The address of slave device on the bus.
> +  @param[in,out] Buf          Buffer that holds data to write.
> +  @param[in,out] WriteLength  Pointer to length of buffer.
> +
> +  @return EFI_SUCCESS            Write successfully.
> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @return EFI_UNSUPPORTED        The bus is not supported.
> +  @return EFI_NOT_READY          The device/bus is not ready.
> +  @return EFI_TIMEOUT            Timeout why transferring data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWrite (
> +  IN     UINT32 Bus,
> +  IN     UINT32 SlaveAddr,
> +  IN OUT UINT8  *Buf,
> +  IN OUT UINT32 *WriteLength
> +  );
> +
> +/**
> +  Read data from I2C bus.
> +
> +  @param[in]     Bus          I2C bus Id.
> +  @param[in]     SlaveAddr    The address of slave device on the bus.
> +  @param[in]     BufCmd       Buffer where to send the command.
> +  @param[in]     CmdLength    Pointer to length of BufCmd.
> +  @param[in,out] Buf          Buffer where to put the read data to.
> +  @param[in,out] ReadLength   Pointer to length of buffer.
> +
> +  @return EFI_SUCCESS            Read successfully.
> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @return EFI_UNSUPPORTED        The bus is not supported.
> +  @return EFI_NOT_READY          The device/bus is not ready.
> +  @return EFI_TIMEOUT            Timeout why transferring data.
> +  @return EFI_CRC_ERROR          There are errors on receiving data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cRead (
> +  IN     UINT32 Bus,
> +  IN     UINT32 SlaveAddr,
> +  IN     UINT8  *BufCmd,
> +  IN     UINT32 CmdLength,
> +  IN OUT UINT8  *Buf,
> +  IN OUT UINT32 *ReadLength
> +  );
> +
> +/**
> + Setup new transaction with I2C slave device.
> +
> +  @param[in] Bus      I2C bus Id.
> +  @param[in] BusSpeed I2C bus speed in Hz.
> +
> +  @retval EFI_SUCCESS           Success.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cProbe (
> +  IN UINT32 Bus,
> +  IN UINTN  BusSpeed
> +  );
> +
> +/**
> + Setup a bus that to be used in runtime service.
> +
> +  @param[in] Bus I2C bus Id.
> +
> +  @retval EFI_SUCCESS  Success.
> +  @retval Otherwise    Error code.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cSetupRuntime (
> +  IN UINT32 Bus
> +  );
> +
> +#endif /* I2C_LIB_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
> new file mode 100644
> index 000000000000..5e7cd020223c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
> @@ -0,0 +1,883 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/I2cLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <PlatformInfoHob.h>
> +
> +#define I2cSync() { asm volatile ("dmb ish" : : : "memory"); }
> +
> +//
> +// Runtime needs to be 64K alignment
> +//
> +#define RUNTIME_ADDRESS_MASK           (~(SIZE_64KB - 1))
> +#define RUNTIME_ADDRESS_LENGTH         SIZE_64KB
> +
> +//
> +// Private I2C bus data
> +//
> +typedef struct {
> +  UINTN  Base;
> +  UINT32 BusSpeed;
> +  UINT32 RxFifo;
> +  UINT32 TxFifo;
> +  UINT32 PollingTime;
> +  UINT32 Enabled;
> +} DW_I2C_CONTEXT_T;
> +
> +//
> +// I2C SCL counter macros
> +//
> +typedef enum {
> +  I2cSpeedModeStandard = 0,
> +  I2cSpeedModeFast,
> +} I2C_SPEED_MODE;
> +
> +#define DW_I2C_MAXIMUM_SPEED_HZ 400000
> +
> +typedef enum {
> +  I2cSclSpkLen = 0,
> +  I2cSclHcnt,
> +  I2cSclLcnt,
> +} I2C_SCL_PARAM;
> +
> +STATIC UINT32 I2cSclParam[][3] = {
> +  /* SPK_LEN, HCNT, LCNT */
> +  [I2cSpeedModeStandard]   = { 10, 0x3E2, 0x47D }, // SS (Standard Speed)
> +  [I2cSpeedModeFast]       = { 10, 0xA4,  0x13F }, // FS (Fast Speed)
> +};
> +
> +STATIC BOOLEAN          mI2cRuntimeEnableArray[MAX_PLATFORM_I2C_BUS_NUM] = {FALSE};
> +STATIC UINTN            mI2cBaseArray[MAX_PLATFORM_I2C_BUS_NUM] = {PLATFORM_I2C_REGISTER_BASE};
> +STATIC DW_I2C_CONTEXT_T mI2cBusList[MAX_PLATFORM_I2C_BUS_NUM];
> +STATIC UINTN            mI2cClock = 0;
> +STATIC EFI_EVENT        mVirtualAddressChangeEvent = NULL;
> +
> +//
> +// Registers
> +//
> +#define DW_IC_CON                       0x0
> +#define DW_IC_CON_MASTER                BIT0
> +#define DW_IC_CON_SPEED_STD             BIT1
> +#define DW_IC_CON_SPEED_FAST            BIT2
> +#define DW_IC_CON_10BITADDR_MASTER      BIT4
> +#define DW_IC_CON_RESTART_EN            BIT5
> +#define DW_IC_CON_SLAVE_DISABLE         BIT6
> +#define DW_IC_TAR                       0x4
> +#define DW_IC_TAR_10BITS                BIT12
> +#define DW_IC_SAR                       0x8
> +#define DW_IC_DATA_CMD                  0x10
> +#define DW_IC_DATA_CMD_RESTART          BIT10
> +#define DW_IC_DATA_CMD_STOP             BIT9
> +#define DW_IC_DATA_CMD_CMD              BIT8
> +#define DW_IC_DATA_CMD_DAT_MASK         0xFF
> +#define DW_IC_SS_SCL_HCNT               0x14
> +#define DW_IC_SS_SCL_LCNT               0x18
> +#define DW_IC_FS_SCL_HCNT               0x1c
> +#define DW_IC_FS_SCL_LCNT               0x20
> +#define DW_IC_HS_SCL_HCNT               0x24
> +#define DW_IC_HS_SCL_LCNT               0x28
> +#define DW_IC_INTR_STAT                 0x2c
> +#define DW_IC_INTR_MASK                 0x30
> +#define DW_IC_INTR_RX_UNDER             BIT0
> +#define DW_IC_INTR_RX_OVER              BIT1
> +#define DW_IC_INTR_RX_FULL              BIT2
> +#define DW_IC_INTR_TX_EMPTY             BIT4
> +#define DW_IC_INTR_TX_ABRT              BIT6
> +#define DW_IC_INTR_ACTIVITY             BIT8
> +#define DW_IC_INTR_STOP_DET             BIT9
> +#define DW_IC_INTR_START_DET            BIT10
> +#define DW_IC_ERR_CONDITION \
> +                (DW_IC_INTR_RX_UNDER | DW_IC_INTR_RX_OVER | DW_IC_INTR_TX_ABRT)
> +#define DW_IC_RAW_INTR_STAT             0x34
> +#define DW_IC_CLR_INTR                  0x40
> +#define DW_IC_CLR_RX_UNDER              0x44
> +#define DW_IC_CLR_RX_OVER               0x48
> +#define DW_IC_CLR_TX_ABRT               0x54
> +#define DW_IC_CLR_ACTIVITY              0x5c
> +#define DW_IC_CLR_STOP_DET              0x60
> +#define DW_IC_CLR_START_DET             0x64
> +#define DW_IC_ENABLE                    0x6c
> +#define DW_IC_STATUS                    0x70
> +#define DW_IC_STATUS_ACTIVITY           BIT0
> +#define DW_IC_STATUS_TFE                BIT2
> +#define DW_IC_STATUS_RFNE               BIT3
> +#define DW_IC_STATUS_MST_ACTIVITY       BIT5
> +#define DW_IC_TXFLR                     0x74
> +#define DW_IC_RXFLR                     0x78
> +#define DW_IC_SDA_HOLD                  0x7c
> +#define DW_IC_TX_ABRT_SOURCE            0x80
> +#define DW_IC_ENABLE_STATUS             0x9c
> +#define DW_IC_COMP_PARAM_1              0xf4
> +#define  DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) \
> +           ((((x) >> 8) & 0xFF) + 1)
> +#define  DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) \
> +           ((((x) >> 16) & 0xFF) + 1)
> +#define DW_IC_COMP_TYPE                 0xfc
> +#define SB_DW_IC_CON                    0xa8
> +#define SB_DW_IC_SCL_TMO_CNT            0xac
> +#define SB_DW_IC_RX_PEC                 0xb0
> +#define SB_DW_IC_ACK                    0xb4
> +#define SB_DW_IC_FLG                    0xb8
> +#define SB_DW_IC_FLG_CLR                0xbc
> +#define SB_DW_IC_INTR_STAT              0xc0
> +#define SB_DW_IC_INTR_STAT_MASK         0xc4
> +#define SB_DW_IC_DEBUG_SEL              0xec
> +#define SB_DW_IC_ACK_DEBUG              0xf0
> +#define DW_IC_FS_SPKLEN                 0xa0
> +#define DW_IC_HS_SPKLEN                 0xa4
> +
> +//
> +// Timeout interval
> +//
> +// The interval is equal to the 10 times the signaling period
> +// for the highest I2C transfer speed used in the system.
> +//
> +#define DW_POLL_INTERVAL_US(x) (10 * (1000000 / (x)))
> +
> +//
> +// Maximum timeout count
> +//
> +#define DW_MAX_TRANSFER_POLL_COUNT 100000 // Maximum timeout: 10s
> +#define DW_MAX_STATUS_POLL_COUNT   100
> +
> +#define DW_POLL_MST_ACTIVITY_INTERVAL_US 1000 // 1ms
> +#define DW_MAX_MST_ACTIVITY_POLL_COUNT   20
> +
> +/**
> + Initialize I2C Bus
> + **/
> +VOID
> +I2cHWInit (
> +  UINT32 Bus
> +  )
> +{
> +  UINT32 Param;
> +
> +  mI2cBusList[Bus].Base = mI2cBaseArray[Bus];
> +
> +  Param = MmioRead32 (mI2cBusList[Bus].Base + DW_IC_COMP_PARAM_1);
> +
> +  mI2cBusList[Bus].PollingTime = DW_POLL_INTERVAL_US (mI2cBusList[Bus].BusSpeed);
> +  mI2cBusList[Bus].RxFifo = DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH (Param);
> +  mI2cBusList[Bus].TxFifo = DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH (Param);
> +  mI2cBusList[Bus].Enabled = 0;
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d, Rx_Buffer %d, Tx_Buffer %d\n",
> +    __FUNCTION__,
> +    Bus,
> +    mI2cBusList[Bus].RxFifo,
> +    mI2cBusList[Bus].TxFifo
> +    ));
> +}
> +
> +/**
> + Enable or disable I2C Bus
> + */
> +VOID
> +I2cEnable (
> +  UINT32 Bus,
> +  UINT32 Enable
> +  )
> +{
> +  UINT32 I2cStatusCnt;
> +  UINTN  Base;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  I2cStatusCnt = DW_MAX_STATUS_POLL_COUNT;
> +  mI2cBusList[Bus].Enabled = Enable;
> +
> +  MmioWrite32 (Base + DW_IC_ENABLE, Enable);
> +
> +  do {
> +    if ((MmioRead32 (Base + DW_IC_ENABLE_STATUS) & 0x01) == Enable) {
> +      break;
> +    }
> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> +  } while (I2cStatusCnt-- != 0);
> +
> +  if (I2cStatusCnt == 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: Enable/disable timeout\n", __FUNCTION__));
> +  }
> +
> +  if ((Enable == 0) || (I2cStatusCnt == 0)) {
> +    /* Unset the target adddress */
> +    MmioWrite32 (Base + DW_IC_TAR, 0);
> +    mI2cBusList[Bus].Enabled = 0;
> +  }
> +}
> +
> +/**
> + Setup Slave address
> + **/
> +VOID
> +I2cSetSlaveAddr (
> +  UINT32 Bus,
> +  UINT32 SlaveAddr
> +  )
> +{
> +  UINTN  Base;
> +  UINT32 OldEnableStatus;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  OldEnableStatus = mI2cBusList[Bus].Enabled;
> +
> +  I2cEnable (Bus, 0);
> +  MmioWrite32 (Base + DW_IC_TAR, SlaveAddr);
> +  if (OldEnableStatus != 0) {
> +    I2cEnable (Bus, 1);
> +  }
> +}
> +
> +/**
> + Check for errors on I2C Bus
> + **/
> +UINT32
> +I2cCheckErrors (
> +  UINT32 Bus
> +  )
> +{
> +  UINTN  Base;
> +  UINT32 ErrorStatus;
> +
> +  Base = mI2cBusList[Bus].Base;
> +
> +  ErrorStatus = MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_ERR_CONDITION;
> +
> +  if ((ErrorStatus & DW_IC_INTR_RX_UNDER) != 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: RX_UNDER error on i2c bus %d error status %08x\n",
> +      __FUNCTION__,
> +      Bus,
> +      ErrorStatus
> +      ));
> +    MmioRead32 (Base + DW_IC_CLR_RX_UNDER);
> +  }
> +
> +  if ((ErrorStatus & DW_IC_INTR_RX_OVER) != 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: RX_OVER error on i2c bus %d error status %08x\n",
> +      __FUNCTION__,
> +      Bus,
> +      ErrorStatus
> +      ));
> +    MmioRead32 (Base + DW_IC_CLR_RX_OVER);
> +  }
> +
> +  if ((ErrorStatus & DW_IC_INTR_TX_ABRT) != 0) {
> +    DEBUG ((DEBUG_VERBOSE, "%a: TX_ABORT at source %08x\n",
> +      __FUNCTION__,
> +      MmioRead32 (Base + DW_IC_TX_ABRT_SOURCE)
> +      ));
> +    MmioRead32 (Base + DW_IC_CLR_TX_ABRT);
> +  }
> +
> +  return ErrorStatus;
> +}
> +
> +/**
> + Waiting for bus to not be busy
> + **/
> +BOOLEAN
> +I2cWaitBusNotBusy (
> +  UINT32 Bus
> +  )
> +{
> +  UINTN Base;
> +  UINTN PollCount;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  PollCount = DW_MAX_MST_ACTIVITY_POLL_COUNT;
> +
> +  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_MST_ACTIVITY) != 0) {
> +    if (PollCount == 0) {
> +      DEBUG ((DEBUG_VERBOSE, "%a: Timeout while waiting for bus ready\n", __FUNCTION__));
> +      return FALSE;
> +    }
> +    PollCount--;
> +    /*
> +     * A delay isn't absolutely necessary.
> +     * But to ensure that we don't hammer the bus constantly,
> +     * delay for DW_POLL_MST_ACTIVITY_INTERVAL_US as with other implementation.
> +     */
> +    MicroSecondDelay (DW_POLL_MST_ACTIVITY_INTERVAL_US);
> +  }
> +
> +  return TRUE;
> +}
> +
> +/**
> + Waiting for TX FIFO buffer available
> + **/
> +EFI_STATUS
> +I2cWaitTxData (
> +  UINT32 Bus
> +  )
> +{
> +  UINTN Base;
> +  UINTN PollCount;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  PollCount = 0;
> +
> +  while (MmioRead32 (Base + DW_IC_TXFLR) == mI2cBusList[Bus].TxFifo) {
> +    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
> +      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX buffer available\n", __FUNCTION__));
> +      return EFI_TIMEOUT;
> +    }
> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + Waiting for RX FIFO buffer available
> + **/
> +EFI_STATUS
> +I2cWaitRxData (
> +  UINT32 Bus
> +  )
> +{
> +  UINTN Base;
> +  UINTN PollCount;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  PollCount = 0;
> +
> +  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_RFNE) == 0) {
> +    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
> +      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for RX buffer available\n", __FUNCTION__));
> +      return EFI_TIMEOUT;
> +    }
> +
> +    if ((I2cCheckErrors (Bus) & DW_IC_INTR_TX_ABRT) != 0) {
> +      return EFI_ABORTED;
> +    }
> +
> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + Initialize the Designware I2C SCL Counts
> +
> + This functions configures SCL clock Count for Standard Speed (SS) and Fast Speed (FS) mode.
> + **/
> +VOID
> +I2cSclInit (
> +  UINT32 Bus,
> +  UINT32 I2cClkFreq,
> +  UINT32 I2cSpeed
> +  )
> +{
> +  UINT16 IcCon;
> +  UINTN  Base;
> +  UINT32 I2cSpeedKhz;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  I2cSpeedKhz = I2cSpeed / 1000;
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d I2cClkFreq %d I2cSpeed %d\n",
> +    __FUNCTION__,
> +    Bus,
> +    I2cClkFreq,
> +    I2cSpeed
> +    ));
> +
> +  IcCon = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN;
> +
> +  if (I2cSpeedKhz <= 100) {
> +    IcCon |= DW_IC_CON_SPEED_STD;
> +    // Standard speed mode
> +    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeStandard][I2cSclSpkLen]);
> +    MmioWrite32 (Base + DW_IC_SS_SCL_HCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclHcnt]);
> +    MmioWrite32 (Base + DW_IC_SS_SCL_LCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclLcnt]);
> +  } else if (I2cSpeedKhz > 100 && I2cSpeedKhz <= 400) {
> +    IcCon |= DW_IC_CON_SPEED_FAST;
> +    // Fast speed mode
> +    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeFast][I2cSclSpkLen]);
> +    MmioWrite32 (Base + DW_IC_FS_SCL_HCNT, I2cSclParam[I2cSpeedModeFast][I2cSclHcnt]);
> +    MmioWrite32 (Base + DW_IC_FS_SCL_LCNT, I2cSclParam[I2cSpeedModeFast][I2cSclLcnt]);
> +  }
> +  MmioWrite32 (Base + DW_IC_CON, IcCon);
> +}
> +
> +/**
> + Initialize the designware i2c master hardware
> + **/
> +EFI_STATUS
> +I2cInit (
> +  UINT32 Bus,
> +  UINTN  BusSpeed
> +  )
> +{
> +  UINTN Base;
> +
> +  ASSERT (mI2cClock != 0);
> +
> +  mI2cBusList[Bus].BusSpeed = BusSpeed;
> +  I2cHWInit (Bus);
> +
> +  Base = mI2cBusList[Bus].Base;
> +
> +  /* Disable the adapter and interrupt */
> +  I2cEnable (Bus, 0);
> +  MmioWrite32 (Base + DW_IC_INTR_MASK, 0);
> +
> +  /* Set standard and fast speed divider for high/low periods */
> +  I2cSclInit (Bus, mI2cClock, BusSpeed);
> +  MmioWrite32 (Base + DW_IC_SDA_HOLD, 0x4b);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + Wait the transaction finished
> + **/
> +EFI_STATUS
> +I2cFinish (
> +  UINT32 Bus
> +  )
> +{
> +  UINTN Base;
> +  UINTN PollCount;
> +
> +  Base = mI2cBusList[Bus].Base;
> +  PollCount = 0;
> +
> +  /* Wait for TX FIFO empty */
> +  do {
> +    if ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_TFE) != 0) {
> +      break;
> +    }
> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> +  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
> +
> +  if (PollCount >= DW_MAX_TRANSFER_POLL_COUNT) {
> +    DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX FIFO empty\n", __FUNCTION__));
> +    return EFI_TIMEOUT;
> +  }
> +
> +  /* Wait for STOP signal detected on the bus */
> +  PollCount = 0;
> +  do {
> +    if ((MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_INTR_STOP_DET) != 0) {
> +      MmioRead32 (Base + DW_IC_CLR_STOP_DET);
> +      return EFI_SUCCESS;
> +    }
> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
> +  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
> +
> +  DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for transaction finished\n", __FUNCTION__));
> +  return EFI_TIMEOUT;
> +}
> +
> +EFI_STATUS
> +InternalI2cWrite (
> +  UINT32 Bus,
> +  UINT8  *Buf,
> +  UINT32 *Length
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN      WriteCount;
> +  UINTN      Base;
> +
> +  Status = EFI_SUCCESS;
> +  Base = mI2cBusList[Bus].Base;
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: Write Bus %d Buf %p Length %d\n",
> +    __FUNCTION__,
> +    Bus,
> +    Buf,
> +    *Length
> +    ));
> +  I2cEnable (Bus, 1);
> +
> +  WriteCount = 0;
> +  while ((*Length - WriteCount) != 0) {
> +    Status = I2cWaitTxData (Bus);
> +    if (EFI_ERROR (Status)) {
> +      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> +      I2cSync ();
> +      goto Exit;
> +    }
> +
> +    if (WriteCount == *Length - 1) {
> +      MmioWrite32 (
> +        Base + DW_IC_DATA_CMD,
> +        (Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK) | DW_IC_DATA_CMD_STOP
> +        );
> +    } else {
> +      MmioWrite32 (
> +        Base + DW_IC_DATA_CMD,
> +        Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK
> +        );
> +    }
> +    I2cSync ();
> +    WriteCount++;
> +  }
> +
> +Exit:
> +  *Length = WriteCount;
> +  I2cFinish (Bus);
> +  I2cWaitBusNotBusy (Bus);
> +  I2cEnable (Bus, 0);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +InternalI2cRead (
> +  UINT32  Bus,
> +  UINT8  *BufCmd,
> +  UINT32 CmdLength,
> +  UINT8  *Buf,
> +  UINT32 *Length
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINTN      Base;
> +  UINT32     CmdSend;
> +  UINT32     TxLimit, RxLimit;
> +  UINTN      Idx;
> +  UINTN      Count;
> +  UINTN      ReadCount;
> +  UINTN      WriteCount;
> +
> +  Status = EFI_SUCCESS;
> +  Base = mI2cBusList[Bus].Base;
> +  Count = 0;
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: Read Bus %d Buf %p Length:%d\n",
> +    __FUNCTION__,
> +    Bus,
> +    Buf,
> +    *Length
> +    ));
> +
> +  I2cEnable (Bus, 1);
> +
> +  /* Write command data */
> +  WriteCount = 0;
> +  while (CmdLength != 0) {
> +    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
> +    Count = CmdLength > TxLimit ? TxLimit : CmdLength;
> +
> +    for (Idx = 0; Idx < Count; Idx++ ) {
> +      CmdSend = BufCmd[WriteCount++] & DW_IC_DATA_CMD_DAT_MASK;
> +      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
> +      I2cSync ();
> +
> +      if (I2cCheckErrors (Bus) != 0) {
> +        Status = EFI_CRC_ERROR;
> +        goto Exit;
> +      }
> +      CmdLength--;
> +    }
> +
> +    Status = I2cWaitTxData (Bus);
> +    if (EFI_ERROR (Status)) {
> +      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> +      I2cSync ();
> +      goto Exit;
> +    }
> +  }
> +
> +  ReadCount = 0;
> +  WriteCount = 0;
> +  while ((*Length - ReadCount) != 0) {
> +    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
> +    RxLimit = mI2cBusList[Bus].RxFifo - MmioRead32 (Base + DW_IC_RXFLR);
> +    Count = *Length - ReadCount;
> +    Count = Count > RxLimit ? RxLimit : Count;
> +    Count = Count > TxLimit ? TxLimit : Count;
> +
> +    for (Idx = 0; Idx < Count; Idx++ ) {
> +      CmdSend = DW_IC_DATA_CMD_CMD;
> +      if (WriteCount == *Length - 1) {
> +        CmdSend |= DW_IC_DATA_CMD_STOP;
> +      }
> +      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
> +      I2cSync ();
> +      WriteCount++;
> +
> +      if (I2cCheckErrors (Bus) != 0) {
> +        DEBUG ((DEBUG_VERBOSE,
> +          "%a: Sending reading command remaining length %d CRC error\n",
> +          __FUNCTION__,
> +          *Length
> +          ));
> +        Status = EFI_CRC_ERROR;
> +        goto Exit;
> +      }
> +    }
> +
> +    for (Idx = 0; Idx < Count; Idx++ ) {
> +      Status = I2cWaitRxData (Bus);
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((DEBUG_VERBOSE,
> +          "%a: Reading remaining length %d failed to wait data\n",
> +          __FUNCTION__,
> +          *Length
> +          ));
> +
> +        if (Status != EFI_ABORTED) {
> +          MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
> +          I2cSync ();
> +        }
> +
> +        goto Exit;
> +      }
> +
> +      Buf[ReadCount++] = MmioRead32 (Base + DW_IC_DATA_CMD) & DW_IC_DATA_CMD_DAT_MASK;
> +      I2cSync ();
> +
> +      if (I2cCheckErrors (Bus) != 0) {
> +        DEBUG ((DEBUG_VERBOSE, "%a: Reading remaining length %d CRC error\n",
> +          __FUNCTION__,
> +          *Length
> +          ));
> +        Status = EFI_CRC_ERROR;
> +        goto Exit;
> +      }
> +    }
> +  }
> +
> +Exit:
> +  *Length = ReadCount;
> +  I2cFinish (Bus);
> +  I2cWaitBusNotBusy (Bus);
> +  I2cEnable (Bus, 0);
> +
> +  return Status;
> +}
> +
> +/**
> +  Write to I2C bus.
> +
> +  @param[in]     Bus          I2C bus Id.
> +  @param[in]     SlaveAddr    The address of slave device on the bus.
> +  @param[in,out] Buf          Buffer that holds data to write.
> +  @param[in,out] WriteLength  Pointer to length of buffer.
> +
> +  @return EFI_SUCCESS            Write successfully.
> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @return EFI_UNSUPPORTED        The bus is not supported.
> +  @return EFI_NOT_READY          The device/bus is not ready.
> +  @return EFI_TIMEOUT            Timeout why transferring data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cWrite (
> +  IN     UINT32 Bus,
> +  IN     UINT32 SlaveAddr,
> +  IN OUT UINT8  *Buf,
> +  IN OUT UINT32 *WriteLength
> +  )
> +{
> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> +      || Buf == NULL
> +      || WriteLength == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  I2cSetSlaveAddr (Bus, SlaveAddr);
> +
> +  return InternalI2cWrite (Bus, Buf, WriteLength);
> +}
> +
> +/**
> +  Read data from I2C bus.
> +
> +  @param[in]     Bus          I2C bus Id.
> +  @param[in]     SlaveAddr    The address of slave device on the bus.
> +  @param[in]     BufCmd       Buffer where to send the command.
> +  @param[in]     CmdLength    Pointer to length of BufCmd.
> +  @param[in,out] Buf          Buffer where to put the read data to.
> +  @param[in,out] ReadLength   Pointer to length of buffer.
> +
> +  @return EFI_SUCCESS            Read successfully.
> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
> +  @return EFI_UNSUPPORTED        The bus is not supported.
> +  @return EFI_NOT_READY          The device/bus is not ready.
> +  @return EFI_TIMEOUT            Timeout why transferring data.
> +  @return EFI_CRC_ERROR          There are errors on receiving data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cRead (
> +  IN     UINT32 Bus,
> +  IN     UINT32 SlaveAddr,
> +  IN     UINT8  *BufCmd,
> +  IN     UINT32 CmdLength,
> +  IN OUT UINT8  *Buf,
> +  IN OUT UINT32 *ReadLength
> +  )
> +{
> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> +      || Buf == NULL
> +      || ReadLength == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  I2cSetSlaveAddr (Bus, SlaveAddr);
> +
> +  return InternalI2cRead (Bus, BufCmd, CmdLength, Buf, ReadLength);
> +}
> +
> +/**
> + Setup new transaction with I2C slave device.
> +
> +  @param[in] Bus      I2C bus Id.
> +  @param[in] BusSpeed I2C bus speed in Hz.
> +
> +  @retval EFI_SUCCESS           Success.
> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cProbe (
> +  IN UINT32 Bus,
> +  IN UINTN  BusSpeed
> +  )
> +{
> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
> +      || BusSpeed > DW_I2C_MAXIMUM_SPEED_HZ)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return I2cInit (Bus, BusSpeed);
> +}
> +
> +/**
> + * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
> + *
> + * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
> + * It convers pointer to new virtual address.
> + *
> + * @param  Event        Event whose notification function is being invoked.
> + * @param  Context      Pointer to the notification function's context.
> + */
> +VOID
> +EFIAPI
> +I2cVirtualAddressChangeEvent (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  UINTN Count;
> +
> +  EfiConvertPointer (0x0, (VOID **)&mI2cBusList);
> +  EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray);
> +  EfiConvertPointer (0x0, (VOID **)&mI2cClock);
> +  for (Count = 0; Count < MAX_PLATFORM_I2C_BUS_NUM; Count++) {
> +    if (!mI2cRuntimeEnableArray[Count]) {
> +      continue;
> +    }
> +    EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray[Count]);
> +    EfiConvertPointer (0x0, (VOID **)&mI2cBusList[Count].Base);
> +  }
> +}
> +
> +/**
> + Setup a bus that to be used in runtime service.
> +
> +  @param[in] Bus I2C bus Id.
> +
> +  @retval EFI_SUCCESS  Success.
> +  @retval Otherwise    Error code.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +I2cSetupRuntime (
> +  IN UINT32 Bus
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
> +
> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (mVirtualAddressChangeEvent == NULL) {
> +    /*
> +     * Register for the virtual address change event
> +     */
> +    Status = gBS->CreateEventEx (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_NOTIFY,
> +                    I2cVirtualAddressChangeEvent,
> +                    NULL,
> +                    &gEfiEventVirtualAddressChangeGuid,
> +                    &mVirtualAddressChangeEvent
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  Status = gDS->GetMemorySpaceDescriptor (
> +                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
> +                  &Descriptor
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gDS->SetMemorySpaceAttributes (
> +                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
> +                  RUNTIME_ADDRESS_LENGTH,
> +                  Descriptor.Attributes | EFI_MEMORY_RUNTIME
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  mI2cRuntimeEnableArray[Bus] = TRUE;
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +I2cLibConstructor (
> +  VOID
> +  )
> +{
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  /* Get I2C Clock from the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return EFI_NOT_FOUND;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +  mI2cClock = PlatformHob->AhbClk;
> +  ASSERT (mI2cClock != 0);
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
@ 2021-06-04 23:22   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:22 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:58 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> The DwGpioLib library provides basic functions to control the GPIO
> controller on Ampere Altra processor.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec              |   3 +
>  Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf |  33 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h       |  76 +++++
>  Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c   | 314 ++++++++++++++++++++
>  4 files changed, 426 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 8be6a329bb26..be827dd19a96 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -31,6 +31,9 @@ [LibraryClasses]
>    ##  @libraryclass  Defines a set of methods to read/write to I2C devices.
>    I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>  
> +  ##  @libraryclass  Defines a set of methods to get/set GPIO.
> +  GpioLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
> +
>    ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>    MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
> new file mode 100644
> index 000000000000..36ce0c3be2c8
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +# Component description for DwGpioLib library for the Designware GPIO controller.
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = DwGpioLib
> +  FILE_GUID                      = E7D9CAE1-6930-46E3-BDF9-0027446E7DF2
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = GpioLib
> +
> +[Sources.common]
> +  DwGpioLib.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  IoLib
> +
> +[Guids]
> +  gEfiEventVirtualAddressChangeGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
> new file mode 100755
> index 000000000000..cb201bc98322
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/GpioLib.h
> @@ -0,0 +1,76 @@
> +/** @file
> +  Library implementation for the Designware GPIO controller.
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef GPIO_LIB_H_
> +#define GPIO_LIB_H_
> +
> +enum SocGpioConfigMode {
> +  GPIO_CONFIG_OUT_LOW = 0,
> +  GPIO_CONFIG_OUT_HI,
> +  GPIO_CONFIG_OUT_LOW_TO_HIGH,
> +  GPIO_CONFIG_OUT_HIGH_TO_LOW,
> +  GPIO_CONFIG_IN,
> +  MAX_GPIO_CONFIG_MODE
> +};
> +
> +/*
> + *  GpioWriteBit: Use to Set/Clear GPIOs
> + *  Input:
> + *              Pin : Pin Identification
> + *              Val : 1 to Set, 0 to Clear
> + */
> +VOID
> +EFIAPI
> +GpioWriteBit (
> +  IN UINT32 Pin,
> +  IN UINT32 Val
> +  );
> +
> +/*
> + *   GpioReadBit:
> + *   Input:
> + *              Pin : Pin Identification
> + *   Return:
> + *              1 : On/High
> + *              0 : Off/Low
> + */
> +UINTN
> +EFIAPI
> +GpioReadBit (
> +  IN UINT32 Pin
> +  );
> +
> +/*
> + *  GpioModeConfig: Use to configure GPIOs as Input/Output
> + *  Input:
> + *              Pin : Pin Identification
> + *              InOut : GPIO_OUT/1 as Output
> + *                      GPIO_IN/0  as Input
> + */
> +EFI_STATUS
> +EFIAPI
> +GpioModeConfig (
> +  UINT8 Pin,
> +  UINTN Mode
> +  );
> +
> +/*
> + *  Setup a controller that to be used in runtime service.
> + *  Input:
> + *              Pin: Pin belongs to the controller.
> + *  return:     0 for success.
> + *              Otherwise, error code.
> + */
> +EFI_STATUS
> +EFIAPI
> +GpioSetupRuntime (
> +  IN UINT32 Pin
> +  );
> +
> +#endif /* GPIO_LIB_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
> new file mode 100644
> index 000000000000..dbb53f7d57d2
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.c
> @@ -0,0 +1,314 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <Uefi.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Platform/Ac01.h>
> +
> +/* Runtime needs to be 64K alignment */
> +#define RUNTIME_ADDRESS_MASK           (~(SIZE_64KB - 1))
> +#define RUNTIME_ADDRESS_LENGTH         SIZE_64KB
> +
> +#define GPIO_MUX_VAL(Gpio)              (0x00000001 << (Gpio))
> +#define GPIO_IN                         0
> +#define GPIO_OUT                        1
> +
> +/* Address GPIO_REG Registers */
> +#define GPIO_SWPORTA_DR_ADDR            0x00000000
> +#define GPIO_SWPORTA_DDR_ADDR           0x00000004
> +#define GPIO_EXT_PORTA_ADDR             0x00000050
> +
> +STATIC UINT64    GpioBaseAddr[] = { GPIO_DWAPB_BASE_ADDR };
> +STATIC UINT64    GpiBaseAddr[] = { GPI_DWAPB_BASE_ADDR };
> +STATIC BOOLEAN   GpioRuntimeEnableArray[sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0])] = { FALSE };
> +STATIC EFI_EVENT mVirtualAddressChangeEvent = NULL;
> +
> +UINT64
> +GetBaseAddr (
> +  IN UINT32 Pin
> +  )
> +{
> +  UINT32 NumberOfControllers = sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0]);
> +  UINT32 TotalPins = GPIO_DWAPB_PINS_PER_CONTROLLER * NumberOfControllers;
> +
> +  if (NumberOfControllers == 0 || Pin >= TotalPins) {
> +    return 0;
> +  }
> +
> +  return GpioBaseAddr[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER];
> +}
> +
> +VOID
> +GpioWrite (
> +  IN UINT64 Base,
> +  IN UINT32 Val
> +  )
> +{
> +  MmioWrite32 ((UINTN)Base, Val);
> +}
> +
> +VOID
> +GpioRead (
> +  IN  UINT64 Base,
> +  OUT UINT32 *Val
> +  )
> +{
> +  ASSERT (Val != NULL);
> +  *Val = MmioRead32 (Base);
> +}
> +
> +VOID
> +EFIAPI
> +GpioWriteBit (
> +  IN UINT32 Pin,
> +  IN UINT32 Val
> +  )
> +{
> +  UINT64 Reg;
> +  UINT32 GpioPin;
> +  UINT32 ReadVal;
> +
> +  Reg = GetBaseAddr (Pin);
> +  if (Reg == 0) {
> +    return;
> +  }
> +
> +  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
> +
> +  Reg += GPIO_SWPORTA_DR_ADDR;
> +  GpioRead (Reg, &ReadVal);
> +
> +  if (Val != 0) {
> +    GpioWrite (Reg, ReadVal | GPIO_MUX_VAL (GpioPin));
> +  } else {
> +    GpioWrite (Reg, ReadVal & ~GPIO_MUX_VAL (GpioPin));
> +  }
> +}
> +
> +UINTN
> +EFIAPI
> +GpioReadBit (
> +  IN UINT32 Pin
> +  )
> +{
> +  UINT64 Reg;
> +  UINT32 Val;
> +  UINT32 GpioPin;
> +  UINT8  Index;
> +  UINT32 MaxIndex;
> +
> +  Reg = GetBaseAddr (Pin);
> +  if (Reg == 0) {
> +    return 0;
> +  }
> +
> +  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
> +
> +  /* Check if a base address is GPI */
> +  MaxIndex = sizeof (GpiBaseAddr) / sizeof (GpiBaseAddr[0]);
> +  for (Index = 0; Index < MaxIndex; Index++) {
> +    if (Reg == GpiBaseAddr[Index]) {
> +      break;
> +    }
> +  }
> +  if (Index == MaxIndex) {
> +    /* Only GPIO has GPIO_EXT_PORTA register, not for GPI */
> +    Reg +=  GPIO_EXT_PORTA_ADDR;
> +  }
> +
> +  GpioRead (Reg, &Val);
> +
> +  return Val & GPIO_MUX_VAL (GpioPin) ? 1 : 0;
> +}
> +
> +EFI_STATUS
> +GpioConfig (
> +  IN UINT32 Pin,
> +  IN UINT32 InOut
> +  )
> +{
> +  INTN   GpioPin;
> +  UINT32 Val;
> +  UINT64 Reg;
> +
> +  /*
> +   * Caculate GPIO Pin Number for Direction Register
> +   * GPIO_SWPORTA_DDR for GPIO[31...0]
> +   * GPIO_SWPORTB_DDR for GPIO[51...32]
> +   */
> +
> +  Reg = GetBaseAddr (Pin);
> +  if (Reg == 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Reg += GPIO_SWPORTA_DDR_ADDR;
> +  GpioPin = Pin % GPIO_DWAPB_PINS_PER_CONTROLLER;
> +  GpioRead (Reg, &Val);
> +
> +  if (InOut == GPIO_OUT) {
> +    Val |= GPIO_MUX_VAL (GpioPin);
> +  } else {
> +    Val &= ~GPIO_MUX_VAL (GpioPin);
> +  }
> +  GpioWrite (Reg, Val);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +GpioModeConfig (
> +  UINT8 Pin,
> +  UINTN Mode
> +  )
> +{
> +  UINT32 NumberOfControllers = sizeof (GpioBaseAddr) / sizeof (UINT64);
> +  UINT32 NumersOfPins = NumberOfControllers * GPIO_DWAPB_PINS_PER_CONTROLLER;
> +  UINT32 Delay = 10;
> +
> +  if (Mode < GPIO_CONFIG_OUT_LOW
> +      || Mode >= MAX_GPIO_CONFIG_MODE
> +      || Pin > NumersOfPins - 1
> +      || Pin < 0)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (Mode) {
> +  case GPIO_CONFIG_OUT_LOW:
> +    GpioConfig (Pin, GPIO_OUT);
> +    GpioWriteBit (Pin, 0);
> +    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low\n", Pin));
> +    break;
> +
> +  case GPIO_CONFIG_OUT_HI:
> +    GpioConfig (Pin, GPIO_OUT);
> +    GpioWriteBit (Pin, 1);
> +    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high\n", Pin));
> +    break;
> +
> +  case GPIO_CONFIG_OUT_LOW_TO_HIGH:
> +    GpioConfig (Pin, GPIO_OUT);
> +    GpioWriteBit (Pin, 0);
> +    MicroSecondDelay (1000 * Delay);
> +    GpioWriteBit (Pin, 1);
> +    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output low->high\n", Pin));
> +    break;
> +
> +  case GPIO_CONFIG_OUT_HIGH_TO_LOW:
> +    GpioConfig (Pin, GPIO_OUT);
> +    GpioWriteBit (Pin, 1);
> +    MicroSecondDelay (1000 * Delay);
> +    GpioWriteBit (Pin, 0);
> +    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as output high->low\n", Pin));
> +    break;
> +
> +  case GPIO_CONFIG_IN:
> +    GpioConfig (Pin, GPIO_IN);
> +    DEBUG ((DEBUG_INFO, "GPIO pin %d configured as input\n", Pin));
> +    break;
> +
> +  default:
> +    break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
> + *
> + * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
> + * It convers pointer to new virtual address.
> + *
> + * @param  Event        Event whose notification function is being invoked.
> + * @param  Context      Pointer to the notification function's context.
> + */
> +VOID
> +EFIAPI
> +GpioVirtualAddressChangeEvent (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  UINTN Count;
> +
> +  EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr);
> +  for (Count = 0; Count < sizeof (GpioBaseAddr) / sizeof (GpioBaseAddr[0]); Count++) {
> +    if (!GpioRuntimeEnableArray[Count]) {
> +      continue;
> +    }
> +    EfiConvertPointer (0x0, (VOID **)&GpioBaseAddr[Count]);
> +  }
> +}
> +
> +/**
> + Setup a controller that to be used in runtime service.
> +
> + @Bus:      Bus ID.
> + @return:   0 for success.
> +            Otherwise, error code.
> + **/
> +EFI_STATUS
> +EFIAPI
> +GpioSetupRuntime (
> +  IN UINT32 Pin
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
> +
> +  if (GetBaseAddr (Pin) == 0) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (mVirtualAddressChangeEvent == NULL) {
> +    /*
> +    * Register for the virtual address change event
> +    */
> +    Status = gBS->CreateEventEx (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_NOTIFY,
> +                    GpioVirtualAddressChangeEvent,
> +                    NULL,
> +                    &gEfiEventVirtualAddressChangeGuid,
> +                    &mVirtualAddressChangeEvent
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  Status = gDS->GetMemorySpaceDescriptor (
> +                  GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK,
> +                  &Descriptor
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = gDS->SetMemorySpaceAttributes (
> +                  GetBaseAddr (Pin) & RUNTIME_ADDRESS_MASK,
> +                  RUNTIME_ADDRESS_LENGTH,
> +                  Descriptor.Attributes | EFI_MEMORY_RUNTIME
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  GpioRuntimeEnableArray[Pin / GPIO_DWAPB_PINS_PER_CONTROLLER] = TRUE;
> +
> +  return Status;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063
  2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
@ 2021-06-04 23:26   ` Leif Lindholm
  2021-06-15 16:48     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:26 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:06:59 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This library adds the support for retrieving and updating system
> datetime over real RTC PCF85063 device on Mt. Jade platform instead of
> using virtual RTC.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                  |   2 +
>  Platform/Ampere/JadePkg/Jade.dsc                                                      |   2 +-
>  Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf |  44 +++
>  Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h                   |  91 ++++++
>  Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c                   | 317 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c   | 257 ++++++++++++++++
>  6 files changed, 712 insertions(+), 1 deletion(-)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 6a6f72e995af..9f19f495fad2 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -84,6 +84,8 @@ [LibraryClasses.common]
>    SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
>    AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>    TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> +  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
>    MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
>  
>    #
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index f92855af99ab..f37ab1a92e44 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -73,7 +73,7 @@ [LibraryClasses]
>    #
>    # RTC Library: Common RTC
>    #
> -  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
> +  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>  
>    #
>    # Library for FailSafe support
> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
> new file mode 100644
> index 000000000000..1fe561cc0ec9
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
> @@ -0,0 +1,44 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                      = 0x0001001B
> +  MODULE_TYPE                      = BASE
> +  BASE_NAME                        = PCF85063RealTimeClockLib
> +  FILE_GUID                        = 271569F6-5522-4006-9FF5-F07A59473AAC
> +  LIBRARY_CLASS                    = RealTimeClockLib
> +  VERSION_STRING                   = 1.0
> +
> +[Sources.common]
> +  PCF85063.c
> +  PCF85063.h
> +  PCF85063RealTimeClockLib.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmGenericTimerCounterLib
> +  ArmLib
> +  BaseLib
> +  DebugLib
> +  GpioLib
> +  DxeServicesTableLib
> +  I2cLib
> +  TimeBaseLib
> +  TimerLib
> +  UefiLib
> +  UefiRuntimeLib
> +
> +[Guids]
> +  gEfiEventVirtualAddressChangeGuid
> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
> new file mode 100644
> index 000000000000..03ce4d29a03f
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
> @@ -0,0 +1,91 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCF85063_H_
> +#define PCF85063_H_
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/RealTimeClockLib.h>
> +
> +//
> +// I2C bus address that RTC connected to
> +//
> +#define I2C_RTC_BUS_ADDRESS        1
> +
> +//
> +// I2C RTC bus speed
> +//
> +#define I2C_RTC_BUS_SPEED          100000
> +
> +//
> +// I2C chip address that RTC connected to
> +//
> +#define I2C_RTC_CHIP_ADDRESS       0x51
> +
> +//
> +// The GPI PIN that tell if RTC can be access
> +//
> +#define I2C_RTC_ACCESS_GPIO_PIN    28
> +
> +/**
> + * Returns the current time and date information of the hardware platform.
> + *
> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER Time is NULL.
> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
> + */
> +EFI_STATUS
> +EFIAPI
> +PlatformGetTime (
> +  OUT EFI_TIME *Time
> +  );
> +
> +/**
> + * Set the time and date information to the hardware platform.
> + *
> + * @param  Time                  A pointer to storage to set the current time to hardware platform.
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER Time is NULL.
> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
> + **/
> +EFI_STATUS
> +EFIAPI
> +PlatformSetTime (
> +  IN EFI_TIME *Time
> +  );
> +
> +/**
> + * Callback function for hardware platform to convert data pointers to virtual address
> + */
> +VOID
> +EFIAPI
> +PlatformVirtualAddressChangeEvent (
> +  VOID
> +  );
> +
> +/**
> + * Callback function for hardware platform to initialize private data
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval Others                The error status indicates the error
> + */
> +EFI_STATUS
> +EFIAPI
> +PlatformInitialize (
> +  VOID
> +  );
> +
> +#endif /* PCF85063_H_ */
> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
> new file mode 100644
> index 000000000000..f9fa125d9d7e
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
> @@ -0,0 +1,317 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/I2cLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +
> +#include "PCF85063.h"
> +
> +#define RTC_TIMEOUT_WAIT_ACCESS        100000 /* 100 miliseconds */
> +#define RTC_DEFAULT_MIN_YEAR           2000
> +#define RTC_DEFAULT_MAX_YEAR           2099
> +
> +#define RTC_ADDR                       0x4
> +#define RTC_DATA_BUF_LEN               8
> +
> +/**
> + * PCF85063 register offsets
> + */
> +#define PCF85063_OFFSET_SEC            0x0
> +#define PCF85063_OFFSET_MIN            0x1
> +#define PCF85063_OFFSET_HR             0x2
> +#define PCF85063_OFFSET_DAY            0x3
> +#define PCF85063_OFFSET_WKD            0x4
> +#define PCF85063_OFFSET_MON            0x5
> +#define PCF85063_OFFSET_YEA            0x6
> +
> +/**
> + * PCF85063 encoding macros
> + */
> +#define PCF85063_SEC_ENC(s) (((((s) / 10) & 0x7) << 4) | (((s) % 10) & 0xf))
> +#define PCF85063_MIN_ENC(m) (((((m) / 10) & 0x7) << 4) | (((m) % 10) & 0xf))
> +#define PCF85063_HR_ENC(h)  (((((h) / 10) & 0x3) << 4) | (((h) % 10) & 0xf))
> +#define PCF85063_DAY_ENC(d) (((((d) / 10) & 0x3) << 4) | (((d) % 10) & 0xf))
> +#define PCF85063_WKD_ENC(w) ((w) & 0x7)
> +#define PCF85063_MON_ENC(m) (((((m) / 10) & 0x1) << 4) | (((m) % 10) & 0xf))
> +#define PCF85063_YEA_ENC(y) (((((y) / 10) & 0xf) << 4) | (((y) % 10) & 0xf))
> +
> +/**
> + * PCF85063 decoding macros
> + */
> +#define PCF85063_SEC_DEC(s) (((((s) & 0x70) >> 4) * 10) + ((s) & 0xf))
> +#define PCF85063_MIN_DEC(m) (((((m) & 0x70) >> 4) * 10) + ((m) & 0xf))
> +#define PCF85063_HR_DEC(h)  (((((h) & 0x30) >> 4) * 10) + ((h) & 0xf))
> +#define PCF85063_DAY_DEC(d) (((((d) & 0x30) >> 4)* 10) + ((d) & 0xf))

*twitch*
Please add that space before '*' like on all other lines.

With that:
Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> +#define PCF85063_WKD_DEC(w) ((w) & 0x7)
> +#define PCF85063_MON_DEC(m) (((((m) & 0x10) >> 4) * 10) + ((m) & 0xf))
> +#define PCF85063_YEA_DEC(y) (((((y) & 0xf0) >> 4) * 10) + ((y) & 0xf))
> +
> +/* Buffer pointers to convert Vir2Phys and Phy2Vir */
> +STATIC volatile UINT64 RtcBufVir;
> +STATIC volatile UINT64 RtcBufPhy;
> +
> +STATIC
> +EFI_STATUS
> +RtcI2cWaitAccess (
> +  VOID
> +  )
> +{
> +  INTN Timeout;
> +
> +  Timeout = RTC_TIMEOUT_WAIT_ACCESS;
> +  while ((GpioReadBit (I2C_RTC_ACCESS_GPIO_PIN) != 0) && (Timeout > 0)) {
> +    MicroSecondDelay (100);
> +    Timeout -= 100;
> +  }
> +
> +  if (Timeout <= 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: Timeout while waiting access RTC\n", __FUNCTION__));
> +    return EFI_TIMEOUT;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +RtcI2cRead (
> +  IN     UINT8  Addr,
> +  IN OUT UINT64 Data,
> +  IN     UINT32 DataLen
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     TmpLen;
> +
> +  if (EFI_ERROR (RtcI2cWaitAccess ())) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Send the slave address for read
> +  //
> +  TmpLen = 1;
> +  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, (UINT8 *)&Addr, &TmpLen);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // Read back the time
> +  //
> +  Status = I2cRead (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, NULL, 0, (UINT8 *)Data, &DataLen);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +RtcI2cWrite (
> +  IN UINT8  Addr,
> +  IN UINT64 Data,
> +  IN UINT32 DataLen
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8      TmpBuf[RTC_DATA_BUF_LEN + 1];
> +  UINT32     TmpLen;
> +
> +  if (EFI_ERROR (RtcI2cWaitAccess ())) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (DataLen > sizeof (TmpBuf) - 1) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  //
> +  // The first byte is the address
> +  //
> +  TmpBuf[0] = Addr;
> +  TmpLen = DataLen + 1;
> +  CopyMem ((VOID *)(TmpBuf + 1), (VOID *)Data, DataLen);
> +
> +  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, TmpBuf, &TmpLen);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + * Returns the current time and date information of the hardware platform.
> + *
> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER Time is NULL.
> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
> + */
> +EFI_STATUS
> +EFIAPI
> +PlatformGetTime (
> +  OUT EFI_TIME *Time
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8      *Data;
> +
> +  if (Time == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = RtcI2cRead (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
> +
> +  Data = (UINT8 *)RtcBufVir;
> +  if (Status == EFI_SUCCESS) {
> +    Time->Second = PCF85063_SEC_DEC (Data[PCF85063_OFFSET_SEC]);
> +    Time->Minute = PCF85063_MIN_DEC (Data[PCF85063_OFFSET_MIN]);
> +    Time->Hour   = PCF85063_HR_DEC (Data[PCF85063_OFFSET_HR]);
> +    Time->Day    = PCF85063_DAY_DEC (Data[PCF85063_OFFSET_DAY]);
> +    Time->Month  = PCF85063_MON_DEC (Data[PCF85063_OFFSET_MON]);
> +    Time->Year   = PCF85063_YEA_DEC (Data[PCF85063_OFFSET_YEA]);
> +    Time->Year  += RTC_DEFAULT_MIN_YEAR;
> +    if (Time->Year > RTC_DEFAULT_MAX_YEAR) {
> +      Time->Year = RTC_DEFAULT_MAX_YEAR;
> +    }
> +    if (Time->Year < RTC_DEFAULT_MIN_YEAR) {
> +      Time->Year = RTC_DEFAULT_MIN_YEAR;
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> + * Set the time and date information to the hardware platform.
> + *
> + * @param  Time                  A pointer to storage to set the current time to hardware platform.
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER Time is NULL.
> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
> + **/
> +EFI_STATUS
> +EFIAPI
> +PlatformSetTime (
> +  IN EFI_TIME *Time
> +  )
> +{
> +  UINT8 *Data;
> +
> +  if (Time == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Time->Year < RTC_DEFAULT_MIN_YEAR ||
> +      Time->Year > RTC_DEFAULT_MAX_YEAR)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Data = (UINT8 *)RtcBufVir;
> +  Data[PCF85063_OFFSET_SEC] = PCF85063_SEC_ENC (Time->Second);
> +  Data[PCF85063_OFFSET_MIN] = PCF85063_MIN_ENC (Time->Minute);
> +  Data[PCF85063_OFFSET_HR]  = PCF85063_HR_ENC (Time->Hour);
> +  Data[PCF85063_OFFSET_DAY] = PCF85063_DAY_ENC (Time->Day);
> +  Data[PCF85063_OFFSET_MON] = PCF85063_MON_ENC (Time->Month);
> +  Data[PCF85063_OFFSET_YEA] = PCF85063_YEA_ENC (Time->Year - RTC_DEFAULT_MIN_YEAR);
> +
> +  return RtcI2cWrite (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
> +}
> +
> +/**
> + * Callback function for hardware platform to convert data pointers to virtual address
> + */
> +VOID
> +EFIAPI
> +PlatformVirtualAddressChangeEvent (
> +  VOID
> +  )
> +{
> +  EfiConvertPointer (0x0, (VOID **)&RtcBufVir);
> +}
> +
> +/**
> + * Callback function for hardware platform to initialize private data
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval Others                The error status indicates the error
> + */
> +EFI_STATUS
> +EFIAPI
> +PlatformInitialize (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  /*
> +   * Allocate the buffer for RTC data
> +   * The buffer can be accessible after ExitBootServices
> +   */
> +  RtcBufVir = (UINT64)AllocateRuntimeZeroPool (RTC_DATA_BUF_LEN);
> +  ASSERT_EFI_ERROR (RtcBufVir);
> +  RtcBufPhy = (UINT64)RtcBufVir;
> +
> +  Status = I2cSetupRuntime (I2C_RTC_BUS_ADDRESS);
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a:%d I2cSetupRuntime() failed - %r \n",
> +      __FUNCTION__,
> +      __LINE__,
> +      Status
> +      ));
> +    return Status;
> +  }
> +
> +  Status = GpioSetupRuntime (I2C_RTC_ACCESS_GPIO_PIN);
> +  ASSERT_EFI_ERROR (Status);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a:%d GpioSetupRuntime() failed - %r \n",
> +      __FUNCTION__,
> +      __LINE__,
> +      Status
> +      ));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
> new file mode 100755
> index 000000000000..ef8c71e92c18
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
> @@ -0,0 +1,257 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiDxe.h>
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +#include <Library/ArmGenericTimerCounterLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/RealTimeClockLib.h>
> +#include <Library/TimeBaseLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/RealTimeClock.h>
> +
> +#include "PCF85063.h"
> +
> +#define TICKS_PER_SEC     (ArmGenericTimerGetTimerFreq ())
> +
> +STATIC EFI_EVENT          mVirtualAddressChangeEvent = NULL;
> +
> +STATIC UINT64             mLastSavedSystemCount = 0;
> +STATIC UINT64             mLastSavedTimeEpoch = 0;
> +
> +/**
> + * Returns the current time and date information, and the time-keeping capabilities
> + * of the hardware platform.
> + *
> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
> + * @param  Capabilities          An optional pointer to a buffer to receive the real time clock
> + *                               device's capabilities.
> + *
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER Time is NULL.
> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
> + */
> +EFI_STATUS
> +EFIAPI
> +LibGetTime (
> +  OUT EFI_TIME                *Time,
> +  OUT EFI_TIME_CAPABILITIES   *Capabilities
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINT64        CurrentSystemCount;
> +  UINT64        TimeElapsed;
> +  UINTN         EpochSeconds;
> +
> +  if ((mLastSavedTimeEpoch == 0) || EfiAtRuntime ()) {
> +    Status = PlatformGetTime (Time);
> +    if (EFI_ERROR (Status)) {
> +      // Failed to read platform RTC so create fake time
> +      Time->Second = 0;
> +      Time->Minute = 0;
> +      Time->Hour = 10;
> +      Time->Day = 1;
> +      Time->Month = 1;
> +      Time->Year = 2017;
> +    }
> +
> +    EpochSeconds = EfiTimeToEpoch (Time);
> +    if (!EfiAtRuntime ()) {
> +      mLastSavedTimeEpoch = EpochSeconds;
> +      mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
> +    }
> +  } else {
> +    CurrentSystemCount = ArmGenericTimerGetSystemCount ();
> +    if (CurrentSystemCount >= mLastSavedSystemCount) {
> +      TimeElapsed = (CurrentSystemCount - mLastSavedSystemCount) / MultU64x32 (1, TICKS_PER_SEC);
> +      EpochSeconds = mLastSavedTimeEpoch + TimeElapsed;
> +    } else {
> +      // System counter overflow 64 bits
> +      // Call GetTime again to read the date from RTC HW, not using generic timer system counter
> +      mLastSavedTimeEpoch = 0;
> +      return LibGetTime (Time, Capabilities);
> +    }
> +  }
> +
> +  // Adjust for the correct timezone
> +  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
> +    EpochSeconds += Time->TimeZone * SEC_PER_MIN;
> +  }
> +
> +  // Adjust for the correct period
> +  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
> +    // Convert to adjusted time, i.e. spring forwards one hour
> +    EpochSeconds += SEC_PER_HOUR;
> +  }
> +
> +  EpochToEfiTime (EpochSeconds, Time);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + * Sets the current local time and date information.
> + *
> + * @param  Time                  A pointer to the current time.
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + * @retval EFI_INVALID_PARAMETER A time field is out of range.
> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
> + */
> +EFI_STATUS
> +EFIAPI
> +LibSetTime (
> +  IN EFI_TIME                *Time
> +  )
> +{
> +  EFI_STATUS    Status;
> +  UINTN         EpochSeconds;
> +
> +  EpochSeconds = EfiTimeToEpoch (Time);
> +
> +  // Adjust for the correct time zone, i.e. convert to UTC time zone
> +  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
> +    EpochSeconds -= Time->TimeZone * SEC_PER_MIN;
> +  }
> +
> +  // Adjust for the correct period, i.e. fall back one hour
> +  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
> +    EpochSeconds -= SEC_PER_HOUR;
> +  }
> +
> +  EpochToEfiTime (EpochSeconds, Time);
> +
> +  Status = PlatformSetTime (Time);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if (!EfiAtRuntime ()) {
> +    mLastSavedTimeEpoch = EpochSeconds;
> +    mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> + * Returns the current wakeup alarm clock setting.
> + *
> + * @param  Enabled               Indicates if the alarm is currently enabled or disabled.
> + * @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
> + * @param  Time                  The current alarm setting.
> + *
> + * @retval EFI_SUCCESS           The alarm settings were returned.
> + * @retval EFI_INVALID_PARAMETER Any parameter is NULL.
> + * @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
> + */
> +EFI_STATUS
> +EFIAPI
> +LibGetWakeupTime (
> +  OUT BOOLEAN     *Enabled,
> +  OUT BOOLEAN     *Pending,
> +  OUT EFI_TIME    *Time
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + * Sets the system wakeup alarm clock time.
> + *
> + * @param  Enabled               Enable or disable the wakeup alarm.
> + * @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
> + *
> + * @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
> + *                               Enable is FALSE, then the wakeup alarm was disabled.
> + * @retval EFI_INVALID_PARAMETER A time field is out of range.
> + * @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
> + * @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
> + */
> +EFI_STATUS
> +EFIAPI
> +LibSetWakeupTime (
> +  IN BOOLEAN      Enabled,
> +  OUT EFI_TIME    *Time
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +/**
> +  Fixup internal data so that EFI can be call in virtual mode.
> +  Call the passed in Child Notify event and convert any pointers in
> +  lib to virtual mode.
> +
> +  @param[in]    Event   The Event that is being processed
> +  @param[in]    Context Event Context
> +**/
> +VOID
> +EFIAPI
> +LibRtcVirtualNotifyEvent (
> +  IN EFI_EVENT        Event,
> +  IN VOID             *Context
> +  )
> +{
> +  //
> +  // Only needed if you are going to support the OS calling RTC functions in virtual mode.
> +  // You will need to call EfiConvertPointer (). To convert any stored physical addresses
> +  // to virtual address. After the OS transitions to calling in virtual mode, all future
> +  // runtime calls will be made in virtual mode.
> +  //
> +  PlatformVirtualAddressChangeEvent ();
> +}
> +
> +/**
> + * This is the declaration of an EFI image entry point. This can be the entry point to an application
> + * written to this specification, an EFI boot service driver, or an EFI runtime driver.
> + *
> + * @param  ImageHandle           Handle that identifies the loaded image.
> + * @param  SystemTable           System Table for this image.
> + *
> + * @retval EFI_SUCCESS           The operation completed successfully.
> + */
> +EFI_STATUS
> +EFIAPI
> +LibRtcInitialize (
> +  IN EFI_HANDLE                            ImageHandle,
> +  IN EFI_SYSTEM_TABLE                      *SystemTable
> +  )
> +{
> +  EFI_STATUS    Status;
> +
> +  Status = PlatformInitialize ();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Register for the virtual address change event
> +  //
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  LibRtcVirtualNotifyEvent,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &mVirtualAddressChangeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
@ 2021-06-04 23:27   ` Leif Lindholm
  2021-06-15 16:48     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:27 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone


On Wed, May 26, 2021 at 17:07:00 +0700, Nhi Pham wrote:
> From: Quan Nguyen <quan@os.amperecomputing.com>
> 
> BootProgress will send 32-bit UEFI Status Code via doorbell to report
> its progress status.
> Currently support reporting Progress Status Code and Error Status Code
> only. Other types of Status Code are ignored.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>

This looks like something that would be a good target to commonalise
between platforms in the future. But for now:
Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                     |   2 +
>  Platform/Ampere/JadePkg/Jade.fdf                                                         |   2 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf   |  51 +++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf |  49 +++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c     | 211 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c   | 210 +++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni   |  16 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni |  18 ++
>  8 files changed, 559 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 9f19f495fad2..9f75da6f05ad 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -529,6 +529,7 @@ [Components.common]
>    }
>    MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
>    MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>  
>    #
>    # DXE Phase modules
> @@ -539,6 +540,7 @@ [Components.common]
>    }
>    MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>    MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>  
>    #
>    # PCD
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 80a86d7c1156..1857296a8ea5 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -102,6 +102,7 @@ [FV.FVMAIN_COMPACT]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>    INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>    INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>    INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> @@ -149,6 +150,7 @@ [FV.FvMain]
>    INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>    INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>    INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>  
>    #
>    # PI DXE Drivers producing Architectural Protocols (EFI Services)
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
> new file mode 100644
> index 000000000000..2211a213a6df
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
> @@ -0,0 +1,51 @@
> +## @file
> +#  This module installs Boot Progress Dxe.
> +#
> +#  This module registers report status code listener to report boot progress
> +#  to SMpro.
> +#
> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = BootProgressDxe
> +  MODULE_UNI_FILE                = BootProgressDxe.uni
> +  FILE_GUID                      = 6E12F248-F0C1-11EA-B37C-9798918A2163
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = BootProgressDxeEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = AARCH64
> +#
> +
> +[Sources]
> +  BootProgressDxe.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  BaseLib
> +  DebugLib
> +  DxeServicesLib
> +  SystemFirmwareInterfaceLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEfiRscHandlerProtocolGuid                    ## CONSUMES
> +
> +[Depex]
> +  gEfiRscHandlerProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
> new file mode 100644
> index 000000000000..1dd0ec31ac37
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
> @@ -0,0 +1,49 @@
> +## @file
> +#  Boot Progress Pei Module.
> +#
> +#  Updates to SCP with Boot Progress information during boot.
> +#
> +#  This module register report status code listener to collect boot progress
> +#  information and keep SCP posted.
> +#
> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = BootProgressPeim
> +  MODULE_UNI_FILE                = BootProgressPeim.uni
> +  FILE_GUID                      = 2E8A3B3E-F26C-11EA-BDE5-6726AD8F88BD
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = BootProgressPeiEntryPoint
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = AARCH64
> +#
> +
> +[Sources]
> +  BootProgressPeim.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  PeiServicesLib
> +  PeimEntryPoint
> +  SystemFirmwareInterfaceLib
> +
> +[Ppis]
> +  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
> +
> +[Depex]
> +  gEfiPeiRscHandlerPpiGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
> new file mode 100644
> index 000000000000..f87a4d53179f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
> @@ -0,0 +1,211 @@
> +/** @file
> +
> +  This module installs Boot Progress Dxe that report boot progress to SMpro.
> +
> +  This module registers report status code listener to report boot progress
> +  to SMpro.
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiDxe.h>
> +
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DxeServicesLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Pi/PiStatusCode.h>
> +#include <Protocol/ReportStatusCodeHandler.h>
> +
> +typedef struct {
> +  UINT8                 Byte;
> +  EFI_STATUS_CODE_VALUE Value;
> +} STATUS_CODE_TO_CHECKPOINT;
> +
> +enum BOOT_PROGRESS_STATE {
> +  BOOT_NOTSTART = 0,
> +  BOOT_START    = 1,
> +  BOOT_COMPLETE = 2,
> +  BOOT_FAILED   = 3,
> +};
> +
> +UINT32 DxeProgressCode[] = {
> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),                     // DXE Core is started
> +  (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_HB_INIT),                    // PCI host bridge initialization
> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT),                 // Boot Device Selection (BDS) phase is started 
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS),     // Driver connecting is started
> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT),                                           // PCI Bus initialization is started
> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT),                                      // PCI Bus Hot Plug Controller Initialization
> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM),                                      // PCI Bus Enumeration
> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC),                                     // PCI Bus Request Resources
> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_ENABLE),                                         // PCI Bus Assign Resources
> +  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_INIT),                               // Console Output devices connect
> +  (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT),                                    // Console input devices connect
> +  (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),                                           // Super IO Initialization
> +  (EFI_IO_BUS_USB | EFI_IOB_PC_INIT),                                           // USB initialization is started
> +  (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),                                          // USB Reset
> +  (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT),                                         // USB Detect
> +  (EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE),                                         // USB Enable
> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),                                          // SCSI initialization is started
> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_RESET),                                         // SCSI Reset
> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),                                        // SCSI Detect
> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),                                        // SCSI Enable
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD),           // Setup Verifying Password
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP),                          // Start of Setup
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT),                          // Setup Input Wait
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT),          // Ready To Boot event
> +  (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES),            // Exit Boot Services event
> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP),    // Runtime Set Virtual Address MAP Begin
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT), // Runtime Set Virtual Address MAP End
> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM),               // System Reset
> +  (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG),                                        // USB hot plug
> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG),                                        // PCI bus hot plug
> +  0                                                                             // Must ended by 0
> +};
> +
> +UINT32 DxeErrorCode[] = {
> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH),                   // Some of the Architectural Protocols are not available
> +  (EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT),                        // PCI resource allocation error. Out of Resources
> +  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED),                 // No Console Output Devices are found
> +  (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED),                      // No Console Input Devices are found
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_PASSWORD),       // Invalid password
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR), // Error loading Boot Option (LoadImage returned error)
> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED),     // Boot Option is failed (StartImage returned error)
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UPDATE_FAIL),             // Flash update is failed
> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),  // Reset protocol is not available
> +  0                                                                       // Must end by 0
> +};
> +
> +EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
> +
> +STATIC UINT8 mBootstate = BOOT_START;
> +
> +STATIC
> +BOOLEAN
> +StatusCodeFilter (
> +  UINT32                *Map,
> +  EFI_STATUS_CODE_VALUE Value
> +  )
> +{
> +  UINTN Index = 0;
> +
> +  while (Map[Index] != 0) {
> +    if (Map[Index] == Value) {
> +      return TRUE;
> +    }
> +    Index++;
> +  }
> +  return FALSE;
> +}
> +
> +/**
> +  Report status code listener of Boot Progress Dxe.
> +
> +  @param[in]  CodeType            Indicates the type of status code being reported.
> +  @param[in]  Value               Describes the current status of a hardware or software entity.
> +                                  This included information about the class and subclass that is used to
> +                                  classify the entity as well as an operation.
> +  @param[in]  Instance            The enumeration of a hardware or software entity within
> +                                  the system. Valid instance numbers start with 1.
> +  @param[in]  CallerId            This optional parameter may be used to identify the caller.
> +                                  This parameter allows the status code driver to apply different rules to
> +                                  different callers.
> +  @param[in]  Data                This optional parameter may be used to pass additional data.
> +
> +  @retval EFI_SUCCESS             Status code is what we expected.
> +  @retval EFI_UNSUPPORTED         Status code not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BootProgressListenerDxe (
> +  IN EFI_STATUS_CODE_TYPE  CodeType,
> +  IN EFI_STATUS_CODE_VALUE Value,
> +  IN UINT32                Instance,
> +  IN EFI_GUID              *CallerId,
> +  IN EFI_STATUS_CODE_DATA  *Data
> +  )
> +{
> +  BOOLEAN IsProgress = FALSE;
> +  BOOLEAN IsError = FALSE;
> +
> +  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
> +    IsProgress = StatusCodeFilter (DxeProgressCode, Value);
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
> +    IsError = StatusCodeFilter (DxeErrorCode, Value);
> +  } else {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (!IsProgress && !IsError) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "BootProgressDxe: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
> +    CodeType,
> +    Value,
> +    Instance,
> +    CallerId,
> +    Data
> +    ));
> +
> +  if (IsError) {
> +    mBootstate = BOOT_FAILED;
> +  } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)) {
> +    /* Set boot complete when reach to ReadyToBoot event */
> +    mBootstate = BOOT_COMPLETE;
> +  }
> +
> +  MailboxMsgSetBootProgress (0, mBootstate, Value);
> +
> +  if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) &&
> +      mRscHandlerProtocol != NULL)
> +  {
> +    mRscHandlerProtocol->Unregister (BootProgressListenerDxe);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +
> +/**
> +  The module Entry Point of the Firmware Performance Data Table DXE driver.
> +
> +  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
> +  @param[in]  SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS    The entry point is executed successfully.
> +  @retval Other          Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BootProgressDxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  //
> +  // Get Report Status Code Handler Protocol.
> +  //
> +  Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **)&mRscHandlerProtocol);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Register report status code listener for OS Loader load and start.
> +  //
> +  if (!EFI_ERROR (Status)) {
> +    Status = mRscHandlerProtocol->Register (BootProgressListenerDxe, TPL_HIGH_LEVEL);
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
> new file mode 100644
> index 000000000000..c677e27a00ce
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
> @@ -0,0 +1,210 @@
> +/** @file
> +
> +  This module installs Boot Progress Pei to report boot progress to SMpro.
> +
> +  This module registers report status code listener to report boot progress
> +  to SMpro.
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +#include <Pi/PiStatusCode.h>
> +#include <Ppi/ReportStatusCodeHandler.h>
> +
> +enum BOOT_PROGRESS_STATE {
> +  BOOT_NOTSTART = 0,
> +  BOOT_START    = 1,
> +  BOOT_COMPLETE = 2,
> +  BOOT_FAILED   = 3,
> +};
> +
> +UINT32 PeiProgressStatusCode[] = {
> +  // Regular boot
> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_ENTRY_POINT),         // PEI Core is started
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT), // Pre-memory CPU initialization is started
> +  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_INSTALL_PEI_MEMORY),     // Memory Installed
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_PC_INIT_BEGIN),       // CPU post-memory initialization is started
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT),    // CPU post-memory initialization. Cache initialization
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT),       // CPU post-memory initialization. Application Processor(s) (AP) initialization
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT),    // CPU post-memory initialization. Boot Strap Processor (BSP) selection
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT),      // CPU post-memory initialization. System Management Mode (SMM) initialization
> +  // DXE IPL is started
> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT), // DXE IPL is started
> +  // DXE Core is started
> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),     // DXE Core is started
> +  // Recovery
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_AUTO),  // Recovery condition triggered by firmware (Auto recovery)
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_USER),  // Recovery condition triggered by user (Forced recovery)
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN), // Recovery process started
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD),   // Recovery firmware image is found
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START),  // Recovery firmware image is loaded
> +  // S3
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT), // S3 Boot Script execution
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE),        // OS S3 wake vector call
> +  0                                                         // Must end with 0
> +};
> +
> +UINT32 PeiErrorStatusCode[] = {
> +  // Regular boot
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_TYPE),       // Memory initialization error. Invalid memory type
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SPEED),      // Memory initialization error. Incompatible memory speed
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_SPD_FAIL),           // Memory initialization error. SPD reading has failed
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SIZE),       // Memory initialization error. Invalid memory size
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH),           // Memory initialization error. Memory modules do not match
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED),      // Memory initialization error. No usable memory detected
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL),        // Memory initialization error. No usable memory detected
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_EC_NON_SPECIFIC),              // Unspecified memory initialization error.
> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED), // Memory not installed
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_TYPE),   // Invalid CPU type
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_SPEED),  // Invalid CPU Speed
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MISMATCH),       // CPU mismatch
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST),      // CPU self test failed
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CACHE),          // possible CPU cache error
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INTERNAL),       // Internal CPU error
> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_NON_SPECIFIC),      // Internal CPU error
> +  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),     // reset PPI is not available
> +  // Recovery
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND),     // Recovery PPI is not available
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE),        // Recovery capsule is not found
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR), // Invalid recovery capsule
> +  // S3 Resume
> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_S3_RESUME_FAIL),     // S3 Resume Failed
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND), // S3 Resume PPI not found
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR),    // S3 Resume Boot Script Error
> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR),        // S3 OS Wake Error
> +  0
> +};
> +
> +// Should always be BOOT_START when start
> +STATIC UINT8 mBootstate = BOOT_START;
> +
> +STATIC
> +BOOLEAN
> +StatusCodeFilter (
> +  UINT32                *Map,
> +  EFI_STATUS_CODE_VALUE Value
> +  )
> +{
> +  UINTN Index = 0;
> +
> +  while (Map[Index] != 0) {
> +    if (Map[Index] == Value) {
> +      return TRUE;
> +    }
> +    Index++;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  Report status code listener for PEI. This is used to record the boot progress info
> +  and report it to SMpro.
> +
> +  @param[in]  PeiServices         An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
> +  @param[in]  CodeType            Indicates the type of status code being reported.
> +  @param[in]  Value               Describes the current status of a hardware or software entity.
> +                                  This included information about the class and subclass that is used to
> +                                  classify the entity as well as an operation.
> +  @param[in]  Instance            The enumeration of a hardware or software entity within
> +                                  the system. Valid instance numbers start with 1.
> +  @param[in]  CallerId            This optional parameter may be used to identify the caller.
> +                                  This parameter allows the status code driver to apply different rules to
> +                                  different callers.
> +  @param[in]  Data                This optional parameter may be used to pass additional data.
> +
> +  @retval EFI_SUCCESS             Status code is what we expected.
> +  @retval EFI_UNSUPPORTED         Status code not supported.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BootProgressListenerPei (
> +  IN       CONST EFI_PEI_SERVICES **PeiServices,
> +  IN       EFI_STATUS_CODE_TYPE   CodeType,
> +  IN       EFI_STATUS_CODE_VALUE  Value,
> +  IN       UINT32                 Instance,
> +  IN CONST EFI_GUID               *CallerId,
> +  IN CONST EFI_STATUS_CODE_DATA   *Data
> +  )
> +{
> +  BOOLEAN IsProgress = FALSE;
> +  BOOLEAN IsError = FALSE;
> +
> +  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
> +    IsProgress = StatusCodeFilter (PeiProgressStatusCode, Value);
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
> +    IsError = StatusCodeFilter (PeiErrorStatusCode, Value);
> +  } else {
> +    return EFI_SUCCESS;
> +  }
> +
> +  // No interested status found
> +  if (!IsProgress && !IsError) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "BootProgressPeim: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
> +    CodeType,
> +    Value,
> +    Instance,
> +    CallerId,
> +    Data
> +    ));
> +
> +  if (IsError) {
> +    mBootstate = BOOT_FAILED;
> +  }
> +
> +  MailboxMsgSetBootProgress (0, mBootstate, Value);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Main entry for Boot Progress PEIM.
> +
> +  This routine is to register report status code listener for Boot Progress PEIM.
> +
> +  @param[in]  FileHandle              Handle of the file being invoked.
> +  @param[in]  PeiServices             Pointer to PEI Services table.
> +
> +  @retval EFI_SUCCESS Report status code listener is registered successfully.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +BootProgressPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_PEI_RSC_HANDLER_PPI *RscHandler;
> +
> +  Status = PeiServicesLocatePpi (
> +             &gEfiPeiRscHandlerPpiGuid,
> +             0,
> +             NULL,
> +             (VOID **)&RscHandler
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (!EFI_ERROR (Status)) {
> +    Status = RscHandler->Register (BootProgressListenerPei);
> +  }
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
> new file mode 100644
> index 000000000000..492e85404631
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
> @@ -0,0 +1,16 @@
> +//
> +// This module installs Boot Progress Dxe that report boot progress to SMpro.
> +//
> +// This module registers report status code listener to report boot progress
> +// for SMpro.
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Installs Boot Progress Driver"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "This module registers report status code listener to collect and report boot progress to SMpro."
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
> new file mode 100644
> index 000000000000..0371fc4f9a80
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
> @@ -0,0 +1,18 @@
> +//
> +// Boot Progress Pei Module.
> +//
> +// Updates to SCP with Boot Progress information during boot
> +//
> +// This module register report status code listener to collect boot progress
> +// information and keep SCP posted.
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +//
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Boot Progress Pei Module."
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "Updates SCP with boot progress information during boot. This module register report status code listener to collect boot progress information and post to SCP."
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
@ 2021-06-04 23:36   ` Leif Lindholm
  2021-06-15 16:48     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:36 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:01 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Non-volatile variables now can be stored on flash. MM communication
> protocol is used to access storage on flash.
> 
> Included in this change are:
> * FlashPei module is used to compare saved UUID with firmware's
>   UEFI_UUID on each boot. If UUIDs match, data is stored to RAM.
>   Otherwise fill the storage with default value from NVRAM FV.
> * FlashLib provide APIs to access flash through MM Communication
>   protocol
> * FlashFvbDxe installs gEfiFirmwareVolumeBlock protocol which will be
>   used by the variable services to get/set variables.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                  |   3 +
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec              |   3 +
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc              |  11 +-
>  Platform/Ampere/JadePkg/Jade.dsc                                  |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                  |  62 ++-
>  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf |  54 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf       |  51 ++
>  Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf       |  36 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h          |  42 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c   | 525 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c         | 283 +++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c         | 358 +++++++++++++
>  12 files changed, 1425 insertions(+), 4 deletions(-)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index be827dd19a96..d5b12a81e9bf 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -37,6 +37,9 @@ [LibraryClasses]
>    ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>    MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  
> +  ##  @libraryclass  Defines a set of methods to access flash memory.
> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
> +
>    ##  @libraryclass  Defines a set of methods to generate random numbers by using Hardware RNG.
>    TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
>  
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> index 6ebdf7db0a57..26e020715290 100755
> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> @@ -44,3 +44,6 @@ [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
>    # Firmware Volume Pcds
>    #
>    gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
> +
> +  # NVRam Pcds
> +  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 9f75da6f05ad..65973569a41d 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -14,6 +14,7 @@ [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
>  
>  [BuildOptions]
>    GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
> +  GCC:*_*_*_CC_FLAGS = -DUEFI_UUID=$(UEFI_UUID)

This isn't obvious enough. I'm a bear of very little brain, and I
could possibly figure out what's happening here, given time, but
please put a proper description in commit message (and possibly here?
whatever makes sense).

>  
>  [LibraryClasses.common]
>  !if $(TARGET) == RELEASE
> @@ -224,6 +225,7 @@ [LibraryClasses.common.DXE_DRIVER]
>    SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
>    PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
>    MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>  
>  [LibraryClasses.common.UEFI_APPLICATION]
>    UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
> @@ -254,6 +256,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>  
>    EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
>    ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>  
>  [LibraryClasses.ARM,LibraryClasses.AARCH64]
>    #
> @@ -500,6 +503,8 @@ [PcdsDynamicDefault.common]
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0
>    gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
>  
> +  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE
> +
>  ################################################################################
>  #
>  # Component Section - list of all EDK II Component Entries defined by this Platform
> @@ -520,8 +525,10 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>    ArmPkg/Drivers/CpuPei/CpuPei.inf
>    UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
>    MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>    MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
>      <LibraryClasses>
> @@ -575,9 +582,9 @@ [Components.common]
>    #
>    # Environment Variables Protocol
>    #
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
> +  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>    MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
> -    <PcdsFixedAtBuild>
> -      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
>      <LibraryClasses>
>        BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
>        TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index f37ab1a92e44..9b9a5d0bad0f 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -52,6 +52,7 @@ [Defines]
>    DEFINE EDK2_SKIP_PEICORE       = TRUE
>    DEFINE SECURE_BOOT_ENABLE      = FALSE
>    DEFINE INCLUDE_TFTP_COMMAND    = TRUE
> +  DEFINE UEFI_UUID               = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5

This is a horrible name for a UUID. What is it meant to identify?

>    #
>    # Network definition
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 1857296a8ea5..375455086d0b 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -26,7 +26,7 @@ [FD.BL33_JADE_UEFI]
>  ErasePolarity = 1
>  
>  # This one is tricky, it must be: BlockSize * NumBlocks = Size
> -BlockSize     = 0x10000
> +BlockSize     = 0x10000|gAmpereTokenSpaceGuid.PcdFvBlockSize
>  NumBlocks     = 0x7C
>  
>  ################################################################################
> @@ -56,8 +56,61 @@ [FD.BL33_JADE_UEFI]
>  
>  #
>  # NV Variables
> -# T.B.D

Ah. If I can make a retroactive comment - could this be introduced as
"Placeholder" rather than "T.B.D."?

/
    Leif

> +# Offset: 0x00740000
> +# Size:   0x00080000
>  #
> +0x00740000|0x00030000
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +DATA = {
> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
> +  # ZeroVector []
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
> +  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
> +  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
> +  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
> +  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
> +  # FvLength: 0x80000
> +  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  # Signature "_FVH"       # Attributes
> +  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
> +  # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
> +  0x48, 0x00, 0x2D, 0x09, 0x00, 0x00, 0x00, 0x02,
> +  # Blockmap[0]: 0x2 Blocks * 0x40000 Bytes / Block
> +  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
> +  # Blockmap[1]: End
> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +  ## This is the VARIABLE_STORE_HEADER
> +  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
> +  # Signature: gEfiAuthenticatedVariableGuid =
> +  #   { 0xaaf32c78, 0x947b, 0x439a,
> +  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
> +  # Size: 0x30000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
> +  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x2FFB8
> +  # This can speed up the Variable Dispatch a bit.
> +  0xB8, 0xFF, 0x02, 0x00,
> +  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +0x00770000|0x00010000
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +DATA = {
> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
> +  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
> +  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
> +  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
> +  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
> +  # WriteQueueSize: UINT64 Size: 0x10000 - 0x20 (FTW_WORKING_HEADER) = 0xFFE0
> +  0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
> +}
> +
> +0x00780000|0x00040000
> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
>  
>  ################################################################################
>  #
> @@ -102,9 +155,11 @@ [FV.FVMAIN_COMPACT]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>    INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>    INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
>    INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>    INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
>    INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
> @@ -144,6 +199,7 @@ [FV.FvMain]
>    INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>    INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>  }
>  
>    INF MdeModulePkg/Core/Dxe/DxeMain.inf
> @@ -173,6 +229,8 @@ [FV.FvMain]
>    # Environment Variables Protocol
>    #
>    INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>  
>    #
>    # Multiple Console IO support
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
> new file mode 100644
> index 000000000000..782278615094
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
> @@ -0,0 +1,54 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = FlashFvbDxe
> +  FILE_GUID                      = 9E6EA240-DF80-11EA-8B6E-0800200C9A66
> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
> +  VERSION_STRING                 = 0.1
> +  ENTRY_POINT                    = FlashFvbDxeInitialize
> +
> +[Sources]
> +  FlashFvbDxe.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  FlashLib
> +  PcdLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiRuntimeLib
> +
> +[FixedPcd]
> +  gAmpereTokenSpaceGuid.PcdFvBlockSize
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
> +
> +[Guids]
> +  gEfiEventVirtualAddressChangeGuid
> +  gSpiNorMmGuid
> +
> +[Protocols]
> +  gEfiFirmwareVolumeBlockProtocolGuid             ## PRODUCES
> +  gEfiMmCommunicationProtocolGuid                 ## CONSUMES
> +
> +[Depex]
> +  gEfiMmCommunicationProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
> new file mode 100644
> index 000000000000..a4eaf5039bb0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
> @@ -0,0 +1,51 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = FlashPei
> +  FILE_GUID                      = 967CFBD0-DF81-11EA-8B6E-0800200C9A66
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = FlashPeiEntryPoint
> +
> +[Sources]
> +  FlashPei.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmSmcLib
> +  BaseMemoryLib
> +  DebugLib
> +  MmCommunicationLib
> +  PcdLib
> +  PeimEntryPoint
> +
> +[Guids]
> +  gSpiNorMmGuid
> +
> +[FixedPcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
> +
> +  gAmpereTokenSpaceGuid.PcdNvramErased
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
> new file mode 100644
> index 000000000000..2d5003d1af17
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
> @@ -0,0 +1,36 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                   = 0x0001001B
> +  BASE_NAME                     = FlashLib
> +  FILE_GUID                     = 9E9D093D-6484-45AE-BA49-0745AA0BB481
> +  MODULE_TYPE                   = DXE_DRIVER
> +  VERSION_STRING                = 0.1
> +  LIBRARY_CLASS                 = FlashLib
> +  CONSTRUCTOR                   = FlashLibConstructor
> +
> +[Sources.common]
> +  FlashLib.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +
> +[Guids]
> +  gSpiNorMmGuid
> +
> +[Protocols]
> +  gEfiMmCommunicationProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
> new file mode 100644
> index 000000000000..9207dee643a5
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
> @@ -0,0 +1,42 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef FLASH_LIB_H_
> +#define FLASH_LIB_H_
> +
> +EFI_STATUS
> +EFIAPI
> +FlashGetNvRamInfo (
> +  OUT UINT64 *NvRamBase,
> +  OUT UINT32 *NvRamSize
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FlashEraseCommand (
> +  IN UINT8  *pBlockAddress,
> +  IN UINT32 Length
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FlashProgramCommand (
> +  IN     UINT8 *pByteAddress,
> +  IN     UINT8 *Byte,
> +  IN OUT UINTN *Length
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +FlashReadCommand (
> +  IN     UINT8 *pByteAddress,
> +  OUT    UINT8 *Byte,
> +  IN OUT UINTN *Length
> +  );
> +
> +#endif /* FLASH_LIB_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
> new file mode 100644
> index 000000000000..dcd92151b7d2
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
> @@ -0,0 +1,525 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/FlashLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeLib.h>
> +#include <Protocol/FirmwareVolumeBlock.h>
> +
> +//
> +// These temporary buffers are used to calculate and convert linear virtual
> +// to physical address
> +//
> +STATIC UINT64 mNvFlashBase;
> +STATIC UINT32 mNvFlashSize;
> +STATIC UINT32 mFlashBlockSize;
> +STATIC UINT64 mNvStorageBase;
> +STATIC UINT64 mNvStorageSize;
> +
> +/**
> +  Fixup internal data so that EFI can be call in virtual mode.
> +  Call the passed in Child Notify event and convert any pointers in
> +  lib to virtual mode.
> +
> +  @param[in]    Event   The Event that is being processed
> +  @param[in]    Context Event Context
> +**/
> +VOID
> +EFIAPI
> +FlashFvbAddressChangeEvent (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EfiConvertPointer (0x0, (VOID **)&mNvStorageBase);
> +}
> +
> +/**
> +  The GetAttributes() function retrieves the attributes and
> +  current settings of the block.
> +
> +  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
> +                    attributes and current settings are
> +                    returned. Type EFI_FVB_ATTRIBUTES_2 is defined
> +                    in EFI_FIRMWARE_VOLUME_HEADER.
> +
> +  @retval EFI_SUCCESS The firmware volume attributes were
> +                      returned.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeGetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  OUT      EFI_FVB_ATTRIBUTES_2                *Attributes
> +  )
> +{
> +  ASSERT (Attributes != NULL);
> +
> +  *Attributes = EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
> +                EFI_FVB2_READ_STATUS        | // Reads are currently enabled
> +                EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
> +                EFI_FVB2_WRITE_ENABLED_CAP  | // Writes may be enabled
> +                EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
> +                EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
> +                EFI_FVB2_ALIGNMENT          |
> +                EFI_FVB2_ERASE_POLARITY;      // After erasure all bits take this value (i.e. '1')
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The SetAttributes() function sets configurable firmware volume
> +  attributes and returns the new settings of the firmware volume.
> +
> +  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Attributes   On input, Attributes is a pointer to
> +                      EFI_FVB_ATTRIBUTES_2 that contains the
> +                      desired firmware volume settings. On
> +                      successful return, it contains the new
> +                      settings of the firmware volume. Type
> +                      EFI_FVB_ATTRIBUTES_2 is defined in
> +                      EFI_FIRMWARE_VOLUME_HEADER.
> +
> +  @retval EFI_SUCCESS           The firmware volume attributes were returned.
> +
> +  @retval EFI_INVALID_PARAMETER The attributes requested are in
> +                                conflict with the capabilities
> +                                as declared in the firmware
> +                                volume header.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeSetAttributes (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  IN OUT   EFI_FVB_ATTRIBUTES_2                *Attributes
> +  )
> +{
> +  return EFI_SUCCESS;  // ignore for now
> +}
> +
> +/**
> +  The GetPhysicalAddress() function retrieves the base address of
> +  a memory-mapped firmware volume. This function should be called
> +  only for memory-mapped firmware volumes.
> +
> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Address  Pointer to a caller-allocated
> +                  EFI_PHYSICAL_ADDRESS that, on successful
> +                  return from GetPhysicalAddress(), contains the
> +                  base address of the firmware volume.
> +
> +  @retval EFI_SUCCESS       The firmware volume base address was returned.
> +
> +  @retval EFI_UNSUPPORTED   The firmware volume is not memory mapped.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeGetPhysicalAddress (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  OUT      EFI_PHYSICAL_ADDRESS                *Address
> +  )
> +{
> +  ASSERT (Address != NULL);
> +
> +  *Address = (EFI_PHYSICAL_ADDRESS)mNvStorageBase;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  The GetBlockSize() function retrieves the size of the requested
> +  block. It also returns the number of additional blocks with
> +  the identical size. The GetBlockSize() function is used to
> +  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
> +
> +
> +  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba            Indicates the block for which to return the size.
> +
> +  @param BlockSize      Pointer to a caller-allocated UINTN in which
> +                        the size of the block is returned.
> +
> +  @param NumberOfBlocks Pointer to a caller-allocated UINTN in
> +                        which the number of consecutive blocks,
> +                        starting with Lba, is returned. All
> +                        blocks in this range have a size of
> +                        BlockSize.
> +
> +
> +  @retval EFI_SUCCESS             The firmware volume base address was returned.
> +
> +  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeGetBlockSize (
> +  IN  CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  IN        EFI_LBA                             Lba,
> +  OUT       UINTN                               *BlockSize,
> +  OUT       UINTN                               *NumberOfBlocks
> +  )
> +{
> +  UINTN TotalNvStorageBlocks;
> +
> +  ASSERT (BlockSize != NULL);
> +  ASSERT (NumberOfBlocks != NULL);
> +
> +  TotalNvStorageBlocks = mNvStorageSize / mFlashBlockSize;
> +
> +  if (TotalNvStorageBlocks <= (UINTN)Lba) {
> +    DEBUG ((DEBUG_ERROR, "The requested LBA is out of range\n"));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *NumberOfBlocks = TotalNvStorageBlocks - (UINTN)Lba;
> +  *BlockSize = mFlashBlockSize;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Reads the specified number of bytes into a buffer from the specified block.
> +
> +  The Read() function reads the requested number of bytes from the
> +  requested block and stores them in the provided buffer.
> +  Implementations should be mindful that the firmware volume
> +  might be in the ReadDisabled state. If it is in this state,
> +  the Read() function must return the status code
> +  EFI_ACCESS_DENIED without modifying the contents of the
> +  buffer. The Read() function must also prevent spanning block
> +  boundaries. If a read is requested that would span a block
> +  boundary, the read must read up to the boundary but not
> +  beyond. The output parameter NumBytes must be set to correctly
> +  indicate the number of bytes actually read. The caller must be
> +  aware that a read may be partially completed.
> +
> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba      The starting logical block index
> +                  from which to read.
> +
> +  @param Offset   Offset into the block at which to begin reading.
> +
> +  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
> +                  contains the total size of the buffer. At
> +                  exit, *NumBytes contains the total number of
> +                  bytes read.
> +
> +  @param Buffer   Pointer to a caller-allocated buffer that will
> +                  be used to hold the data that is read.
> +
> +  @retval EFI_SUCCESS         The firmware volume was read successfully,
> +                              and contents are in Buffer.
> +
> +  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
> +                              boundary. On output, NumBytes
> +                              contains the total number of bytes
> +                              returned in Buffer.
> +
> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
> +                              ReadDisabled state.
> +
> +  @retval EFI_DEVICE_ERROR    The block device is not
> +                              functioning correctly and could
> +                              not be read.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeRead (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  IN       EFI_LBA                             Lba,
> +  IN       UINTN                               Offset,
> +  IN OUT   UINTN                               *NumBytes,
> +  IN OUT   UINT8                               *Buffer
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  ASSERT (NumBytes != NULL);
> +  ASSERT (Buffer != NULL);
> +
> +  if (Offset + *NumBytes > mFlashBlockSize) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  Status = FlashReadCommand (
> +             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
> +             Buffer,
> +             NumBytes
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to do flash read\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Writes the specified number of bytes from the input buffer to the block.
> +
> +  The Write() function writes the specified number of bytes from
> +  the provided buffer to the specified block and offset. If the
> +  firmware volume is sticky write, the caller must ensure that
> +  all the bits of the specified range to write are in the
> +  EFI_FVB_ERASE_POLARITY state before calling the Write()
> +  function, or else the result will be unpredictable. This
> +  unpredictability arises because, for a sticky-write firmware
> +  volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
> +  state but cannot flip it back again.  Before calling the
> +  Write() function,  it is recommended for the caller to first call
> +  the EraseBlocks() function to erase the specified block to
> +  write. A block erase cycle will transition bits from the
> +  (NOT)EFI_FVB_ERASE_POLARITY state back to the
> +  EFI_FVB_ERASE_POLARITY state. Implementations should be
> +  mindful that the firmware volume might be in the WriteDisabled
> +  state. If it is in this state, the Write() function must
> +  return the status code EFI_ACCESS_DENIED without modifying the
> +  contents of the firmware volume. The Write() function must
> +  also prevent spanning block boundaries. If a write is
> +  requested that spans a block boundary, the write must store up
> +  to the boundary but not beyond. The output parameter NumBytes
> +  must be set to correctly indicate the number of bytes actually
> +  written. The caller must be aware that a write may be
> +  partially completed. All writes, partial or otherwise, must be
> +  fully flushed to the hardware before the Write() service
> +  returns.
> +
> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
> +
> +  @param Lba      The starting logical block index to write to.
> +
> +  @param Offset   Offset into the block at which to begin writing.
> +
> +  @param NumBytes The pointer to a UINTN. At entry, *NumBytes
> +                  contains the total size of the buffer. At
> +                  exit, *NumBytes contains the total number of
> +                  bytes actually written.
> +
> +  @param Buffer   The pointer to a caller-allocated buffer that
> +                  contains the source for the write.
> +
> +  @retval EFI_SUCCESS         The firmware volume was written successfully.
> +
> +  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
> +                              LBA boundary. On output, NumBytes
> +                              contains the total number of bytes
> +                              actually written.
> +
> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
> +                              WriteDisabled state.
> +
> +  @retval EFI_DEVICE_ERROR    The block device is malfunctioning
> +                              and could not be written.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeWrite (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  IN       EFI_LBA                             Lba,
> +  IN       UINTN                               Offset,
> +  IN OUT   UINTN                               *NumBytes,
> +  IN       UINT8                               *Buffer
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  ASSERT (NumBytes != NULL);
> +  ASSERT (Buffer != NULL);
> +
> +  if (Offset + *NumBytes > mFlashBlockSize) {
> +    return EFI_BAD_BUFFER_SIZE;
> +  }
> +
> +  Status = FlashProgramCommand (
> +             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
> +             Buffer,
> +             NumBytes
> +             );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to do flash program\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  Erases and initializes a firmware volume block.
> +
> +  The EraseBlocks() function erases one or more blocks as denoted
> +  by the variable argument list. The entire parameter list of
> +  blocks must be verified before erasing any blocks. If a block is
> +  requested that does not exist within the associated firmware
> +  volume (it has a larger index than the last block of the
> +  firmware volume), the EraseBlocks() function must return the
> +  status code EFI_INVALID_PARAMETER without modifying the contents
> +  of the firmware volume. Implementations should be mindful that
> +  the firmware volume might be in the WriteDisabled state. If it
> +  is in this state, the EraseBlocks() function must return the
> +  status code EFI_ACCESS_DENIED without modifying the contents of
> +  the firmware volume. All calls to EraseBlocks() must be fully
> +  flushed to the hardware before the EraseBlocks() service
> +  returns.
> +
> +  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
> +                instance.
> +
> +  @param ...    The variable argument list is a list of tuples.
> +                Each tuple describes a range of LBAs to erase
> +                and consists of the following:
> +                - An EFI_LBA that indicates the starting LBA
> +                - A UINTN that indicates the number of blocks to
> +                  erase.
> +
> +                The list is terminated with an
> +                EFI_LBA_LIST_TERMINATOR. For example, the
> +                following indicates that two ranges of blocks
> +                (5-7 and 10-11) are to be erased: EraseBlocks
> +                (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
> +
> +  @retval EFI_SUCCESS The erase request successfully
> +                      completed.
> +
> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
> +                              WriteDisabled state.
> +  @retval EFI_DEVICE_ERROR  The block device is not functioning
> +                            correctly and could not be written.
> +                            The firmware device may have been
> +                            partially erased.
> +  @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
> +                                in the variable argument list do
> +                                not exist in the firmware volume.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeErase (
> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
> +  ...
> +  )
> +{
> +  VA_LIST    Args;
> +  EFI_LBA    Start;
> +  UINTN      Length;
> +  EFI_STATUS Status;
> +
> +  Status = EFI_SUCCESS;
> +
> +  VA_START (Args, This);
> +
> +  for (Start = VA_ARG (Args, EFI_LBA);
> +       Start != EFI_LBA_LIST_TERMINATOR;
> +       Start = VA_ARG (Args, EFI_LBA))
> +  {
> +    Length = VA_ARG (Args, UINTN);
> +    Status = FlashEraseCommand (
> +               (UINT8 *)(mNvFlashBase + Start * mFlashBlockSize),
> +               Length * mFlashBlockSize
> +               );
> +  }
> +
> +  VA_END (Args);
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to do flash erase\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFlashFvbProtocol = {
> +  FlashFvbDxeGetAttributes,
> +  FlashFvbDxeSetAttributes,
> +  FlashFvbDxeGetPhysicalAddress,
> +  FlashFvbDxeGetBlockSize,
> +  FlashFvbDxeRead,
> +  FlashFvbDxeWrite,
> +  FlashFvbDxeErase
> +};
> +
> +EFI_STATUS
> +EFIAPI
> +FlashFvbDxeInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_HANDLE FvbHandle = NULL;
> +  EFI_EVENT  VirtualAddressChangeEvent;
> +
> +  // Get NV store FV info
> +  mFlashBlockSize = FixedPcdGet32 (PcdFvBlockSize);
> +  mNvStorageBase = PcdGet64 (PcdFlashNvStorageVariableBase64);
> +  mNvStorageSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +                   FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +                   FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
> +
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n",
> +    __FUNCTION__,
> +    mNvStorageBase,
> +    mNvStorageSize
> +    ));
> +
> +  // Get NV Flash information
> +  Status = FlashGetNvRamInfo ((UINT64 *)&mNvFlashBase, (UINT32 *)&mNvFlashSize);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash info\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (mNvFlashSize >= (mNvStorageSize * 2)) {
> +    DEBUG ((DEBUG_INFO, "%a: NV store on Flash is valid\n", __FUNCTION__));
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "%a: NV store on Flash is invalid\n", __FUNCTION__));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  FlashFvbAddressChangeEvent,
> +                  NULL,
> +                  &gEfiEventVirtualAddressChangeGuid,
> +                  &VirtualAddressChangeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &FvbHandle,
> +                  &gEfiFirmwareVolumeBlockProtocolGuid,
> +                  &mFlashFvbProtocol,
> +                  NULL
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to install Firmware Volume Block protocol\n"));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
> new file mode 100644
> index 000000000000..6bfbbbebaa85
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
> @@ -0,0 +1,283 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Uefi.h>
> +
> +#include <Library/ArmSmcLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MmCommunicationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <MmLib.h>
> +
> +// Convert to string
> +#define _STR(x)          #x
> +
> +// Make sure the argument is expanded before converting to string
> +#define STR(x)          _STR(x)
> +
> +// Use dynamic UEFI_UUID of each build time
> +#define UEFI_UUID_BUILD      STR(UEFI_UUID)
> +
> +EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
> +
> +STATIC CHAR8 mBuildUuid[sizeof (UEFI_UUID_BUILD)];
> +STATIC CHAR8 mStoredUuid[sizeof (UEFI_UUID_BUILD)];
> +
> +STATIC
> +EFI_STATUS
> +UefiMmCreateSpiNorReq (
> +  VOID   *Data,
> +  UINT64 Size
> +  )
> +{
> +  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
> +  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
> +
> +  if (Size != 0) {
> +    ASSERT (Data);
> +    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
> +
> +    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Entry point function for the PEIM
> +
> +  @param FileHandle      Handle of the file being invoked.
> +  @param PeiServices     Describes the list of possible PEI Services.
> +
> +  @return EFI_SUCCESS    If we installed our PPI
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +FlashPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  UINT64                               FWNvRamStartOffset;
> +  EFI_STATUS                           Status;
> +  EFI_MM_COMMUNICATE_SPINOR_RES        *MmSpiNorRes;
> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
> +  UINT64                               MmData[5];
> +  UINTN                                Size;
> +  VOID                                 *NvRamAddress;
> +  UINTN                                NvRamSize;
> +
> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNV2InfoRes;
> +  UINT64                               NV2Base, NV2Size;
> +#endif
> +
> +  NvRamAddress = (VOID *)PcdGet64 (PcdFlashNvStorageVariableBase64);
> +  NvRamSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
> +              FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
> +              FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
> +
> +  /* Find out about the start offset of NVRAM to be passed to SMC */
> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = MmCommunicationCommunicate (
> +             (VOID *)&mEfiMmSpiNorReq,
> +             &Size
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorNVInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    /* Old FW so just exit */
> +    return EFI_SUCCESS;
> +  }
> +  FWNvRamStartOffset = MmSpiNorNVInfoRes->NVBase;
> +
> +  CopyMem ((VOID *)mBuildUuid, (VOID *)UEFI_UUID_BUILD, sizeof (UEFI_UUID_BUILD));
> +  if (MmSpiNorNVInfoRes->NVSize < (NvRamSize * 2 + sizeof (mBuildUuid))) {
> +    /* NVRAM size provided by FW is not enough */
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  /* We stored BIOS UUID build at the offset NVRAM_SIZE * 2 */
> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
> +  MmData[0] = MM_SPINOR_FUNC_READ;
> +  MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
> +  MmData[2] = (UINT64)sizeof (mStoredUuid);
> +  MmData[3] = (UINT64)mStoredUuid;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = MmCommunicationCommunicate (
> +             (VOID *)&mEfiMmSpiNorReq,
> +             &Size
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    return Status;
> +  }
> +
> +  if (CompareMem ((VOID *)mStoredUuid, (VOID *)mBuildUuid, sizeof (mBuildUuid))) {
> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
> +    MmData[0] = MM_SPINOR_FUNC_ERASE;
> +    MmData[1] = (UINT64)FWNvRamStartOffset;
> +    MmData[2] = (UINT64)(NvRamSize * 2);
> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = MmCommunicationCommunicate (
> +               (VOID *)&mEfiMmSpiNorReq,
> +               &Size
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      return Status;
> +    }
> +
> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
> +    MmData[1] = (UINT64)FWNvRamStartOffset;
> +    MmData[2] = (UINT64)(NvRamSize * 2);
> +    MmData[3] = (UINT64)NvRamAddress;
> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = MmCommunicationCommunicate (
> +               (VOID *)&mEfiMmSpiNorReq,
> +               &Size
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      return Status;
> +    }
> +
> +    /* Update UUID */
> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
> +    MmData[0] = MM_SPINOR_FUNC_ERASE;
> +    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
> +    MmData[2] = (UINT64)sizeof (mBuildUuid);
> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = MmCommunicationCommunicate (
> +               (VOID *)&mEfiMmSpiNorReq,
> +               &Size
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      return Status;
> +    }
> +
> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
> +    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
> +    MmData[2] = (UINT64)sizeof (mBuildUuid);
> +    MmData[3] = (UINT64)mBuildUuid;
> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = MmCommunicationCommunicate (
> +               (VOID *)&mEfiMmSpiNorReq,
> +               &Size
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      return Status;
> +    }
> +    DEBUG ((DEBUG_INFO, "UUID Changed, Update Storage with FV NVRAM\n"));
> +
> +    /* Indicate that NVRAM was cleared */
> +    PcdSetBoolS (PcdNvramErased, TRUE);
> +  } else {
> +    /* Copy the stored NVRAM to RAM */
> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
> +    MmData[0] = MM_SPINOR_FUNC_READ;
> +    MmData[1] = (UINT64)FWNvRamStartOffset;
> +    MmData[2] = (UINT64)(NvRamSize * 2);
> +    MmData[3] = (UINT64)NvRamAddress;
> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = MmCommunicationCommunicate (
> +               (VOID *)&mEfiMmSpiNorReq,
> +               &Size
> +               );
> +    ASSERT_EFI_ERROR (Status);
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      return Status;
> +    }
> +    DEBUG ((DEBUG_INFO, "Identical UUID, copy stored NVRAM to RAM\n"));
> +  }
> +
> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
> +  /* Find out about the start offset of NVRAM2 to be passed to SMC */
> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM2_INFO;
> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = MmCommunicationCommunicate (
> +             (VOID *)&mEfiMmSpiNorReq,
> +             &Size
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  MmSpiNorNV2InfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
> +  if (MmSpiNorNV2InfoRes->Status == MM_SPINOR_RES_SUCCESS) {
> +    NV2Base = MmSpiNorNV2InfoRes->NVBase;
> +    NV2Size = MmSpiNorNV2InfoRes->NVSize;
> +    /* Make sure the requested size is smaller than allocated */
> +    if (RAM_BLOCKIO_SIZE <= NV2Size) {
> +      /* Copy the ramdisk image to RAM */
> +      ZeroMem ((VOID *)MmData, sizeof (MmData));
> +      MmData[0] = MM_SPINOR_FUNC_READ;
> +      MmData[1] = (UINT64)NV2Base; /* Start virtual address */
> +      MmData[2] = (UINT64)RAM_BLOCKIO_SIZE;
> +      MmData[3] = (UINT64)RAM_BLOCKIO_START_ADDRESS;
> +      UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +
> +      Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +      Status = MmCommunicationCommunicate (
> +                 (VOID *)&mEfiMmSpiNorReq,
> +                 &Size
> +                 );
> +      ASSERT_EFI_ERROR (Status);
> +
> +      MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
> +      ASSERT (MmSpiNorRes->Status == MM_SPINOR_RES_SUCCESS);
> +    }
> +
> +    BuildMemoryAllocationHob (
> +      (EFI_PHYSICAL_ADDRESS)RAM_BLOCKIO_START_ADDRESS,
> +      EFI_SIZE_TO_PAGES (RAM_BLOCKIO_SIZE) * EFI_PAGE_SIZE,
> +      EfiLoaderData
> +      );
> +  }
> +#endif
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
> new file mode 100644
> index 000000000000..cd77aed3cfe1
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
> @@ -0,0 +1,358 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/FlashLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <MmLib.h>
> +#include <Protocol/MmCommunication.h>
> +
> +STATIC EFI_MM_COMMUNICATION_PROTOCOL *mMmCommunicationProtocol = NULL;
> +STATIC EFI_MM_COMM_REQUEST           *mCommBuffer              = NULL;
> +
> +BOOLEAN mIsEfiRuntime;
> +UINT8   *mTmpBufVirt;
> +UINT8   *mTmpBufPhy;
> +
> +/**
> +  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
> +  event. It converts a pointer to a new virtual address.
> +
> +  @param  Event        Event whose notification function is being invoked.
> +  @param  Context      Pointer to the notification function's context
> +
> +**/
> +VOID
> +EFIAPI
> +FlashLibAddressChangeEvent (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  gRT->ConvertPointer (0x0, (VOID **)&mTmpBufVirt);
> +  gRT->ConvertPointer (0x0, (VOID **)&mCommBuffer);
> +  gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol);
> +
> +  mIsEfiRuntime = TRUE;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FlashLibConstructor (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_EVENT  VirtualAddressChangeEvent = NULL;
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  mCommBuffer = AllocateRuntimeZeroPool (sizeof (EFI_MM_COMM_REQUEST));
> +  ASSERT (mCommBuffer != NULL);
> +
> +  mTmpBufPhy = AllocateRuntimeZeroPool (EFI_MM_MAX_TMP_BUF_SIZE);
> +  mTmpBufVirt = mTmpBufPhy;
> +  ASSERT (mTmpBufPhy != NULL);
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiMmCommunicationProtocolGuid,
> +                  NULL,
> +                  (VOID **)&mMmCommunicationProtocol
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
> +                  TPL_CALLBACK,
> +                  FlashLibAddressChangeEvent,
> +                  NULL,
> +                  &VirtualAddressChangeEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +FlashMmCommunicate (
> +  IN OUT VOID  *CommBuffer,
> +  IN OUT UINTN *CommSize
> +  )
> +{
> +  if (mMmCommunicationProtocol == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return mMmCommunicationProtocol->Communicate (
> +                                     mMmCommunicationProtocol,
> +                                     CommBuffer,
> +                                     CommSize
> +                                     );
> +}
> +
> +STATIC
> +EFI_STATUS
> +UefiMmCreateSpiNorReq (
> +  IN VOID   *Data,
> +  IN UINT64 Size
> +  )
> +{
> +  if (mCommBuffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  CopyGuid (&mCommBuffer->EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
> +  mCommBuffer->EfiMmHdr.MsgLength = Size;
> +
> +  if (Size != 0) {
> +    ASSERT (Data);
> +    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
> +
> +    CopyMem (mCommBuffer->PayLoad.Data, Data, Size);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Convert Virtual Address to Physical Address at Runtime Services
> +
> +  @param  VirtualPtr          Virtual Address Pointer
> +  @param  Size                Total bytes of the buffer
> +
> +  @retval Ptr                 Return the pointer of the converted address
> +
> +**/
> +STATIC
> +UINT8 *
> +ConvertVirtualToPhysical (
> +  IN UINT8 *VirtualPtr,
> +  IN UINTN Size
> +  )
> +{
> +  if (mIsEfiRuntime) {
> +    ASSERT (VirtualPtr != NULL);
> +    CopyMem ((VOID *)mTmpBufVirt, (VOID *)VirtualPtr, Size);
> +    return (UINT8 *)mTmpBufPhy;
> +  }
> +
> +  return (UINT8 *)VirtualPtr;
> +}
> +
> +/**
> +  Convert Physical Address to Virtual Address at Runtime Services
> +
> +  @param  VirtualPtr          Physical Address Pointer
> +  @param  Size                Total bytes of the buffer
> +
> +**/
> +STATIC
> +VOID
> +ConvertPhysicaltoVirtual (
> +  IN UINT8 *PhysicalPtr,
> +  IN UINTN Size
> +  )
> +{
> +  if (mIsEfiRuntime) {
> +    ASSERT (PhysicalPtr != NULL);
> +    CopyMem ((VOID *)PhysicalPtr, (VOID *)mTmpBufVirt, Size);
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FlashGetNvRamInfo (
> +  OUT UINT64 *NvRamBase,
> +  OUT UINT32 *NvRamSize
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
> +  EFI_STATUS                           Status;
> +  UINT64                               MmData[5];
> +  UINTN                                Size;
> +
> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
> +
> +  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = FlashMmCommunicate (
> +             mCommBuffer,
> +             &Size
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mCommBuffer->PayLoad;
> +  if (MmSpiNorNVInfoRes->Status == MM_SPINOR_RES_SUCCESS) {
> +    *NvRamBase = MmSpiNorNVInfoRes->NVBase;
> +    *NvRamSize = MmSpiNorNVInfoRes->NVSize;
> +    DEBUG ((DEBUG_INFO, "NVInfo Base 0x%llx, Size 0x%lx\n", *NvRamBase, *NvRamSize));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FlashEraseCommand (
> +  IN UINT8  *pBlockAddress,
> +  IN UINT32 Length
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
> +  EFI_STATUS                    Status;
> +  UINT64                        MmData[5];
> +  UINTN                         Size;
> +
> +  ASSERT (pBlockAddress != NULL);
> +
> +  MmData[0] = MM_SPINOR_FUNC_ERASE;
> +  MmData[1] = (UINT64)pBlockAddress;
> +  MmData[2] = Length;
> +
> +  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +  Status = FlashMmCommunicate (
> +             mCommBuffer,
> +             &Size
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "Flash Erase: Device error %llx\n", MmSpiNorRes->Status));
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FlashProgramCommand (
> +  IN     UINT8 *pByteAddress,
> +  IN     UINT8 *Byte,
> +  IN OUT UINTN *Length
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
> +  EFI_STATUS                    Status;
> +  UINT64                        MmData[5];
> +  UINTN                         Remain, Size, NumWrite;
> +  UINTN                         Count = 0;
> +
> +  ASSERT (pByteAddress != NULL);
> +  ASSERT (Byte != NULL);
> +  ASSERT (Length != NULL);
> +
> +  Remain = *Length;
> +  while (Remain > 0) {
> +    NumWrite = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
> +
> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
> +    MmData[1] = (UINT64)pByteAddress;
> +    MmData[2] = NumWrite;
> +    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumWrite);
> +
> +    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = FlashMmCommunicate (
> +               mCommBuffer,
> +               &Size
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "Flash program: Device error 0x%llx\n", MmSpiNorRes->Status));
> +      return EFI_DEVICE_ERROR;
> +    }
> +
> +    Remain -= NumWrite;
> +    Count += NumWrite;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +FlashReadCommand (
> +  IN     UINT8 *pByteAddress,
> +  OUT    UINT8 *Byte,
> +  IN OUT UINTN *Length
> +  )
> +{
> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
> +  EFI_STATUS                    Status;
> +  UINT64                        MmData[5];
> +  UINTN                         Remain, Size, NumRead;
> +  UINTN                         Count = 0;
> +
> +  ASSERT (pByteAddress != NULL);
> +  ASSERT (Byte != NULL);
> +  ASSERT (Length != NULL);
> +
> +  Remain = *Length;
> +  while (Remain > 0) {
> +    NumRead = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
> +
> +    MmData[0] = MM_SPINOR_FUNC_READ;
> +    MmData[1] = (UINT64)pByteAddress;
> +    MmData[2] = NumRead;
> +    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumRead);
> +
> +    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
> +    Status = FlashMmCommunicate (
> +               mCommBuffer,
> +               &Size
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "Flash Read: Device error %llx\n", MmSpiNorRes->Status));
> +      return EFI_DEVICE_ERROR;
> +    }
> +
> +    ConvertPhysicaltoVirtual (Byte + Count, NumRead);
> +    Remain -= NumRead;
> +    Count += NumRead;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
@ 2021-06-04 23:37   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:37 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:02 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> The idea came from DeviceManagerUiLib that all related menu settings can be
> placed under a common entry. This change intends to provide a central point
> for all platform menus by creating a Platform Manager entry located under
> Device Manager entry of UiApp.
> 
> New classuuid called gPlatformManagerFormsetGuid was introduced for
> platform menus which want to be reached through this Platform Manager.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                             |  19 ++
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                             |   1 +
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf   |  47 +++
>  Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h                |  31 ++
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h          |  51 +++
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h       |  28 ++
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c          | 354 ++++++++++++++++++++
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni |  21 ++
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni   |  13 +
>  Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr     |  29 ++
>  10 files changed, 594 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> index 26e020715290..a72205aa5316 100755
> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> @@ -22,12 +22,31 @@ [Defines]
>  #
>  ################################################################################
>  [Includes.common]
> +  Include                        # Root include for the package
>  
>  [LibraryClasses]
>  
>  [Guids]
>    gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
>  
> +  #
> +  # Platform Manager formset UUID
> +  #
> +  ## Include/Guid/PlatformManagerHii.h
> +  gPlatformManagerFormsetGuid  = { 0x83ABD546, 0x7AD9, 0x4DE7, { 0xBD, 0x52, 0x12, 0x23, 0xF6, 0xE8, 0xFD, 0x4B } }
> +
> +  #
> +  # Platform Manager entry UUID
> +  #
> +  ## Include/Guid/PlatformManagerHii.h
> +  gPlatformManagerEntryEventGuid = { 0x28A4731E, 0x14A9, 0x488A, { 0xA8, 0x19, 0xFF, 0x27, 0x80, 0x6E, 0xDB, 0x0E } }
> +
> +  #
> +  # Platform Manager exit UUID
> +  #
> +  ## Include/Guid/PlatformManagerHii.h
> +  gPlatformManagerExitEventGuid  = { 0xE8887242, 0x4EFF, 0x4323, { 0x81, 0xF4, 0xC9, 0x5F, 0xD5, 0x8D, 0x80, 0xD5 } }
> +
>  [Ppis]
>  
>  [PcdsFixedAtBuild]
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 65973569a41d..3c47099b8edc 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -649,6 +649,7 @@ [Components.common]
>    MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>    MdeModulePkg/Application/UiApp/UiApp.inf {
>      <LibraryClasses>
> +      NULL|Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
>        NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
>        NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
>        NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
> new file mode 100644
> index 000000000000..1cc5788bcebb
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.inf
> @@ -0,0 +1,47 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PlatformManagerUiLib
> +  MODULE_UNI_FILE                = PlatformManagerUiLib.uni
> +  FILE_GUID                      = 9264993E-2E15-478A-8928-14573E34C606
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = NULL|DXE_DRIVER UEFI_APPLICATION
> +  CONSTRUCTOR                    = PlatformManagerUiLibConstructor
> +  DESTRUCTOR                     = PlatformManagerUiLibDestructor
> +
> +[Sources]
> +  PlatformManager.h
> +  PlatformManagerVfr.Vfr
> +  PlatformManagerStrings.uni
> +  PlatformManager.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  DevicePathLib
> +  BaseLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  BaseMemoryLib
> +  DebugLib
> +  HiiLib
> +  UefiLib
> +  UefiHiiServicesLib
> +
> +[Guids]
> +  gPlatformManagerFormsetGuid                   ## CONSUMES ## GUID (Indicate the formset class guid to be displayed)
> +  gEfiIfrTianoGuid                              ## CONSUMES ## GUID (Extended IFR Guid Opcode)
> +  gEfiIfrFrontPageGuid                          ## CONSUMES ## GUID (Indicate the formset in this library need to display in which page)
> +  gPlatformManagerEntryEventGuid                ## CONSUMES ## GUID (Indicate enter PlatformManager)
> +  gPlatformManagerExitEventGuid                 ## CONSUMES ## GUID (Indicate exit PlatformManager)
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
> new file mode 100644
> index 000000000000..ee3ca13ddeb1
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Guid/PlatformManagerHii.h
> @@ -0,0 +1,31 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PLATFORM_MANAGER_HII_GUID_H_
> +#define PLATFORM_MANAGER_HII_GUID_H_
> +
> +#define PLATFORM_MANAGER_FORMSET_GUID  \
> +  { \
> +  0x83ABD546, 0x7AD9, 0x4DE7, { 0xBD, 0x52, 0x12, 0x23, 0xF6, 0xE8, 0xFD, 0x4B } \
> +  }
> +
> +#define PLATFORM_MANAGER_ENTRY_EVENT_GUID  \
> +  { \
> +  0x28A4731E, 0x14A9, 0x488A, { 0xA8, 0x19, 0xFF, 0x27, 0x80, 0x6E, 0xDB, 0x0E } \
> +  }
> +
> +#define PLATFORM_MANAGER_EXIT_EVENT_GUID  \
> +  { \
> +  0xE8887242, 0x4EFF, 0x4323, { 0x81, 0xF4, 0xC9, 0x5F, 0xD5, 0x8D, 0x80, 0xD5 } \
> +  }
> +
> +extern EFI_GUID gPlatformManagerFormsetGuid;
> +extern EFI_GUID gPlatformManagerEntryEventGuid;
> +extern EFI_GUID gPlatformManagerExitEventGuid;
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
> new file mode 100644
> index 000000000000..49157e0cea47
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.h
> @@ -0,0 +1,51 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PLATFORM_MANAGER_H_
> +#define PLATFORM_MANAGER_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PlatformManagerHii.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiHiiServicesLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include "PlatformManagerVfr.h"
> +
> +//
> +// These are the VFR compiler generated data representing our VFR data.
> +//
> +extern UINT8 PlatformManagerVfrBin[];
> +extern UINT8 PlatformManagerUiLibStrings[];
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +typedef struct {
> +  ///
> +  /// Platform Manager HII relative handles
> +  ///
> +  EFI_HII_HANDLE HiiHandle;
> +  EFI_HANDLE     DriverHandle;
> +
> +} PLATFORM_MANAGER_CALLBACK_DATA;
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
> new file mode 100644
> index 000000000000..205907d3777a
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.h
> @@ -0,0 +1,28 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PLATFORM_MANAGER_VFR_H_
> +#define PLATFORM_MANAGER_VFR_H_
> +
> +#define FORMSET_GUID \
> +  { \
> +  0x6E7233C5, 0x2B79, 0x4383, { 0x81, 0x46, 0xD8, 0x6A, 0x9F, 0x0A, 0x0B, 0x99 } \
> +  }
> +
> +//
> +// These are defined as the same with vfr file
> +//
> +#define LABEL_FORM_ID_OFFSET                 0x0100
> +#define ENTRY_KEY_OFFSET                     0x4000
> +
> +#define PLATFORM_MANAGER_FORM_ID             0x1000
> +
> +#define LABEL_ENTRY_LIST                     0x1100
> +#define LABEL_END                            0xffff
> +
> +#endif /* PLATFORM_MANAGER_VFR_H_ */
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
> new file mode 100644
> index 000000000000..1872aa80ed18
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManager.c
> @@ -0,0 +1,354 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformManager.h"
> +
> +PLATFORM_MANAGER_CALLBACK_DATA gPlatformManagerPrivate = {
> +  NULL,
> +  NULL
> +};
> +
> +EFI_GUID mPlatformManagerGuid = FORMSET_GUID;
> +
> +HII_VENDOR_DEVICE_PATH mPlatformManagerHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    //
> +    // {FC587265-0750-44D1-B68D-D1DDD3F29B0B}
> +    //
> +    { 0xFC587265, 0x0750, 0x44D1, {0xB6, 0x8D, 0xD1, 0xDD, 0xD3, 0xF2, 0x9B, 0x0B} }
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +/**
> +  Extract device path for given HII handle and class guid.
> +
> +  @param Handle          The HII handle.
> +
> +  @retval  NULL          Fail to get the device path string.
> +  @return  PathString    Get the device path string.
> +
> +**/
> +CHAR16 *
> +PmExtractDevicePathFromHiiHandle (
> +  IN EFI_HII_HANDLE Handle
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_HANDLE DriverHandle;
> +
> +  ASSERT (Handle != NULL);
> +
> +  if (Handle == NULL) {
> +    return NULL;
> +  }
> +
> +  Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
> +  if (EFI_ERROR (Status)) {
> +    return NULL;
> +  }
> +  //
> +  // Get device path string.
> +  //
> +  return ConvertDevicePathToText (DevicePathFromHandle (DriverHandle), FALSE, FALSE);
> +}
> +
> +/**
> +  Dynamic create Hii information for Platform Manager.
> +
> +  @param   NextShowFormId     The FormId which need to be show.
> +
> +**/
> +VOID
> +CreatePlatformManagerForm (
> +  IN EFI_FORM_ID NextShowFormId
> +  )
> +{
> +  UINTN              Index;
> +  EFI_STRING         String;
> +  EFI_STRING_ID      Token;
> +  EFI_STRING_ID      TokenHelp;
> +  EFI_HII_HANDLE     *HiiHandles;
> +  EFI_HII_HANDLE     HiiHandle;
> +  EFI_GUID           FormSetGuid;
> +  VOID               *StartOpCodeHandle;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +  CHAR16             *DevicePathStr;
> +  EFI_STRING_ID      DevicePathId;
> +  EFI_IFR_FORM_SET   *Buffer;
> +  UINTN              BufferSize;
> +  UINT8              ClassGuidNum;
> +  EFI_GUID           *ClassGuid;
> +  UINTN              TempSize;
> +  UINT8              *Ptr;
> +  EFI_STATUS         Status;
> +
> +  TempSize = 0;
> +  BufferSize = 0;
> +  Buffer = NULL;
> +
> +  HiiHandle = gPlatformManagerPrivate.HiiHandle;
> +
> +  //
> +  // Allocate space for creation of UpdateData Buffer
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  ASSERT (StartLabel != NULL);
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  //
> +  // According to the next show Form id(mNextShowFormId) to decide which form need to update.
> +  //
> +  StartLabel->Number       = (UINT16)(LABEL_FORM_ID_OFFSET + NextShowFormId);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  ASSERT (EndLabel != NULL);
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  //
> +  // Get all the Hii handles
> +  //
> +  HiiHandles = HiiGetHiiHandles (NULL);
> +  ASSERT (HiiHandles != NULL);
> +
> +  //
> +  // Search for formset of each class type
> +  //
> +  for (Index = 0; HiiHandles[Index] != NULL; Index++) {
> +    Status = HiiGetFormSetFromHiiHandle (HiiHandles[Index], &Buffer,&BufferSize);
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +
> +    Ptr = (UINT8 *)Buffer;
> +
> +    while(TempSize < BufferSize) {
> +      TempSize += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
> +      if (((EFI_IFR_OP_HEADER *)Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)) {
> +        Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
> +        continue;
> +      }
> +
> +      ClassGuidNum = (UINT8)(((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
> +      ClassGuid = (EFI_GUID *)(VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
> +      while (ClassGuidNum-- > 0) {
> +        if (CompareGuid (&gPlatformManagerFormsetGuid, ClassGuid)== 0) {
> +          ClassGuid++;
> +          continue;
> +        }
> +
> +        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);
> +        if (String == NULL) {
> +          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
> +          ASSERT (String != NULL);
> +        }
> +        Token = HiiSetString (HiiHandle, 0, String, NULL);
> +        FreePool (String);
> +
> +        String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);
> +        if (String == NULL) {
> +          String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
> +          ASSERT (String != NULL);
> +        }
> +        TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
> +        FreePool (String);
> +
> +        CopyMem (&FormSetGuid, &((EFI_IFR_FORM_SET *)Ptr)->Guid, sizeof (EFI_GUID));
> +
> +        if (NextShowFormId == PLATFORM_MANAGER_FORM_ID) {
> +          DevicePathStr = PmExtractDevicePathFromHiiHandle (HiiHandles[Index]);
> +          DevicePathId  = 0;
> +          if (DevicePathStr != NULL) {
> +            DevicePathId =  HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
> +            FreePool (DevicePathStr);
> +          }
> +
> +          HiiCreateGotoExOpCode (
> +            StartOpCodeHandle,
> +            0,
> +            Token,
> +            TokenHelp,
> +            0,
> +            (EFI_QUESTION_ID)(Index + ENTRY_KEY_OFFSET),
> +            0,
> +            &FormSetGuid,
> +            DevicePathId
> +            );
> +        }
> +        break;
> +      }
> +
> +      Ptr += ((EFI_IFR_OP_HEADER *)Ptr)->Length;
> +    }
> +
> +    FreePool (Buffer);
> +    Buffer = NULL;
> +    TempSize = 0;
> +    BufferSize = 0;
> +  }
> +
> +  HiiUpdateForm (
> +    HiiHandle,
> +    &mPlatformManagerGuid,
> +    NextShowFormId,
> +    StartOpCodeHandle,
> +    EndOpCodeHandle
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +  FreePool (HiiHandles);
> +}
> +
> +/**
> +  Install Boot Manager Menu driver.
> +
> +  @param ImageHandle     The image handle.
> +  @param SystemTable     The system table.
> +
> +  @retval  EFI_SUCEESS  Install Boot manager menu success.
> +  @retval  Other        Return error status.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformManagerUiLibConstructor (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  PlatformUiEntryEvent;
> +
> +  gPlatformManagerPrivate.DriverHandle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &gPlatformManagerPrivate.DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mPlatformManagerHiiVendorDevicePath,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Publish our HII data.
> +  //
> +  gPlatformManagerPrivate.HiiHandle = HiiAddPackages (
> +                                        &mPlatformManagerGuid,
> +                                        gPlatformManagerPrivate.DriverHandle,
> +                                        PlatformManagerVfrBin,
> +                                        PlatformManagerUiLibStrings,
> +                                        NULL
> +                                        );
> +  if (gPlatformManagerPrivate.HiiHandle != NULL) {
> +    //
> +    // Update platform manager page
> +    //
> +    CreatePlatformManagerForm (PLATFORM_MANAGER_FORM_ID);
> +  } else {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to add Hii package\n", __FUNCTION__));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Signal Entry event
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  EfiEventEmptyFunction,
> +                  NULL,
> +                  &gPlatformManagerEntryEventGuid,
> +                  &PlatformUiEntryEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  gBS->SignalEvent (PlatformUiEntryEvent);
> +  gBS->CloseEvent (PlatformUiEntryEvent);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Unloads the application and its installed protocol.
> +
> +  @param  ImageHandle     Handle that identifies the image to be unloaded.
> +  @param  SystemTable     The system table.
> +
> +  @retval EFI_SUCCESS           The image has been unloaded.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PlatformManagerUiLibDestructor (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  PlatformUiExitEvent;
> +
> +  Status = gBS->UninstallMultipleProtocolInterfaces (
> +                  gPlatformManagerPrivate.DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mPlatformManagerHiiVendorDevicePath,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  HiiRemovePackages (gPlatformManagerPrivate.HiiHandle);
> +
> +  // Signal Exit event
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  EfiEventEmptyFunction,
> +                  NULL,
> +                  &gPlatformManagerExitEventGuid,
> +                  &PlatformUiExitEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +  gBS->SignalEvent (PlatformUiExitEvent);
> +  gBS->CloseEvent (PlatformUiExitEvent);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
> new file mode 100644
> index 000000000000..3bb39413bc4b
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerStrings.uni
> @@ -0,0 +1,21 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +/=#
> +
> +#langdef   en-US "English"
> +
> +#string STR_EDKII_MENU_TITLE           #language en-US  "Platform Manager"
> +#string STR_EDKII_MENU_HELP            #language en-US  "This selection will take you to the Platform Manager"
> +#string STR_PLATFORM_LIST              #language en-US  "Platform Configuration"
> +#string STR_MISSING_STRING             #language en-US  "Missing String"
> +#string STR_EMPTY_STRING               #language en-US  ""
> +#string STR_EXIT_STRING                #language en-US  "Press ESC to exit."
> +//
> +// Ensure that this is the last string.  We are using it programmatically
> +// to do string token re-usage settings for the Device Manager since we are
> +// constantly recreating this page based on HII population.
> +////
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
> new file mode 100644
> index 000000000000..217a7e999dab
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerUiLib.uni
> @@ -0,0 +1,13 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#string STR_MODULE_ABSTRACT
> +#language en-US
> +"Platform Manager Library used by UiApp"
> +
> +#string STR_MODULE_DESCRIPTION
> +#language en-US
> +"Platform Manager Library used by UiApp"
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
> new file mode 100644
> index 000000000000..bfda75319416
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/PlatformUiLib/PlatformManagerVfr.Vfr
> @@ -0,0 +1,29 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/HiiPlatformSetupFormset.h>
> +#include "PlatformManagerVfr.h"
> +
> +formset
> +  guid      = FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_EDKII_MENU_TITLE),
> +  help      = STRING_TOKEN(STR_EDKII_MENU_HELP),
> +  classguid = EFI_HII_PLATFORM_SETUP_FORMSET_GUID,
> +
> +  form formid = PLATFORM_MANAGER_FORM_ID,
> +    title  = STRING_TOKEN(STR_EDKII_MENU_TITLE);
> +    subtitle text = STRING_TOKEN(STR_PLATFORM_LIST);
> +
> +    label LABEL_ENTRY_LIST;
> +    label LABEL_END;
> +
> +    subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
> +    subtitle text = STRING_TOKEN(STR_EMPTY_STRING);
> +    subtitle text = STRING_TOKEN(STR_EXIT_STRING);
> +  endform;
> +endformset;
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
@ 2021-06-04 23:44   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:44 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:03 +0700, Nhi Pham wrote:
> The AcpiPccLib provides functions to allocate and get the physical
> address of PCC shared memory.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Again - on your head be it to start symbol names with Acpi and hope
for no clashes. But given that:
Reviewed-by: Leif Lindholm <leif@nuviainc.com>


> ---
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                |   2 +
>  Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf |  41 ++++
>  Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h        | 166 ++++++++++++++
>  Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c   | 241 ++++++++++++++++++++
>  4 files changed, 450 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> index a72205aa5316..8193ff617600 100755
> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> @@ -25,6 +25,8 @@ [Includes.common]
>    Include                        # Root include for the package
>  
>  [LibraryClasses]
> +  ##  @libraryclass  Provides functions to create the ACPI PCCT Table which which advertises PCC mailbox channel information.
> +  AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
>  
>  [Guids]
>    gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
> new file mode 100755
> index 000000000000..9f38e1e77145
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                   = 0x0001001B
> +  BASE_NAME                     = AcpiPccLib
> +  FILE_GUID                     = 790519F0-F344-11E3-AC10-0800200C9A66
> +  MODULE_TYPE                   = BASE
> +  VERSION_STRING                = 1.0
> +  LIBRARY_CLASS                 = AcpiPccLib
> +
> +[Sources.common]
> +  AcpiPccLib.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  IoLib
> +  MailboxInterfaceLib
> +  PrintLib
> +  SystemFirmwareInterfaceLib
> +  TimerLib
> +  UefiBootServicesTableLib
> +
> +[Pcd]
> +  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
> +  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
> new file mode 100644
> index 000000000000..d8ae48e7612a
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
> @@ -0,0 +1,166 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_PCC_LIB_H_
> +#define ACPI_PCC_LIB_H_
> +
> +#include <Library/MailboxInterfaceLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +
> +// Send a message with dummy payload is to advertise the shared memory address
> +#define DB_PCC_PAYLOAD_DUMMY         0x0F000000
> +
> +#define DB_PCC_MSG_PAYLOAD_SIZE      12 // Number of Bytes
> +
> +//
> +// ACPI Platform Communication Channel (PCC)
> +//
> +#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE  0x50434300 // "PCC"
> +#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE       0x4000     // Number of Bytes
> +
> +//
> +// Reserved Doorbell Mask
> +// Bit 0 --> 31 correspond to Doorbell 0 --> 31
> +//
> +// List of reserved Doorbells
> +//  1. Doorbell 4: PCIe Hot-plug
> +//
> +#define ACPI_PCC_AVAILABLE_DOORBELL_MASK        0xEFFFEFFF
> +#define ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS   1
> +
> +// Supported doorbells in the platform
> +#define ACPI_PCC_MAX_DOORBELL              (NUMBER_OF_DOORBELLS_PER_SOCKET * PLATFORM_CPU_MAX_SOCKET)
> +
> +// Valid doorbells for use
> +#define ACPI_PCC_MAX_SUBPACE_PER_SOCKET    (NUMBER_OF_DOORBELLS_PER_SOCKET - ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS)
> +#define ACPI_PCC_MAX_SUBPACE               (ACPI_PCC_MAX_SUBPACE_PER_SOCKET * PLATFORM_CPU_MAX_SOCKET)
> +
> +#define ACPI_PCC_NOMINAL_LATENCY_US                1000 // us
> +#define ACPI_PCC_MAX_PERIODIC_ACCESS_RATE          0    // no limitation
> +#define ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US        0
> +
> +// Polling interval for PCC Command Complete
> +#define ACPI_PCC_COMMAND_POLL_INTERVAL_US          10
> +
> +#define ACPI_PCC_COMMAND_POLL_COUNT  (ACPI_PCC_NOMINAL_LATENCY_US / ACPI_PCC_COMMAND_POLL_INTERVAL_US)
> +
> +//
> +// PCC subspace 2 (PMpro Doorbell Channel 2) is used for ACPI CPPC
> +//
> +#define ACPI_PCC_CPPC_DOORBELL_ID                  (PMproDoorbellChannel2)
> +
> +#define ACPI_PCC_CPPC_NOMINAL_LATENCY_US           100
> +#define ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US   110
> +
> +
> +/**
> +  Allocate memory pages for the PCC shared memory region.
> +
> +  @param  PccSharedMemoryPtr     Pointer to the shared memory address.
> +  @param  NumberOfSubspaces      Number of subspaces slot in the shared memory region.
> +
> +  @retval EFI_SUCCESS            Send the message successfully.
> +  @retval EFI_INVALID_PARAMETER  TheNumberOfSubspaces is out of the valid range.
> +  @retval Otherwise              Return errors from call to gBS->AllocatePages().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccAllocateSharedMemory (
> +  OUT EFI_PHYSICAL_ADDRESS *PccSharedMemPointer,
> +  IN  UINT16               NumberOfSubspaces
> +  );
> +
> +/**
> +  Free the whole shared memory region that is allocated by
> +  the AcpiPccAllocateSharedMemory() function.
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiPccFreeSharedMemory (
> +  VOID
> +  );
> +
> +/**
> +  Send a PCC message to the platform (SMpro/PMpro).
> +
> +  @param  Socket    The Socket ID.
> +  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
> +  @param  Subspace  The Subspace index in the shared memory region.
> +
> +  @retval EFI_SUCCESS            Send the message successfully.
> +  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
> +                                 The data buffer is NULL or the size of data buffer is zero.
> +  @retval EFI_NOT_READY          The shared memory region is NULL.
> +  @retval EFI_TIMEOUT            Timeout occurred when polling the PCC Command Complete bit.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccSendMessage (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell,
> +  IN UINT16 Subspace,
> +  IN VOID   *DataBuffer,
> +  IN UINT32 DataSize
> +  );
> +
> +/**
> +  Initialize the shared memory in the SMpro/PMpro Doorbell handler.
> +  This function is to advertise the shared memory region address to the platform (SMpro/PMpro).
> +
> +  @param  Socket    The Socket ID.
> +  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
> +  @param  Subspace  The Subspace index in the shared memory region.
> +
> +  @retval EFI_SUCCESS            Initialize successfully.
> +  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccInitSharedMemory (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell,
> +  IN UINT16 Subspace
> +  );
> +
> +/**
> +  Unmask the Doorbell interrupt.
> +
> +  @param  Socket    The Socket ID.
> +  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
> +
> +  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
> +  @retval EFI_INVALID_PARAMETER  The Socket or Doorbell is out of the valid range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccUnmaskDoorbellInterrupt (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell
> +  );
> +
> +/**
> +  Check whether the Doorbell is reserved or not.
> +
> +  @param  Doorbell   The Doorbell index from supported Doorbells.
> +
> +  @retval TRUE         The Doorbell is reserved for private use or invalid.
> +  @retval FALSE        The Doorbell is available.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AcpiPccIsDoorbellReserved (
> +  IN UINT16 Doorbell
> +  );
> +
> +#endif /* ACPI_PCC_LIB_H_ */
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
> new file mode 100644
> index 000000000000..48e0b9e876ef
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c
> @@ -0,0 +1,241 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/AcpiPccLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Platform/Ac01.h>
> +
> +STATIC EFI_PHYSICAL_ADDRESS mPccSharedMemoryAddress;
> +STATIC UINTN                mPccSharedMemorySize;
> +
> +EFI_STATUS
> +AcpiPccGetSharedMemoryAddress (
> +  IN  UINT8  Socket,
> +  IN  UINT16 Subspace,
> +  OUT VOID   **SharedMemoryAddress
> +  )
> +{
> +  if (Socket >= PLATFORM_CPU_MAX_SOCKET
> +      || Subspace >= ACPI_PCC_MAX_SUBPACE)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (mPccSharedMemoryAddress == 0) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  *SharedMemoryAddress = (VOID *)(mPccSharedMemoryAddress + ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Allocate memory pages for the PCC shared memory region.
> +
> +  @param  PccSharedMemoryPtr     Pointer to the shared memory address.
> +  @param  NumberOfSubspaces      Number of subspaces slot in the shared memory region.
> +
> +  @retval EFI_SUCCESS            Send the message successfully.
> +  @retval EFI_INVALID_PARAMETER  TheNumberOfSubspaces is out of the valid range.
> +  @retval Otherwise              Return errors from call to gBS->AllocatePages().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccAllocateSharedMemory (
> +  OUT EFI_PHYSICAL_ADDRESS *PccSharedMemoryPtr,
> +  IN  UINT16               NumberOfSubspaces
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (NumberOfSubspaces > ACPI_PCC_MAX_SUBPACE) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  mPccSharedMemorySize = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * NumberOfSubspaces;
> +
> +  Status = gBS->AllocatePages (
> +                  AllocateAnyPages,
> +                  EfiRuntimeServicesData,
> +                  EFI_SIZE_TO_PAGES (mPccSharedMemorySize),
> +                  &mPccSharedMemoryAddress
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to allocate PCC shared memory\n"));
> +    mPccSharedMemorySize = 0;
> +    return Status;
> +  }
> +
> +  *PccSharedMemoryPtr = mPccSharedMemoryAddress;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Free the whole shared memory region that is allocated by
> +  the AcpiPccAllocateSharedMemory() function.
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiPccFreeSharedMemory (
> +  VOID
> +  )
> +{
> +  if (mPccSharedMemoryAddress != 0 && mPccSharedMemorySize != 0)
> +  {
> +    gBS->FreePages (
> +           mPccSharedMemoryAddress,
> +           EFI_SIZE_TO_PAGES (mPccSharedMemorySize)
> +           );
> +
> +    mPccSharedMemoryAddress = 0;
> +  }
> +}
> +
> +/**
> +  Initialize the shared memory in the SMpro/PMpro Doorbell handler.
> +  This function is to advertise the shared memory region address to the platform (SMpro/PMpro).
> +
> +  @param  Socket    The Socket ID.
> +  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
> +  @param  Subspace  The Subspace index in the shared memory region.
> +
> +  @retval EFI_SUCCESS            Initialize successfully.
> +  @retval EFI_INVALID_PARAMETER  The Socket, Doorbell or Subspace is out of the valid range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccInitSharedMemory (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell,
> +  IN UINT16 Subspace
> +  )
> +{
> +  EFI_STATUS                                            Status;
> +  EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER *PcctSharedMemoryRegion;
> +  UINT32                                                CommunicationData;
> +  UINTN                                                 Timeout;
> +
> +  if (Socket >= PLATFORM_CPU_MAX_SOCKET
> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
> +      || Subspace >= ACPI_PCC_MAX_SUBPACE)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = AcpiPccGetSharedMemoryAddress (Socket, Subspace, (VOID **)&PcctSharedMemoryRegion);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Zero shared memory region for each PCC subspace
> +  //
> +  SetMem (
> +    (VOID *)PcctSharedMemoryRegion,
> +    sizeof (EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER) + DB_PCC_MSG_PAYLOAD_SIZE,
> +    0
> +    );
> +
> +  // Advertise shared memory address to Platform (SMpro/PMpro)
> +  // by ringing the doorbell with dummy PCC message
> +  //
> +  CommunicationData = DB_PCC_PAYLOAD_DUMMY;
> +
> +  //
> +  // Write Data into Communication Space Region
> +  //
> +  CopyMem ((VOID *)(PcctSharedMemoryRegion + 1), &CommunicationData, sizeof (CommunicationData));
> +
> +  PcctSharedMemoryRegion->Status.CommandComplete = 0;
> +  PcctSharedMemoryRegion->Signature = ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE | Subspace;
> +
> +  Status = MailboxMsgSetPccSharedMem (Socket, Doorbell, TRUE, (UINT64)PcctSharedMemoryRegion);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Failed to send mailbox message!\n", __FUNCTION__));
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  //
> +  // Polling CMD_COMPLETE bit
> +  //
> +  Timeout = ACPI_PCC_COMMAND_POLL_COUNT;
> +  while (PcctSharedMemoryRegion->Status.CommandComplete != 1) {
> +    if (--Timeout <= 0) {
> +      DEBUG ((DEBUG_ERROR, "%a - Timeout occurred when polling the PCC Status Complete\n", __FUNCTION__));
> +      return EFI_TIMEOUT;
> +    }
> +    MicroSecondDelay (ACPI_PCC_COMMAND_POLL_INTERVAL_US);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Unmask the Doorbell interrupt.
> +
> +  @param  Socket    The Socket ID.
> +  @param  Doorbell  The Doorbell index from supported Doorbells per socket.
> +
> +  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
> +  @retval EFI_INVALID_PARAMETER  The Socket or Doorbell is out of the valid range.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiPccUnmaskDoorbellInterrupt (
> +  IN UINT8  Socket,
> +  IN UINT16 Doorbell
> +  )
> +{
> +  return MailboxUnmaskInterrupt (Socket, Doorbell);
> +}
> +
> +/**
> +  Check whether the Doorbell is reserved or not.
> +
> +  @param  Doorbell   The Doorbell index from supported Doorbells.
> +
> +  @retval TRUE         The Doorbell is reserved for private use or invalid.
> +  @retval FALSE        The Doorbell is available.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +AcpiPccIsDoorbellReserved (
> +  IN UINT16 Doorbell
> +  )
> +{
> +  if (Doorbell >= ACPI_PCC_MAX_DOORBELL) {
> +    ASSERT (FALSE);
> +    return TRUE;
> +  }
> +
> +  if (((1 << Doorbell) & ACPI_PCC_AVAILABLE_DOORBELL_MASK) == 0) {
> +    //
> +    // The doorbell is reserved for private use.
> +    //
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
@ 2021-06-04 23:47   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:47 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:04 +0700, Nhi Pham wrote:
> The AcpiHelperLib provides functions to update the ACPI DSDT table after
> this table is installed.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                      |   3 +
>  Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf |  33 +++
>  Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h           | 109 +++++++++
>  Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c   | 246 ++++++++++++++++++++
>  4 files changed, 391 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> index 8193ff617600..0ac075047276 100755
> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> @@ -28,6 +28,9 @@ [LibraryClasses]
>    ##  @libraryclass  Provides functions to create the ACPI PCCT Table which which advertises PCC mailbox channel information.
>    AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h
>  
> +  ##  @libraryclass  Provides helper functions to update ACPI DSDT Table.
> +  AcpiHelperLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
> +
>  [Guids]
>    gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, 0xc3, 0x91, 0x35, 0xbf, 0xdf } }
>  
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
> new file mode 100755
> index 000000000000..df26a2810bd3
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
> @@ -0,0 +1,33 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = AcpiHelperLib
> +  FILE_GUID                      = E4F89216-E722-11E6-BF01-FE55135034F3
> +  MODULE_TYPE                    = BASE
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = AcpiHelperLib
> +
> +[Sources]
> +  AcpiHelperLib.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +
> +[Protocols]
> +  gEfiAcpiSdtProtocolGuid         ## COMSUMED
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
> new file mode 100644
> index 000000000000..f98118a0f6a2
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h
> @@ -0,0 +1,109 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPIHELPERLIB_H_
> +#define ACPIHELPERLIB_H_
> +
> +#include <Uefi.h>
> +
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +#define MAX_ACPI_NODE_PATH    256
> +
> +
> +typedef struct {
> +  EFI_ACPI_SDT_HEADER    *Table;
> +  EFI_ACPI_TABLE_VERSION TableVersion;
> +  UINTN                  TableKey;
> +} ACPI_TABLE_DESCRIPTOR;
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in]  Buffer          Pointer to buffer to checksum
> +  @param[in]  Size            Number of bytes to checksum
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiTableChecksum (
> +  IN UINT8 *Buffer,
> +  IN UINTN Size
> +  );

This should be a central function. If we have spectacularly failed up
until this point, please do this separately.

> +
> +/**
> +  This function calculates and updates the ACPI DSDT checksum.
> +
> +  @param[in]  AcpiTableProtocol          Pointer to ACPI table protocol
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiDSDTUpdateChecksum (
> +  IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol
> +  );
> +
> +/**
> +  This function update the _STA value of a ACPI DSDT node.
> +
> +  @param[in]  AsciiNodePath          Pointer to the path of the node.
> +  @param[in]  NodeStatus             The status value needed to be updated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiDSDTSetNodeStatusValue (
> +  IN CHAR8 *AsciiNodePath,
> +  IN CHAR8 NodeStatus
> +  );
> +
> +/**
> +  This function return the handle of the ACPI DSDT table.
> +
> +  @param[in]   AcpiTableProtocol          Pointer to ACPI table protocol.
> +  @param[out]  TableHandle                Pointer to table handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiOpenDSDT (
> +  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
> +  OUT EFI_ACPI_HANDLE       *TableHandle
> +  );
> +
> +/**
> +  This function return the ACPI table matching a signature.
> +
> +  @param[in]   TableDescriptor        Pointer to ACPI table descriptor.
> +  @param[in]   TableSignature         ACPI table signature.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGetTable (
> +  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol,
> +  IN  UINT32                TableSignature,
> +  OUT ACPI_TABLE_DESCRIPTOR *TableDescriptor
> +  );
> +
> +/**
> +  Check whether the ACPI table is installed or not.
> +
> +  @param[in]    AcpiTableSignature        ACPI table signature.
> +
> +  @retval       TRUE     Already installed.
> +  @retval       FALSE    Not installed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsAcpiInstalled (

OK, this has officially gone too far.
Please add proper vendor prefixes to anything you aren't actually
upstreaming to MdePkg. The Acpi/ACPI prefixes belong to actual
industry standards.

/
    Leif

> +  IN UINT32 AcpiTableSignature
> +  );
> +
> +#endif /* ACPIHELPERLIB_H_ */
> diff --git a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
> new file mode 100644
> index 000000000000..4a85dd5dc8c5
> --- /dev/null
> +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c
> @@ -0,0 +1,246 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <IndustryStandard/AcpiAml.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +#include <Protocol/AcpiTable.h>
> +
> +#define DSDT_SIGNATURE                  0x54445344
> +#define FADT_SIGNATURE                  0x50434146
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in]  Buffer          Pointer to buffer to checksum
> +  @param[in]  Size            Number of bytes to checksum
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiTableChecksum (
> +  IN UINT8 *Buffer,
> +  IN UINTN Size
> +  )
> +{
> +  UINTN ChecksumOffset;
> +
> +  ASSERT (Buffer != NULL);
> +
> +  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);
> +
> +  /*
> +   * Set checksum to 0 first.
> +   */
> +  Buffer[ChecksumOffset] = 0;
> +
> +  /*
> +   * Update checksum value.
> +   */
> +  Buffer[ChecksumOffset] = 0 - CalculateSum8 (Buffer, Size);
> +}
> +
> +/**
> +  This function calculates and updates the ACPI DSDT checksum.
> +
> +  @param[in]  AcpiTableProtocol          Pointer to ACPI table protocol
> +
> +**/
> +VOID
> +EFIAPI
> +AcpiDSDTUpdateChecksum (
> +  IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol
> +  )
> +{
> +  EFI_STATUS                                Status = EFI_SUCCESS;
> +  EFI_ACPI_SDT_HEADER                       *DsdtHdr = NULL;
> +  ACPI_TABLE_DESCRIPTOR                     TableDescriptor;
> +  EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPtr = NULL;
> +
> +  ASSERT (AcpiTableProtocol != NULL);
> +
> +  Status = AcpiGetTable (AcpiTableProtocol, FADT_SIGNATURE, &TableDescriptor);
> +  if (EFI_ERROR (Status) || TableDescriptor.Table == NULL) {
> +    return;
> +  }
> +
> +  FadtPtr = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *)TableDescriptor.Table;
> +
> +  if (FadtPtr->Dsdt) {
> +    DsdtHdr = (EFI_ACPI_SDT_HEADER *)(UINT64)FadtPtr->Dsdt;
> +  } else if (FadtPtr->XDsdt) {
> +    DsdtHdr = (EFI_ACPI_SDT_HEADER *)FadtPtr->XDsdt;
> +  }
> +
> +  if (DsdtHdr != NULL) {
> +    AcpiTableChecksum ((UINT8 *)DsdtHdr, DsdtHdr->Length);
> +  }
> +}
> +
> +/**
> +  This function return the handle of the ACPI DSDT table.
> +
> +  @param[in]   AcpiTableProtocol          Pointer to ACPI table protocol.
> +  @param[out]  TableHandle                Pointer to table handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiOpenDSDT (
> +  IN  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol,
> +  OUT EFI_ACPI_HANDLE       *TableHandle
> +  )
> +{
> +  EFI_STATUS            Status = EFI_SUCCESS;
> +  ACPI_TABLE_DESCRIPTOR TableDescriptor;
> +
> +  Status = AcpiGetTable (AcpiTableProtocol, DSDT_SIGNATURE, &TableDescriptor);
> +  if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) {
> +    return AcpiTableProtocol->OpenSdt (TableDescriptor.TableKey, TableHandle);
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiDSDTSetNodeStatusValue (
> +  IN CHAR8 *AsciiNodePath,
> +  IN CHAR8 NodeStatus
> +  )
> +{
> +  EFI_STATUS            Status = EFI_SUCCESS;
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
> +  EFI_ACPI_HANDLE       TableHandle;
> +  EFI_ACPI_HANDLE       ChildHandle;
> +  EFI_ACPI_DATA_TYPE    DataType;
> +  CHAR8                 *Buffer;
> +  UINTN                 DataSize;
> +
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
> +    return Status;
> +  }
> +
> +  /* Open DSDT Table */
> +  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = AcpiTableProtocol->FindPath (TableHandle, AsciiNodePath, &ChildHandle);
> +  if (EFI_ERROR (Status)) {
> +    /* Close DSDT Table */
> +    AcpiTableProtocol->Close (TableHandle);
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = AcpiTableProtocol->GetOption (ChildHandle, 2, &DataType, (VOID *)&Buffer, &DataSize);
> +  if (Status == EFI_SUCCESS && Buffer[2] == AML_BYTE_PREFIX) {
> +    /*
> +     * Only patch when the initial value is byte object.
> +     */
> +    Buffer[3] = NodeStatus;
> +  }
> +
> +  /* Close DSDT Table */
> +  AcpiTableProtocol->Close (TableHandle);
> +
> +  /* Update DSDT Checksum */
> +  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function return the ACPI table matching a signature.
> +
> +  @param[in]   AcpiTableSdtProtocol   Pointer to ACPI SDT protocol.
> +  @param[in]   TableSignature         ACPI table signature.
> +  @param[out]  TableDescriptor        Pointer to ACPI table descriptor.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +AcpiGetTable (
> +  IN  EFI_ACPI_SDT_PROTOCOL  *AcpiTableSdtProtocol,
> +  IN  UINT32                 TableSignature,
> +  OUT ACPI_TABLE_DESCRIPTOR  *TableDescriptor
> +  )
> +{
> +  EFI_STATUS Status = EFI_SUCCESS;
> +  UINTN      TableIndex = 0;
> +
> +  ASSERT (AcpiTableSdtProtocol != NULL);
> +  ASSERT (TableDescriptor != NULL);
> +
> +  /*
> +   * Search for ACPI Table Signature
> +   */
> +  while (!EFI_ERROR (Status)) {
> +    Status = AcpiTableSdtProtocol->GetAcpiTable (
> +                                     TableIndex,
> +                                     &(TableDescriptor->Table),
> +                                     &(TableDescriptor->TableVersion),
> +                                     &(TableDescriptor->TableKey)
> +                                     );
> +    if (!EFI_ERROR (Status)) {
> +      TableIndex++;
> +
> +      if (((EFI_ACPI_SDT_HEADER *)TableDescriptor->Table)->Signature == TableSignature) {
> +        return EFI_SUCCESS;
> +      }
> +    }
> +  }
> +
> +  /* Nothing was found.  Clear the table descriptor. */
> +  ZeroMem (&TableDescriptor, sizeof (TableDescriptor));
> +
> +  return EFI_NOT_FOUND;
> +}
> +
> +/**
> +  Check whether the ACPI table is installed or not.
> +
> +  @param[in]    AcpiTableSignature        ACPI table signature.
> +
> +  @retval       TRUE     Already installed.
> +  @retval       FALSE    Not installed.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +IsAcpiInstalled (
> +  IN UINT32 AcpiTableSignature
> +  )
> +{
> +  EFI_STATUS            Status;
> +  ACPI_TABLE_DESCRIPTOR TableDescriptor;
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol = NULL;
> +
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = AcpiGetTable (AcpiTableSdtProtocol, AcpiTableSignature, &TableDescriptor);
> +  if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) {
> +    return TRUE;
> +  }
> +
> +  return FALSE;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
@ 2021-06-04 23:50   ` Leif Lindholm
  2021-06-15 16:49     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-04 23:50 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:05 +0700, Nhi Pham wrote:
> Add various ACPI tables for the Mt. Jade platform including: DSDT, SPCR,
> DBG2, GTDT, FACP, SSDT, MADT, PPTT, PCCT, SLIT, SRAT, and NFIT.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Contents of ACPI tables not reviewed.
Creation modes on many of these files are incorrect (as commented on
cover letter).
Address this, and you can have:
Acked-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |    8 +
>  Platform/Ampere/JadePkg/Jade.dsc                                    |   23 +
>  Platform/Ampere/JadePkg/Jade.fdf                                    |    8 +
>  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf                   |   20 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf |   75 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf |   44 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h          |  121 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h          |   49 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h      |   76 +
>  Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h                  |   37 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c          |  457 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c          |  445 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c          |  351 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c          |  599 +++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c          |  196 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c   |  178 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c          |  378 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c          |  190 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c          |  274 +
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi                       | 5639 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi                       | 5639 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/AcpiTables/CPU.asi                          |  127 +
>  Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl                         |  575 ++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi                     |  217 +
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi                 |  681 +++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi                       | 2078 ++++++++
>  Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi                       | 2087 ++++++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi                       | 1303 +++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi                       | 1303 +++++
>  Platform/Ampere/JadePkg/AcpiTables/PMU.asi                          |   10 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc            |   33 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc            |   87 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl             |  165 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc            |   87 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc            |  180 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl             |  330 ++
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl             |   17 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc            |   81 +
>  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl             |   15 +
>  39 files changed, 24183 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 3c47099b8edc..11f50f2f09cd 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -466,6 +466,14 @@ [PcdsFixedAtBuild.common]
>    #
>    gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
>  
> +  #
> +  # ACPI table
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013
> +
>    #
>    # Enable strict image permissions for all images. (This applies
>    # only to images that were built with >= 4 KB section alignment.)
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 9b9a5d0bad0f..0f9d0adbd34e 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -81,12 +81,24 @@ [LibraryClasses]
>    #
>    FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>  
> +  #
> +  # ACPI Libraries
> +  #
> +  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
> +  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
> +  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
> +
>  ################################################################################
>  #
>  # Specific Platform Pcds
>  #
>  ################################################################################
>  [PcdsFeatureFlag.common]
> +  #
> +  # Activate AcpiSdtProtocol
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
> +
>  [PcdsFixedAtBuild.common]
>  
>  !if $(SECURE_BOOT_ENABLE) == TRUE
> @@ -108,3 +120,14 @@ [Components.common]
>    # FailSafe and Watchdog Timer
>    #
>    Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> +
> +  #
> +  # ACPI
> +  #
> +  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2B
> +  }
> +  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> +  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 375455086d0b..2c6f9fac76fd 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -289,4 +289,12 @@ [FV.FvMain]
>    #
>  !include NetworkPkg/Network.fdf.inc
>  
> +  #
> +  # ACPI
> +  #
> +  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> +  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> +
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> new file mode 100644
> index 000000000000..1cf632f8a406
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> @@ -0,0 +1,20 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = JadeAcpiTables
> +  FILE_GUID                      = 5ADDBC13-8634-480C-9B94-671B7855CDB8
> +  MODULE_TYPE                    = USER_DEFINED
> +  VERSION_STRING                 = 1.0
> +
> +[Sources]
> +  Dsdt.asl
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> new file mode 100644
> index 000000000000..a1a323eee472
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> @@ -0,0 +1,75 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = AcpiPlatformDxe
> +  FILE_GUID                      = CDA4ED56-6960-4092-885D-FEF37D29093E
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = AcpiPlatformDxeInitialize
> +
> +[Sources.common]
> +  AcpiApei.c
> +  AcpiApei.h
> +  AcpiDsdt.c
> +  AcpiMadt.c
> +  AcpiNfit.c
> +  AcpiPcct.c
> +  AcpiPptt.c
> +  AcpiPlatform.h
> +  AcpiPlatformDxe.c
> +  AcpiSlit.c
> +  AcpiSrat.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AcpiHelperLib
> +  AcpiLib
> +  AcpiPccLib
> +  AmpereCpuLib
> +  BaseLib
> +  DebugLib
> +  FlashLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Pcd]
> +  gArmPlatformTokenSpaceGuid.PcdCoreCount
> +  gArmPlatformTokenSpaceGuid.PcdClusterCount
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
> +  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
> +
> +[Guids]
> +  gArmMpCoreInfoGuid
> +  gEfiAcpiTableGuid
> +  gEfiEventReadyToBootGuid
> +  gPlatformHobGuid
> +
> +[Protocols]
> +  gEfiAcpiTableProtocolGuid                     ## ALWAYS_CONSUMED
> +  gEfiAcpiSdtProtocolGuid
> +  gEfiPciRootBridgeIoProtocolGuid
> +
> +[Depex]
> +  gEfiAcpiTableProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> new file mode 100644
> index 000000000000..acc4092c650d
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> @@ -0,0 +1,44 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = AcpiCommonTables
> +  FILE_GUID                      = CEFA2AEB-357E-4F48-8066-EA950853056E
> +  MODULE_TYPE                    = USER_DEFINED
> +  VERSION_STRING                 = 1.0
> +
> +[Sources]
> +  Bert.aslc
> +  Dbg2.aslc
> +  Einj.asl
> +  Fadt.aslc
> +  Gtdt.aslc
> +  Hest.asl
> +  Sdei.asl
> +  Spcr.aslc
> +  Ssdt.asl
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[FixedPcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase            ## CONSUMES
> +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt                   ## CONSUMES
> +  gArmPlatformTokenSpaceGuid.PcdWatchdogCount                     ## CONSUMES
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision        ## CONSUMES
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision    ## CONSUMES
> +
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase             ## CONSUMES
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate                 ## CONSUMES
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
> new file mode 100644
> index 000000000000..c207142459ad
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
> @@ -0,0 +1,121 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_APEI_H_
> +#define ACPI_APEI_H_
> +
> +#include <Base.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Platform/Ac01.h>
> +#include <Protocol/AcpiTable.h>
> +
> +#pragma pack(1)
> +#define BERT_MSG_SIZE                0x2C
> +#define BERT_ERROR_TYPE              0x7F
> +#define BERT_UEFI_FAILURE            5
> +#define RAS_2P_TYPE                  0x03
> +#define BERT_DEFAULT_ERROR_SEVERITY  0x1
> +#define GENERIC_ERROR_DATA_REVISION  0x300
> +
> +
> +#define PLAT_CRASH_ITERATOR_SIZE     0x398
> +#define SMPRO_CRASH_SIZE             0x800
> +#define PMPRO_CRASH_SIZE             0x800
> +#define HEST_NUM_ENTRIES_PER_SOC     3
> +
> +#define CURRENT_BERT_VERSION         0x10
> +#define BERT_FLASH_OFFSET            0x91B30000ULL
> +#define BERT_DDR_OFFSET              0x88230000ULL
> +#define BERT_DDR_LENGTH              0x50000
> +
> +typedef struct {
> +  UINT8  Type;
> +  UINT8  SubType;
> +  UINT16 Instance;
> +  CHAR8  Msg[BERT_MSG_SIZE];
> +} APEI_BERT_ERROR_DATA;
> +
> +typedef struct {
> +  APEI_BERT_ERROR_DATA Vendor;
> +  UINT8                BertRev;
> +  UINT8                S0PmproRegisters[PMPRO_CRASH_SIZE];
> +  UINT8                S0SmproRegisters[SMPRO_CRASH_SIZE];
> +  UINT8                S1PmproRegisters[PMPRO_CRASH_SIZE];
> +  UINT8                S1SmproRegisters[SMPRO_CRASH_SIZE];
> +  UINT8                AtfDump[PLATFORM_CPU_MAX_NUM_CORES * PLAT_CRASH_ITERATOR_SIZE];
> +} APEI_CRASH_DUMP_DATA;
> +
> +typedef struct {
> +  EFI_ACPI_6_3_GENERIC_ERROR_STATUS_STRUCTURE     Ges;
> +  EFI_ACPI_6_3_GENERIC_ERROR_DATA_ENTRY_STRUCTURE Ged;
> +  APEI_CRASH_DUMP_DATA                            Bed;
> +} APEI_CRASH_DUMP_BERT_ERROR;
> +#pragma pack()
> +
> +VOID
> +EFIAPI
> +CreateDefaultBertData (
> +  APEI_BERT_ERROR_DATA *Data
> +  );
> +
> +VOID
> +EFIAPI
> +WrapBertErrorData (
> +  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
> +  );
> +
> +VOID
> +EFIAPI
> +PullBertSpinorData (
> +  APEI_CRASH_DUMP_DATA *BertErrorData
> +  );
> +
> +VOID
> +EFIAPI
> +AdjustBERTRegionLen (
> +  UINT32 Len
> +  );
> +
> +BOOLEAN
> +EFIAPI
> +IsBertEnabled (
> +  VOID
> +  );
> +
> +VOID
> +EFIAPI
> +WriteDDRBertTable (
> +  APEI_CRASH_DUMP_BERT_ERROR *Data
> +  );
> +
> +VOID
> +WriteSpinorDefaultBertTable (
> +  APEI_CRASH_DUMP_DATA *SpiRefrenceData
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiApeiUpdate (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiPopulateBert (
> +  VOID
> +  );
> +
> +#endif /* ACPI_APEI_H_ */
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
> new file mode 100644
> index 000000000000..920579281dd5
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
> @@ -0,0 +1,49 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_NFIT_H_
> +#define ACPI_NFIT_H_
> +
> +#include <Platform/Ac01.h>
> +
> +#define NVDIMM_SK0          0
> +#define NVDIMM_SK1          1
> +#define NVDIMM_NUM_PER_SK   (PLATFORM_NVDIMM_MCU_MAX_PER_SK * PLATFORM_NVDIMM_NUM_MAX_PER_MCU)
> +#define ONE_GB              (1024 * 1024 * 1024)
> +
> +enum NvdimmMode {
> +  NVDIMM_DISABLED   = 0,
> +  NVDIMM_NON_HASHED = 1,
> +  NVDIMM_HASHED     = 2
> +};
> +
> +typedef struct {
> +  BOOLEAN Enabled;
> +  UINT64  NvdSize;
> +  UINT32  DeviceHandle;
> +  UINT16  PhysId;
> +  UINT8   InterleaveWays;
> +  UINT64  RegionOffset;
> +  UINT16  VendorId;
> +  UINT16  DeviceId;
> +  UINT16  RevisionId;
> +  UINT16  SubVendorId;
> +  UINT16  SubDeviceId;
> +  UINT16  SubRevisionId;
> +  UINT32  SerialNumber;
> +} NVDIMM_INFO;
> +
> +typedef struct {
> +  UINT8       NvdRegionNum;
> +  UINT8       NvdRegionId[PLATFORM_NVDIMM_REGION_MAX_PER_SK];
> +  UINT8       NvdMode;
> +  UINT8       NvdNum;
> +  NVDIMM_INFO NvdInfo[NVDIMM_NUM_PER_SK];
> +} NVDIMM_DATA;
> +
> +#endif
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
> new file mode 100644
> index 000000000000..ce4d9b8440b8
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
> @@ -0,0 +1,76 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_PLATFORM_H_
> +#define ACPI_PLATFORM_H_
> +
> +#include <Uefi.h>
> +
> +#include <AcpiHeader.h>
> +#include <Guid/EventGroup.h>
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <Library/ArmLib/ArmLibPrivate.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/AcpiLib.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Platform/Ac01.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/AcpiTable.h>
> +
> +EFI_STATUS
> +AcpiPatchDsdtTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallMadtTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallNfitTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiPcctInit (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallPcctTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallPpttTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallSlitTable (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +AcpiInstallSratTable (
> +  VOID
> +  );
> +
> +#endif /* ACPI_PLATFORM_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
> new file mode 100644
> index 000000000000..d604b712d8c8
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
> @@ -0,0 +1,37 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_HEADER_H_
> +#define ACPI_HEADER_H_
> +
> +#include <IndustryStandard/Acpi.h>
> +
> +//
> +// ACPI table information used to initialize tables.
> +//
> +#define EFI_ACPI_OEM_ID           {'A','m','p','e','r','e'}
> +#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('A','l','t','r','a',' ',' ',' ')
> +#define EFI_ACPI_OEM_REVISION     FixedPcdGet32 (PcdAcpiDefaultOemRevision)
> +#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('A','M','P','.')
> +#define EFI_ACPI_CREATOR_REVISION FixedPcdGet32 (PcdAcpiDefaultCreatorRevision)
> +
> +// A macro to initialise the common header part of EFI ACPI tables as defined by
> +// EFI_ACPI_DESCRIPTION_HEADER structure.
> +#define __ACPI_HEADER(Signature, Type, Revision) {                \
> +    Signature,                /* UINT32  Signature */       \
> +    sizeof (Type),            /* UINT32  Length */          \
> +    Revision,                 /* UINT8   Revision */        \
> +    0,                        /* UINT8   Checksum */        \
> +    EFI_ACPI_OEM_ID,          /* UINT8   OemId[6] */        \
> +    EFI_ACPI_OEM_TABLE_ID,    /* UINT64  OemTableId */      \
> +    EFI_ACPI_OEM_REVISION,    /* UINT32  OemRevision */     \
> +    EFI_ACPI_CREATOR_ID,      /* UINT32  CreatorId */       \
> +    EFI_ACPI_CREATOR_REVISION /* UINT32  CreatorRevision */ \
> +  }
> +
> +#endif /* ACPI_HEADER_H_ */
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
> new file mode 100644
> index 000000000000..fa188c7776db
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
> @@ -0,0 +1,457 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/FlashLib.h>
> +#include <Library/NVParamLib.h>
> +#include <NVParamDef.h>
> +
> +#include "AcpiApei.h"
> +
> +UINT8 AMPERE_GUID[16] = {0x8d, 0x89, 0xed, 0xe8, 0x16, 0xdf, 0xcc, 0x43, 0x8e, 0xcc, 0x54, 0xf0, 0x60, 0xef, 0x15, 0x7f};
> +CHAR8 DEFAULT_BERT_REBOOT_MSG[BERT_MSG_SIZE] = "Unknown reboot reason";
> +
> +STATIC VOID
> +AcpiApeiUninstallTable (
> +  UINT32 Signature
> +  )
> +{
> +  EFI_STATUS              Status;
> +  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
> +  EFI_ACPI_SDT_PROTOCOL   *AcpiTableSdtProtocol;
> +  EFI_ACPI_SDT_HEADER     *Table;
> +  EFI_ACPI_TABLE_VERSION  TableVersion;
> +  UINTN                   TableKey;
> +  UINTN                   Idx;
> +
> +  /*
> +   * Get access to ACPI tables
> +   */
> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table protocol\n", __FUNCTION__, __LINE__));
> +    return;
> +  }
> +
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table support protocol\n", __FUNCTION__, __LINE__));
> +    return;
> +  }
> +
> +  /*
> +   * Search for ACPI Table Signature
> +   */
> +  for (Idx = 0; ; Idx++) {
> +    Status = AcpiTableSdtProtocol->GetAcpiTable (Idx, &Table, &TableVersion, &TableKey);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d: Unable to get ACPI table index %d \n", __FUNCTION__, __LINE__, Idx));
> +      return;
> +    } else if (Table->Signature == Signature) {
> +      break;
> +    }
> +  }
> +
> +  /*
> +   * Uninstall ACPI Table
> +   */
> +  Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, TableKey);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to uninstall table\n", __FUNCTION__, __LINE__));
> +  }
> +}
> +
> +VOID
> +AdjustBERTRegionLen (
> +  UINT32 Len
> +  )
> +{
> +  UINT32                                      Signature = EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE;
> +  EFI_STATUS                                  Status;
> +  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableSdtProtocol = NULL;
> +  EFI_ACPI_TABLE_VERSION                      TableVersion;
> +  UINTN                                       TableKey;
> +  UINTN                                       Idx;
> +  EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER *Table;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiSdtProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableSdtProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
> +    return;
> +  }
> +
> +  /*
> +   * Search for ACPI Table Signature
> +   */
> +  for (Idx = 0; ; Idx++) {
> +    Status = AcpiTableSdtProtocol->GetAcpiTable (
> +                                     Idx,
> +                                     (EFI_ACPI_SDT_HEADER **)&Table,
> +                                     &TableVersion,
> +                                     &TableKey
> +                                     );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "APEI: Unable to get ACPI table index:%d\n", Idx));
> +      return;
> +    } else if (Table->Header.Signature == Signature) {
> +      break;
> +    }
> +  }
> +
> +  /*
> +   * Adjust Boot Error Region Length
> +   */
> +  Table->BootErrorRegionLength = Len;
> +
> +  AcpiTableChecksum ((UINT8 *)Table, Table->Header.Length);
> +}
> +
> +/*
> + * Retrieve Bert data from SPI NOR
> + */
> +VOID
> +PullBertSpinorData (
> +  APEI_CRASH_DUMP_DATA *BertErrorData
> +  )
> +{
> +  UINTN Length;
> +
> +  Length = sizeof (*BertErrorData);
> +
> +  FlashReadCommand (
> +    (UINT8 *)BERT_FLASH_OFFSET,
> +    (UINT8 *)BertErrorData,
> +    &Length
> +    );
> +}
> +
> +/*
> + * wrap raw bert error data
> + *
> + * @param  IN  BertErrorData     Bert Error record to be wrapped
> + * @param  OUT WrappedError      Generic error data for OS to consume.
> + */
> +VOID
> +WrapBertErrorData (
> +  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
> +  )
> +{
> +  UINT32 CrashSize;
> +
> +  CrashSize = PLAT_CRASH_ITERATOR_SIZE *
> +              GetNumberOfSupportedSockets () *
> +              GetMaximumNumberOfCores ();
> +  CrashSize += 2 * (SMPRO_CRASH_SIZE + PMPRO_CRASH_SIZE);
> +  CrashSize += sizeof (WrappedError->Bed.Vendor) + sizeof (WrappedError->Bed.BertRev);
> +
> +  WrappedError->Ges.BlockStatus.ErrorDataEntryCount = 1;
> +  WrappedError->Ges.BlockStatus.UncorrectableErrorValid = 1;
> +  WrappedError->Ged.ErrorSeverity = BERT_DEFAULT_ERROR_SEVERITY;
> +  WrappedError->Ged.Revision = GENERIC_ERROR_DATA_REVISION;
> +
> +  if (WrappedError->Bed.Vendor.Type == RAS_2P_TYPE ||
> +      (WrappedError->Bed.Vendor.Type == BERT_ERROR_TYPE &&
> +       (WrappedError->Bed.Vendor.SubType == 0 ||
> +        WrappedError->Bed.Vendor.SubType == BERT_UEFI_FAILURE)))
> +  {
> +    WrappedError->Ged.ErrorDataLength = sizeof (WrappedError->Bed.Vendor) +
> +                                        sizeof (WrappedError->Bed.BertRev);
> +    WrappedError->Ges.DataLength = sizeof (WrappedError->Bed.Vendor) +
> +                                   sizeof (WrappedError->Bed.BertRev) +
> +                                   sizeof (WrappedError->Ged);
> +    AdjustBERTRegionLen (
> +      sizeof (WrappedError->Bed.Vendor) +
> +      sizeof (WrappedError->Bed.BertRev) +
> +      sizeof (WrappedError->Ged) +
> +      sizeof (WrappedError->Ges)
> +      );
> +  } else {
> +    WrappedError->Ged.ErrorDataLength = CrashSize;
> +    WrappedError->Ges.DataLength = CrashSize + sizeof (WrappedError->Ged);
> +    AdjustBERTRegionLen (
> +      CrashSize +
> +      sizeof (WrappedError->Ged) +
> +      sizeof (WrappedError->Ges)
> +      );
> +  }
> +  CopyMem (
> +    WrappedError->Ged.SectionType,
> +    AMPERE_GUID,
> +    sizeof (AMPERE_GUID)
> +    );
> +}
> +
> +
> +/*
> + * create default bert error
> + * Msg: Unknown reboot reason
> + */
> +VOID
> +CreateDefaultBertData (
> +  APEI_BERT_ERROR_DATA *Data
> +  )
> +{
> +  Data->Type = BERT_ERROR_TYPE;
> +  AsciiStrCpyS (
> +    Data->Msg,
> +    BERT_MSG_SIZE,
> +    DEFAULT_BERT_REBOOT_MSG
> +    );
> +}
> +
> +/*
> + * Ensures BertErrorData In SPINOR matches
> + * the record produced by CreateDefaultBertData.
> + * @param  Bed    Crash dump Data
> + */
> +VOID
> +WriteSpinorDefaultBertTable (
> +  APEI_CRASH_DUMP_DATA *Bed
> +  )
> +{
> +  UINT8                BertRev;
> +  UINTN                Length;
> +  UINT64               Offset;
> +  UINT32               MsgDiff;
> +  APEI_BERT_ERROR_DATA DefaultData = {0};
> +
> +  CreateDefaultBertData (&DefaultData);
> +  if ((Bed->Vendor.Type != DefaultData.Type)) {
> +    Offset = BERT_FLASH_OFFSET +
> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Type);
> +    Length = sizeof (DefaultData.Type);
> +    FlashEraseCommand ((UINT8 *)Offset, Length);
> +    FlashProgramCommand (
> +      (UINT8 *)Offset,
> +      (UINT8 *)&(DefaultData.Type),
> +      &Length
> +      );
> +  }
> +
> +  if ((Bed->Vendor.SubType != DefaultData.SubType)) {
> +    Offset = BERT_FLASH_OFFSET +
> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
> +             OFFSET_OF (APEI_BERT_ERROR_DATA, SubType);
> +    Length = sizeof (DefaultData.SubType);
> +    FlashEraseCommand ((UINT8 *)Offset, Length);
> +    FlashProgramCommand (
> +      (UINT8 *)Offset,
> +      (UINT8 *)&(DefaultData.SubType),
> +      &Length
> +      );
> +  }
> +
> +  if ((Bed->Vendor.Instance != DefaultData.Instance)) {
> +    Offset = BERT_FLASH_OFFSET +
> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Instance);
> +    Length = sizeof (DefaultData.Instance);
> +    FlashEraseCommand ((UINT8 *)Offset, Length);
> +    FlashProgramCommand (
> +      (UINT8 *)Offset,
> +      (UINT8 *)&(DefaultData.Instance),
> +      &Length
> +      );
> +  }
> +
> +  MsgDiff = AsciiStrnCmp (Bed->Vendor.Msg, DefaultData.Msg, BERT_MSG_SIZE);
> +  if (MsgDiff != 0) {
> +    Offset = BERT_FLASH_OFFSET +
> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Msg);
> +    Length = sizeof (DefaultData.Msg);
> +    FlashEraseCommand ((UINT8 *)Offset, Length);
> +    FlashProgramCommand (
> +      (UINT8 *)Offset,
> +      (UINT8 *)&(DefaultData.Msg),
> +      &Length
> +      );
> +  }
> +
> +  if (Bed->BertRev != CURRENT_BERT_VERSION) {
> +    Offset = BERT_FLASH_OFFSET + OFFSET_OF (APEI_CRASH_DUMP_DATA, BertRev);
> +    Length = sizeof (Bed->BertRev);
> +    BertRev = CURRENT_BERT_VERSION;
> +    FlashEraseCommand ((UINT8 *)Offset, Length);
> +    FlashProgramCommand ((UINT8 *)Offset, (UINT8 *)&BertRev, &Length);
> +  }
> +
> +}
> +
> +/*
> + * Checks Status of NV_SI_RAS_BERT_ENABLED
> + * Returns TRUE if enabled and FALSE if disabled
> + */
> +BOOLEAN
> +IsBertEnabled (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_RAS_BERT_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    // BERT is enabled by default
> +    return TRUE;
> +  }
> +
> +  return (Value != 0) ? TRUE : FALSE;
> +}
> +
> +/*
> + * Write bert table to DDR
> + */
> +VOID
> +WriteDDRBertTable (
> +  APEI_CRASH_DUMP_BERT_ERROR *Data
> +  )
> +{
> +  VOID *Blk = (VOID *)BERT_DDR_OFFSET;
> +
> +  /*
> +   * writing sizeof data to ddr produces alignment error
> +   * this is a temporary workaround
> +   */
> +  CopyMem (Blk, Data, BERT_DDR_LENGTH);
> +}
> +
> +/*
> + * Update Bert Table
> + */
> +EFI_STATUS
> +AcpiPopulateBert (
> +  VOID
> +  )
> +{
> +  APEI_CRASH_DUMP_BERT_ERROR *DDRError;
> +
> +  DDRError =
> +    (APEI_CRASH_DUMP_BERT_ERROR *)
> +    AllocateZeroPool (sizeof (APEI_CRASH_DUMP_BERT_ERROR));
> +
> +  if (DDRError == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  if (IsBertEnabled ()) {
> +    PullBertSpinorData (&(DDRError->Bed));
> +    if ((DDRError->Bed.BertRev == CURRENT_BERT_VERSION)) {
> +      WrapBertErrorData (DDRError);
> +      WriteDDRBertTable (DDRError);
> +    }
> +    WriteSpinorDefaultBertTable (&(DDRError->Bed));
> +  }
> +
> +  FreePool (DDRError);
> +  return EFI_SUCCESS;
> +}
> +
> +/*
> + * Checks Status of NV_SI_RAS_SDEI_ENABLED
> + * Returns TRUE if enabled and FALSE if disabled or error occurred
> + */
> +BOOLEAN
> +IsSdeiEnabled (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_RAS_SDEI_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    // SDEI is disabled by default
> +    return FALSE;
> +  }
> +
> +  return (Value != 0) ? TRUE : FALSE;
> +}
> +
> +STATIC
> +VOID
> +AcpiApeiHestUpdateTable1P (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                                      Status;
> +  EFI_ACPI_SDT_PROTOCOL                           *AcpiTableSdtProtocol = NULL;
> +  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *HestTablePointer;
> +  EFI_ACPI_TABLE_VERSION                          TableVersion;
> +  UINTN                                           TableKey;
> +  UINTN                                           Idx;
> +
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
> +    return;
> +  }
> +
> +  /*
> +   * Search for ACPI Table Signature
> +   */
> +  for (Idx = 0; ; Idx++) {
> +    Status = AcpiTableSdtProtocol->GetAcpiTable (
> +                                     Idx,
> +                                     (EFI_ACPI_SDT_HEADER **)&HestTablePointer,
> +                                     &TableVersion,
> +                                     &TableKey
> +                                     );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "APEI: Unable to get HEST table"));
> +      return;
> +    } else if (HestTablePointer->Header.Signature ==
> +               EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE)
> +    {
> +      break;
> +    }
> +  }
> +
> +  HestTablePointer->ErrorSourceCount -= HEST_NUM_ENTRIES_PER_SOC;
> +  HestTablePointer->Header.Length -=
> +    (HEST_NUM_ENTRIES_PER_SOC *
> +     sizeof (EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE));
> +
> +  AcpiTableChecksum ((UINT8 *)HestTablePointer, HestTablePointer->Header.Length);
> +}
> +
> +/*
> + * Update APEI
> + *
> + */
> +EFI_STATUS
> +EFIAPI
> +AcpiApeiUpdate (
> +  VOID
> +  )
> +{
> +  if (!IsSlaveSocketActive ()) {
> +    AcpiApeiHestUpdateTable1P ();
> +  }
> +
> +  if (!IsSdeiEnabled ()) {
> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
> new file mode 100644
> index 000000000000..7881044104e4
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
> @@ -0,0 +1,445 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Protocol/PciRootBridgeIo.h>
> +#include <Library/NVParamLib.h>
> +#include <NVParamDef.h>
> +
> +#include "AcpiNfit.h"
> +#include "AcpiPlatform.h"
> +
> +#define PCIE_DEVICE_CONTROL_OFFSET                      0x078
> +#define PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN        0x08
> +#define PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN         0x04
> +#define PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN     0x02
> +#define PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN          0x01
> +
> +#define PCIE_ROOT_ERR_CMD_OFFSET                        0x12C
> +#define PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN        0x4
> +#define PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN    0x2
> +#define PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN         0x1
> +
> +#define PCIE_MAX_DEVICE_PER_ROOT_PORT 8
> +
> +STATIC VOID
> +AcpiPatchCmn600 (
> +  VOID
> +  )
> +{
> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
> +  UINTN Index;
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.CMN%1X._STA", Index);
> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +    } else {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    }
> +  }
> +}
> +
> +STATIC VOID
> +AcpiPatchDmc620 (
> +  VOID
> +  )
> +{
> +  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
> +  UINTN              Index, Index1;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  UINT32             McuMask;
> +  VOID               *Hob;
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    McuMask = PlatformHob->DramInfo.McuMask[Index];
> +    for (Index1 = 0; Index1 < sizeof (McuMask) * 8; Index1++) {
> +      AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.MC%1X%1X._STA", Index, Index1);
> +      if (McuMask & (0x1 << Index1)) {
> +        AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +      } else {
> +        AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +      }
> +    }
> +  }
> +}
> +
> +STATIC VOID
> +AcpiPatchNvdimm (
> +  VOID
> +  )
> +{
> +  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
> +  UINTN              NvdRegionNumSK0, NvdRegionNumSK1, NvdRegionNum, Count;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  VOID               *Hob;
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  NvdRegionNumSK0 = 0;
> +  NvdRegionNumSK1 = 0;
> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +    if (PlatformHob->DramInfo.NvdRegion[Count] > 0) {
> +      if (PlatformHob->DramInfo.Socket[Count] == 0) {
> +        NvdRegionNumSK0++;
> +      } else {
> +        NvdRegionNumSK1++;
> +      }
> +    }
> +  }
> +  NvdRegionNum = NvdRegionNumSK0 + NvdRegionNumSK1;
> +
> +  /* Disable NVDIMM Root Device */
> +  if (NvdRegionNum == 0) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR._STA");
> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +  }
> +  /* Update NVDIMM Device _STA for SK0 */
> +  if (NvdRegionNumSK0 == 0) {
> +    /* Disable NVD1/2 */
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +  } else if (NvdRegionNumSK0 == 1) {
> +    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK0] == NVDIMM_NON_HASHED) {
> +      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
> +            PlatformHob->DramInfo.Socket[Count] == 0)
> +        {
> +          if (PlatformHob->DramInfo.Base[Count] ==
> +              PLATFORM_NVDIMM_SK0_NHASHED_REGION0)
> +          {
> +            /* Disable NVD2 */
> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +          } else if (PlatformHob->DramInfo.Base[Count] ==
> +                     PLATFORM_NVDIMM_SK0_NHASHED_REGION1)
> +          {
> +            /* Disable NVD1 */
> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +          }
> +        }
> +      }
> +    }
> +  }
> +  /* Update NVDIMM Device _STA for SK1 */
> +  if (NvdRegionNumSK1 == 0) {
> +    /* Disable NVD3/4 */
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +  } else if (NvdRegionNumSK1 == 1) {
> +    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK1] == NVDIMM_NON_HASHED) {
> +      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
> +            PlatformHob->DramInfo.Socket[Count] == 1)
> +        {
> +          if (PlatformHob->DramInfo.Base[Count] ==
> +              PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
> +          {
> +            /* Disable NVD4 */
> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +          } else if (PlatformHob->DramInfo.Base[Count] ==
> +                     PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
> +          {
> +            /* Disable NVD3 */
> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +          }
> +        }
> +      }
> +    }
> +  }
> +}
> +
> +STATIC VOID
> +AcpiPatchHwmon (
> +  VOID
> +  )
> +{
> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
> +  UINT8 Index;
> +
> +  // PCC Hardware Monitor Devices
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index);
> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +    } else {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    }
> +  }
> +
> +  // Ampere Altra SoC Hardware Monitor Devices
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index + 2);
> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +    } else {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    }
> +  }
> +}
> +
> +STATIC VOID
> +AcpiPatchDsu (
> +  VOID
> +  )
> +{
> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
> +  UINTN Index;
> +
> +  for (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index += PLATFORM_CPU_NUM_CORES_PER_CPM) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.DU%2X._STA", Index / PLATFORM_CPU_NUM_CORES_PER_CPM);
> +    if (IsCpuEnabled (Index)) {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +    } else {
> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +    }
> +  }
> +}
> +
> +VOID
> +AcpiPatchPcieNuma (
> +  VOID
> +  )
> +{
> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
> +  UINTN Index;
> +  UINTN NumaIdx;
> +  UINTN NumPciePort;
> +  UINTN NumaAssignment[3][16] = {
> +    { 0, 0, 0, 0, 0, 0, 0, 0,   // Monolithic Node 0 (S0)
> +      1, 1, 1, 1, 1, 1, 1, 1 }, // Monolithic Node 1 (S1)
> +    { 0, 1, 0, 1, 0, 0, 1, 1,   // Hemisphere Node 0, 1 (S0)
> +      2, 3, 2, 3, 2, 2, 3, 3 }, // Hemisphere Node 2, 3 (S1)
> +    { 0, 2, 1, 3, 1, 1, 3, 3,   // Quadrant Node 0, 1, 2, 3 (S0)
> +      4, 6, 5, 7, 5, 5, 7, 7 }, // Quadrant Node 4, 5, 6, 7 (S1)
> +  };
> +
> +  switch (CpuGetSubNumaMode ()) {
> +  case SUBNUMA_MODE_MONOLITHIC:
> +    NumaIdx = 0;
> +    break;
> +
> +  case SUBNUMA_MODE_HEMISPHERE:
> +    NumaIdx = 1;
> +    break;
> +
> +  case SUBNUMA_MODE_QUADRANT:
> +    NumaIdx = 2;
> +    break;
> +
> +  default:
> +    NumaIdx = 0;
> +    break;
> +  }
> +
> +  if (IsSlaveSocketActive ()) {
> +    NumPciePort = 16; // 16 ports total (8 per socket)
> +  } else {
> +    NumPciePort = 8;  // 8 ports total
> +  }
> +
> +  for (Index = 0; Index < NumPciePort; Index++) {
> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._PXM", Index);
> +    AcpiDSDTSetNodeStatusValue (NodePath, NumaAssignment[NumaIdx][Index]);
> +  }
> +}
> +
> +EFI_STATUS
> +AcpiPatchPcieAerFwFirst (
> +  VOID
> +  )
> +{
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS Address;
> +  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableProtocol;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL             *PciRootBridgeIo;
> +  EFI_HANDLE                                  *HandleBuffer;
> +  UINTN                                       HandleCount;
> +  EFI_ACPI_HANDLE                             TableHandle;
> +  EFI_ACPI_HANDLE                             ChildHandle;
> +  EFI_ACPI_DATA_TYPE                          DataType;
> +  UINTN                                       DataSize;
> +  CHAR8                                       ObjectPath[8];
> +  EFI_STATUS                                  Status;
> +  UINT32                                      AerFwFirstConfigValue;
> +  UINT32                                      RegData;
> +  UINT16                                      Device;
> +  UINT32                                      Index;
> +  UINT8                                       *Data;
> +
> +  //
> +  // Check if PCIe AER Firmware First should be enabled
> +  //
> +  Status = NVParamGet (
> +             NV_SI_RAS_PCIE_AER_FW_FIRST,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &AerFwFirstConfigValue
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Status = NVParamGet (
> +               NV_SI_RO_BOARD_PCIE_AER_FW_FIRST,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               &AerFwFirstConfigValue
> +               );
> +    if (EFI_ERROR (Status)) {
> +      AerFwFirstConfigValue = 0;
> +    }
> +  }
> +
> +  if (AerFwFirstConfigValue == 0) {
> +    //
> +    // By default, the PCIe AER FW-First (ACPI Object "AERF") is set to 0
> +    // in the DSDT table.
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiSdtProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
> +    return Status;
> +  }
> +
> +  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
> +  if (EFI_ERROR (Status)) {
> +    AcpiTableProtocol->Close (TableHandle);
> +    return Status;
> +  }
> +
> +  //
> +  // Update Name Object "AERF" (PCIe AER Firmware-First) if it is enabled.
> +  //
> +  AsciiSPrint (ObjectPath, sizeof (ObjectPath), "\\AERF");
> +  Status = AcpiTableProtocol->FindPath (TableHandle, ObjectPath, &ChildHandle);
> +  ASSERT_EFI_ERROR (Status);
> +  if (!EFI_ERROR (Status)) {
> +    Status = AcpiTableProtocol->GetOption (
> +                                  ChildHandle,
> +                                  0,
> +                                  &DataType,
> +                                  (VOID *)&Data,
> +                                  &DataSize
> +                                  );
> +    ASSERT_EFI_ERROR (Status);
> +    if (!EFI_ERROR (Status)
> +        && Data[0] == AML_NAME_OP
> +        && (Data[5] == AML_ZERO_OP || Data[5] == AML_ONE_OP))
> +    {
> +      Data[5] = 1; // Enable PCIe AER Firmware-First
> +    }
> +  }
> +
> +  AcpiTableProtocol->Close (TableHandle);
> +  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
> +
> +  //
> +  // For PCIe AER Firmware First, PCIe capability registers need
> +  // to be updated to allow Firmware to detect AER errors.
> +  //
> +
> +  HandleCount = 0;
> +  HandleBuffer = NULL;
> +  PciRootBridgeIo = NULL;
> +
> +  Status = gBS->LocateHandleBuffer (
> +                  ByProtocol,
> +                  &gEfiPciRootBridgeIoProtocolGuid,
> +                  NULL,
> +                  &HandleCount,
> +                  &HandleBuffer
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Loop through each root complex
> +  //
> +  for (Index = 0; Index < HandleCount; Index++) {
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer[Index],
> +                    &gEfiPciRootBridgeIoProtocolGuid,
> +                    (VOID **)&PciRootBridgeIo
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    //
> +    // Loop through each root port
> +    //
> +    for (Device = 1; Device <= PCIE_MAX_DEVICE_PER_ROOT_PORT; Device++) {
> +      Address.Bus = 0;
> +      Address.Device = Device;
> +      Address.Function = 0;
> +      Address.Register = 0;
> +
> +      Address.ExtendedRegister = PCIE_DEVICE_CONTROL_OFFSET;
> +      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
> +
> +      if (RegData == 0xFFFFFFFF) {
> +        continue;
> +      }
> +
> +      RegData |= PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN
> +                 | PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN
> +                 | PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN
> +                 | PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN;
> +
> +      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
> +
> +      RegData = 0;
> +      Address.ExtendedRegister = PCIE_ROOT_ERR_CMD_OFFSET;
> +      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
> +
> +      RegData |= PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN
> +                 | PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN
> +                 | PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN;
> +
> +      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
> +    }
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +AcpiPatchDsdtTable (
> +  VOID
> +  )
> +{
> +  AcpiPatchCmn600 ();
> +  AcpiPatchDmc620 ();
> +  AcpiPatchDsu ();
> +  AcpiPatchHwmon ();
> +  AcpiPatchNvdimm ();
> +  AcpiPatchPcieNuma ();
> +  AcpiPatchPcieAerFwFirst ();
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
> new file mode 100644
> index 000000000000..1d1643abd299
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
> @@ -0,0 +1,351 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiPlatform.h"
> +
> +EFI_ACPI_6_3_GIC_ITS_STRUCTURE GicItsTemplate = {
> +  EFI_ACPI_6_3_GIC_ITS,
> +  sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE),
> +  EFI_ACPI_RESERVED_WORD,
> +  0, /* GicItsId */
> +  0, /* PhysicalBaseAddress */
> +  0, /* Reserved2 */
> +};
> +
> +EFI_ACPI_6_3_GICR_STRUCTURE GicRTemplate = {
> +  EFI_ACPI_6_3_GICR,
> +  sizeof (EFI_ACPI_6_3_GICR_STRUCTURE),
> +  EFI_ACPI_RESERVED_WORD,
> +  GICR_MASTER_BASE_REG, /* DiscoveryRangeBaseAddress */
> +  0x1000000,            /* DiscoveryRangeLength */
> +};
> +
> +EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDTemplate = {
> +  EFI_ACPI_6_3_GICD,
> +  sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE),
> +  EFI_ACPI_RESERVED_WORD,
> +  0,             /* GicDistHwId */
> +  GICD_BASE_REG, /* GicDistBase */
> +  0,             /* GicDistVector */
> +  0x3,           /* GicVersion */
> +  {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}
> +};
> +
> +EFI_ACPI_6_3_GIC_STRUCTURE GiccTemplate = {
> +  EFI_ACPI_6_3_GIC,
> +  sizeof (EFI_ACPI_6_3_GIC_STRUCTURE),
> +  EFI_ACPI_RESERVED_WORD,
> +  0, /* GicId */
> +  0, /* AcpiCpuUid */
> +  0, /* Flags */
> +  0,
> +  23, /* PmuIrq */
> +  0,
> +  0,
> +  0,
> +  0,
> +  25, /* GsivId */
> +  0,  /* GicRBase */
> +  0,  /* Mpidr */
> +  0,  /* ProcessorPowerEfficiencyClass */
> +  0,  /* Reserved2 */
> +  21, /* SPE irq */
> +};
> +
> +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MADTTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
> +    0, /* need fill in */
> +    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
> +    ),
> +};
> +
> +UINT32 Ac01CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
> +  36, 52, 40, 56, 32, 48, 44, 60,
> +  20, 68, 24, 72, 16, 64, 28, 76,
> +  4, 8, 0, 12, 38, 54, 42, 58,
> +  34, 50, 46, 62, 22, 70, 26, 74,
> +  18, 66, 30, 78, 6, 10, 2, 14,
> +  37, 53, 41, 57, 33, 49, 45, 61,
> +  21, 69, 25, 73, 17, 65, 29, 77,
> +  5, 9, 1, 13, 39, 55, 43, 59,
> +  35, 51, 47, 63, 23, 71, 27, 75,
> +  19, 67, 31, 79, 7, 11, 3, 15,
> +};
> +
> +UINT32 Ac01CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
> +  32, 48, 16, 64, 36, 52, 0, 20,
> +  68, 4, 34, 50, 18, 66, 38, 54,
> +  2, 22, 70, 6, 33, 49, 17, 65,
> +  37, 53, 1, 21, 69, 5, 35, 51,
> +  19, 67, 39, 55, 3, 23, 71, 7,
> +  44, 60, 28, 76, 40, 56, 12, 24,
> +  72, 8, 46, 62, 30, 78, 42, 58,
> +  14, 26, 74, 10, 45, 61, 29, 77,
> +  41, 57, 13, 25, 73, 9, 47, 63,
> +  31, 79, 43, 59, 15, 27, 75, 11,
> +};
> +
> +UINT32 Ac01CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
> +  16, 32, 0, 20, 4, 18, 34, 2,
> +  22, 6, 17, 33, 1, 21, 5, 19,
> +  35, 3, 23, 7, 48, 64, 52, 68,
> +  36, 50, 66, 54, 70, 38, 49, 65,
> +  53, 69, 37, 51, 67, 55, 71, 39,
> +  28, 44, 12, 24, 8, 30, 46, 14,
> +  26, 10, 29, 45, 13, 25, 9, 31,
> +  47, 15, 27, 11, 60, 76, 56, 72,
> +  40, 62, 78, 58, 74, 42, 61, 77,
> +  57, 73, 41, 63, 79, 59, 75, 43,
> +};
> +
> +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTablePointer;
> +
> +UINT32 *
> +CpuGetCoreOrder (
> +  VOID
> +  )
> +{
> +  UINT8              SubNumaMode;
> +
> +  SubNumaMode = CpuGetSubNumaMode ();
> +  switch (SubNumaMode) {
> +  case SUBNUMA_MODE_MONOLITHIC:
> +    return (UINT32 *)&Ac01CoreOrderMonolithic;
> +
> +  case SUBNUMA_MODE_HEMISPHERE:
> +    return (UINT32 *)&Ac01CoreOrderHemisphere;
> +
> +  case SUBNUMA_MODE_QUADRANT:
> +    return (UINT32 *)&Ac01CoreOrderQuadrant;
> +
> +  default:
> +    // Should never reach here
> +    ASSERT (FALSE);
> +    return NULL;
> +  }
> +
> +  return NULL;
> +}
> +
> +UINT32
> +AcpiInstallMadtProcessorNode (
> +  VOID   *EntryPointer,
> +  UINT32 CpuId
> +  )
> +{
> +  EFI_ACPI_6_3_GIC_STRUCTURE *MadtProcessorEntryPointer = EntryPointer;
> +  UINT32                     SocketId;
> +  UINT32                     ClusterId;
> +  UINTN                      Size;
> +
> +  Size = sizeof (GiccTemplate);
> +  CopyMem (MadtProcessorEntryPointer, &GiccTemplate, Size);
> +
> +  SocketId = SOCKET_ID (CpuId);
> +  ClusterId = CLUSTER_ID (CpuId);
> +
> +  //
> +  // GICv2 compatibility mode is not supported.
> +  // Hence, set GIC's CPU Interface Number to 0.
> +  //
> +  MadtProcessorEntryPointer->CPUInterfaceNumber = 0;
> +  MadtProcessorEntryPointer->AcpiProcessorUid =
> +    (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
> +    (ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM);
> +  MadtProcessorEntryPointer->Flags = 1;
> +  MadtProcessorEntryPointer->MPIDR =
> +    (((ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM)) << 8);
> +  MadtProcessorEntryPointer->MPIDR += (((UINT64)SocketId) << 32);
> +
> +  return Size;
> +}
> +
> +UINT32
> +AcpiInstallMadtGicD (
> +  VOID *EntryPointer
> +  )
> +{
> +  EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GicDEntryPointer = EntryPointer;
> +  UINTN                                  Size;
> +
> +  Size = sizeof (GicDTemplate);
> +  CopyMem (GicDEntryPointer, &GicDTemplate, Size);
> +
> +  return Size;
> +}
> +
> +UINT32
> +AcpiInstallMadtGicR (
> +  VOID   *EntryPointer,
> +  UINT32 SocketId
> +  )
> +{
> +  EFI_ACPI_6_3_GICR_STRUCTURE *GicREntryPointer = EntryPointer;
> +  UINTN                       Size;
> +
> +  /*
> +   * If the Slave socket is not present, discard the Slave socket
> +   * GIC redistributor region
> +   */
> +  if (SocketId == 1 && !IsSlaveSocketActive ()) {
> +    return 0;
> +  }
> +
> +  Size = sizeof (GicRTemplate);
> +  CopyMem (GicREntryPointer, &GicRTemplate, Size);
> +
> +  if (SocketId == 1) {
> +    GicREntryPointer->DiscoveryRangeBaseAddress = GICR_SLAVE_BASE_REG;
> +  }
> +
> +  return Size;
> +}
> +
> +UINT32
> +AcpiInstallMadtGicIts (
> +  VOID   *EntryPointer,
> +  UINT32 Index
> +  )
> +{
> +  EFI_ACPI_6_3_GIC_ITS_STRUCTURE *GicItsEntryPointer = EntryPointer;
> +  UINTN                          Size, Offset;
> +  UINT64                         GicBase = GICD_BASE_REG;
> +  UINT32                         ItsId = Index;
> +
> +  if (Index > SOCKET0_LAST_RC) { /* Socket 1, Index: 8-15 */
> +    GicBase = GICD_SLAVE_BASE_REG;
> +    Index -= (SOCKET0_LAST_RC + 1); /* Socket 1, Index:8 -> RCA0 */
> +  }
> +  Size = sizeof (GicItsTemplate);
> +  CopyMem (GicItsEntryPointer, &GicItsTemplate, Size);
> +  Offset = 0x40000 + Index * 0x20000;
> +  GicItsEntryPointer->GicItsId = ItsId;
> +  GicItsEntryPointer->PhysicalBaseAddress = Offset + GicBase;
> +
> +  return Size;
> +}
> +
> +/*
> + *  Install MADT table.
> + */
> +EFI_STATUS
> +AcpiInstallMadtTable (
> +  VOID
> +  )
> +{
> +  EFI_ACPI_6_3_GIC_STRUCTURE *GiccEntryPointer = NULL;
> +  EFI_ACPI_TABLE_PROTOCOL    *AcpiTableProtocol;
> +  UINTN                      MadtTableKey  = 0;
> +  INTN                       Index;
> +  EFI_STATUS                 Status;
> +  UINTN                      Size;
> +  UINT32                     *CoreOrder;
> +  UINT32                     SktMaxCoreNum;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Size = sizeof (MADTTableHeaderTemplate) +
> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (GiccTemplate)) +
> +          sizeof (GicDTemplate) +
> +          (PLATFORM_CPU_MAX_SOCKET * sizeof (GicRTemplate)) +
> +          ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsTemplate));
> +  if (IsSlaveSocketActive ()) {
> +    Size += ((SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsTemplate));
> +  } else if (!IsSlaveSocketPresent ()) {
> +    Size += 2 * sizeof (GicItsTemplate); /* RCA0/1 */
> +  }
> +
> +  MadtTablePointer =
> +    (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (Size);
> +  if (MadtTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  GiccEntryPointer =
> +    (EFI_ACPI_6_3_GIC_STRUCTURE *)((UINT64)MadtTablePointer +
> +                                    sizeof (MADTTableHeaderTemplate));
> +
> +  /* Install Gic interface for each processor */
> +  Size = 0;
> +  CoreOrder = CpuGetCoreOrder ();
> +  ASSERT (CoreOrder != NULL);
> +  SktMaxCoreNum = PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM;
> +  for (Index = 0; Index < SktMaxCoreNum; Index++) {
> +    if (IsCpuEnabled (CoreOrder[Index])) {
> +      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index]);
> +    }
> +  }
> +
> +  for (Index = 0; Index < SktMaxCoreNum; Index++) {
> +    if (IsCpuEnabled (CoreOrder[Index] + SktMaxCoreNum)) {
> +      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index] + SktMaxCoreNum);
> +    }
> +  }
> +
> +  /* Install Gic Distributor */
> +  Size += AcpiInstallMadtGicD ((VOID *)((UINT64)GiccEntryPointer + Size));
> +
> +  /* Install Gic Redistributor */
> +  for (Index = 0; Index < PLATFORM_CPU_MAX_SOCKET; Index++) {
> +    Size += AcpiInstallMadtGicR ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
> +  }
> +
> +  /* Install Gic ITS */
> +  if (!IsSlaveSocketPresent ()) {
> +    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
> +      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
> +    }
> +  }
> +  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
> +    Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
> +  }
> +  if (IsSlaveSocketActive ()) {
> +    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
> +      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
> +    }
> +  }
> +  CopyMem (
> +    MadtTablePointer,
> +    &MADTTableHeaderTemplate,
> +    sizeof (MADTTableHeaderTemplate)
> +    );
> +
> +  Size += sizeof (MADTTableHeaderTemplate);
> +  MadtTablePointer->Header.Length = Size;
> +  CopyMem (
> +    MadtTablePointer->Header.OemId,
> +    PcdGetPtr (PcdAcpiDefaultOemId),
> +    sizeof (MadtTablePointer->Header.OemId)
> +    );
> +
> +  AcpiTableChecksum (
> +    (UINT8 *)MadtTablePointer,
> +    MadtTablePointer->Header.Length
> +    );
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)MadtTablePointer,
> +                                MadtTablePointer->Header.Length,
> +                                &MadtTableKey
> +                                );
> +  FreePool ((VOID *)MadtTablePointer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
> new file mode 100644
> index 000000000000..d13ac3514e11
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
> @@ -0,0 +1,599 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiNfit.h"
> +#include "AcpiPlatform.h"
> +
> +EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE NfitSPATemplate = {
> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE,
> +  sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE),
> +  0,                                                                // The uniue index - need to be filled.
> +  0,                                                                // The flags - need to be filled.
> +  0,                                                                // Reserved.
> +  0,                                                                // Proximity domain - need to be filled.
> +  EFI_ACPI_6_3_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION, // PM range type.
> +  0,                                                                // Start address - need to be filled.
> +  0,                                                                // Size - need to be filled.
> +  EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB |
> +  EFI_MEMORY_WP | EFI_MEMORY_UCE, // attribute - need to be filled.
> +};
> +
> +EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE NvdimmControlRegionTemplate = {
> +  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE,
> +  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE),
> +  0,   // The unique index - need to be filled.
> +  0,   // The vendor id - need to be filled.
> +  0,   // The device id - need to be filled.
> +  0,   // The revision - need to be filled.
> +  0,   // The subsystem nvdimm id - need to be filled.
> +  0,   // The subsystem nvdimm device id - need to be filled.
> +  0,   // The subsystem revision - need to be filled.
> +  0,   // The valid field.
> +  0,   // The manufacturing location - not valid.
> +  0,   // The manufacturing date - not valid.
> +  {0}, // Reserved.
> +  0,   // The serial number - need to be filled.
> +  0,   // The region format interface code - dummy value.
> +  0,   // The number of block control windows.
> +  0,   // The size of block control windows.
> +  0,   // The Command Register Offset in Block Control Window.
> +  0,   // The Size of Command Register in Block Control Windows.
> +  0,   // The Status Register Offset in Block Control Window.
> +  0,   // Size of Status Register in Block Control Windows.
> +  0,   // The NVDIMM Control Region Flag.
> +  {0}, // Reserved.
> +};
> +
> +EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE NvdimmRegionMappingTemplate = {
> +  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE,
> +  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE),
> +  {0}, // _ADR of the NVDIMM device - need to be filled.
> +  0,   // Dimm smbios handle index - need to be filled.
> +  0,   // The unique region index - need to be filled.
> +  0,   // The SPA range index - need to be filled.
> +  0,   // The control region index - need to be filled.
> +  0,   // The region size - need to be filled.
> +  0,   // The region offset - need to be filled.
> +  0,   // The region base - need to be filled.
> +  0,   // The interleave structure index - need to be filled.
> +  0,   // The interleave ways - need to be filled.
> +  0,   // NVDIMM flags - need to be filled.
> +  0,   // Reserved.
> +};
> +
> +EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE NFITTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE,
> +    0, /* need fill in */
> +    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION
> +    ),
> +  0x00000000, // Reserved
> +};
> +
> +NVDIMM_DATA NvdData[PLATFORM_CPU_MAX_SOCKET] = { 0 };
> +
> +EFI_STATUS
> +AcpiNvdInfoInit (
> +  IN OUT NVDIMM_INFO *NvdInfoPtr,
> +  IN     UINTN       NvdId
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  VOID               *Hob;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL || NvdInfoPtr == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  NvdInfoPtr->Enabled = TRUE;
> +  NvdInfoPtr->PhysId = NvdId;
> +  NvdInfoPtr->NvdSize = PlatformHob->DimmList.Dimm[NvdId].Info.DimmSize * ONE_GB;
> +  NvdInfoPtr->VendorId =
> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[320]);
> +  NvdInfoPtr->DeviceId =
> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[192]);
> +  NvdInfoPtr->RevisionId =
> +    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[349];
> +  NvdInfoPtr->SubVendorId =
> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[194]);
> +  NvdInfoPtr->SubDeviceId =
> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[196]);
> +  NvdInfoPtr->SubRevisionId =
> +    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[198];
> +  NvdInfoPtr->SerialNumber =
> +    *((UINT32 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[325]);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AcpiNvdDataInit (
> +  IN UINTN Socket
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  NVDIMM_INFO        *NvdInfo;
> +  UINTN              Count;
> +  VOID               *Hob;
> +  UINTN              NvdRegionNum, RegionId;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  NvdRegionNum = 0;
> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +    if (PlatformHob->DramInfo.NvdRegion[Count] != 0
> +        && (PlatformHob->DramInfo.Socket[Count] == Socket))
> +    {
> +      NvdData[Socket].NvdRegionId[NvdRegionNum] = Count;
> +      NvdRegionNum++;
> +    }
> +  }
> +  if (NvdRegionNum == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  NvdData[Socket].NvdRegionNum = NvdRegionNum;
> +  NvdData[Socket].NvdMode = PlatformHob->DramInfo.NvdimmMode[Socket];
> +  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
> +    NvdInfo = &NvdData[Socket].NvdInfo[NVDIMM_SK0];
> +    NvdInfo->DeviceHandle   =
> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
> +      PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
> +    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
> +    NvdInfo->RegionOffset   = 0;
> +    AcpiNvdInfoInit (
> +      NvdInfo,
> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
> +      PLATFORM_NVDIMM_NVD3_DIMM_ID
> +      );
> +
> +    NvdInfo = &NvdData[Socket].NvdInfo[1];
> +    NvdInfo->DeviceHandle   =
> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
> +      PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
> +    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
> +    NvdInfo->RegionOffset   = PLATFORM_NVDIMM_HASHED_REGION_OFFSET;
> +    AcpiNvdInfoInit (
> +      NvdInfo,
> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
> +      PLATFORM_NVDIMM_NVD4_DIMM_ID
> +      );
> +
> +    /* Update NvdNum */
> +    NvdData[Socket].NvdNum = 0;
> +    for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
> +      if (NvdData[Socket].NvdInfo[Count].Enabled) {
> +        NvdData[Socket].NvdNum++;
> +      }
> +    }
> +    return EFI_SUCCESS;
> +  }
> +  /* NVDIMM_NON_HASHED */
> +  NvdData[Socket].NvdNum = 0;
> +  for (Count = 0; Count < NvdData[Socket].NvdRegionNum; Count++) {
> +    RegionId = NvdData[Socket].NvdRegionId[Count];
> +    if (PlatformHob->DramInfo.Base[RegionId] ==
> +        PLATFORM_NVDIMM_SK0_NHASHED_REGION0 ||
> +        PlatformHob->DramInfo.Base[RegionId] ==
> +        PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
> +    {
> +      NvdInfo = &NvdData[Socket].NvdInfo[0];
> +      NvdInfo->DeviceHandle   =
> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
> +        PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
> +      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
> +      NvdInfo->RegionOffset   = 0;
> +      AcpiNvdInfoInit (
> +        NvdInfo,
> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
> +        PLATFORM_NVDIMM_NVD3_DIMM_ID
> +        );
> +
> +    } else if (PlatformHob->DramInfo.Base[RegionId] ==
> +               PLATFORM_NVDIMM_SK0_NHASHED_REGION1 ||
> +               PlatformHob->DramInfo.Base[RegionId] ==
> +               PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
> +    {
> +      NvdInfo = &NvdData[Socket].NvdInfo[1];
> +      NvdInfo->DeviceHandle   =
> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
> +        PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
> +      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
> +      NvdInfo->RegionOffset   = 0;
> +      AcpiNvdInfoInit (
> +        NvdInfo,
> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
> +        PLATFORM_NVDIMM_NVD4_DIMM_ID
> +        );
> +    }
> +  }
> +  /* Update NvdNum */
> +  NvdData[Socket].NvdNum = 0;
> +  for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
> +    if (NvdData[Socket].NvdInfo[Count].Enabled) {
> +      NvdData[Socket].NvdNum++;
> +    }
> +  }
> +  return EFI_SUCCESS;
> +}
> +
> +/*
> + * Fill in SPA structure
> + */
> +VOID
> +AcpiNfitFillSPA (
> +  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
> +  IN     UINTN                                                     NvdRegionIndex,
> +  IN     UINT64                                                    NvdRegionBase,
> +  IN     UINT64                                                    NvdRegionSize
> +  )
> +{
> +  ASSERT (NfitSpaPointer != NULL);
> +
> +  NfitSpaPointer->Flags                            = 0;
> +  NfitSpaPointer->SPARangeStructureIndex           = NvdRegionIndex;
> +  NfitSpaPointer->SystemPhysicalAddressRangeBase   = NvdRegionBase;
> +  NfitSpaPointer->SystemPhysicalAddressRangeLength = NvdRegionSize;
> +}
> +
> +VOID
> +NfitFillControlRegion (
> +  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControlRegionPointer,
> +  IN     NVDIMM_INFO                                       *NvdInfo,
> +  IN     UINTN                                             NvdControlRegionIndex
> +  )
> +{
> +  ASSERT (
> +    NfitControlRegionPointer != NULL
> +    && NvdInfo != NULL
> +    );
> +
> +  NfitControlRegionPointer->NVDIMMControlRegionStructureIndex =
> +    NvdControlRegionIndex;
> +  NfitControlRegionPointer->VendorID = NvdInfo->VendorId;
> +  NfitControlRegionPointer->DeviceID = NvdInfo->DeviceId;
> +  NfitControlRegionPointer->RevisionID = NvdInfo->RevisionId;
> +  NfitControlRegionPointer->SubsystemVendorID = NvdInfo->SubVendorId;
> +  NfitControlRegionPointer->SubsystemDeviceID = NvdInfo->SubDeviceId;
> +  NfitControlRegionPointer->SubsystemRevisionID = NvdInfo->SubRevisionId;
> +  NfitControlRegionPointer->SerialNumber = NvdInfo->SerialNumber;
> +}
> +
> +VOID
> +NfitFillRegionMapping (
> +  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer,
> +  IN     EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer,
> +  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
> +  IN     NVDIMM_INFO                                               *NvdInfo,
> +  IN     UINTN                                                     NvdRegionID
> +  )
> +{
> +  ASSERT (
> +    NfitRegionMappingPointer != NULL
> +    && NfitRegionMappingPointer != NULL
> +    && NfitRegionMappingPointer != NULL
> +    && NfitRegionMappingPointer != NULL
> +    && NvdInfo != NULL
> +    );
> +
> +  NfitRegionMappingPointer->NVDIMMRegionID = NvdRegionID;
> +  NfitRegionMappingPointer->NVDIMMPhysicalID = NvdInfo->PhysId;
> +  NfitRegionMappingPointer->InterleaveWays = NvdInfo->InterleaveWays;
> +  NfitRegionMappingPointer->RegionOffset = NvdInfo->RegionOffset;
> +  NfitRegionMappingPointer->NVDIMMRegionSize = NvdInfo->NvdSize;
> +  NfitRegionMappingPointer->NFITDeviceHandle.DIMMNumber =
> +    NvdInfo->DeviceHandle & 0x0F;
> +  NfitRegionMappingPointer->NFITDeviceHandle.MemoryChannelNumber =
> +    (NvdInfo->DeviceHandle >> 4) & 0x0F;
> +  NfitRegionMappingPointer->NFITDeviceHandle.MemoryControllerID =
> +    (NvdInfo->DeviceHandle >> 8) & 0x0F;
> +  NfitRegionMappingPointer->NFITDeviceHandle.SocketID =
> +    (NvdInfo->DeviceHandle >> 12) & 0x0F;
> +  NfitRegionMappingPointer->SPARangeStructureIndex =
> +    NfitSpaPointer->SPARangeStructureIndex;
> +  NfitRegionMappingPointer->NVDIMMPhysicalAddressRegionBase =
> +    NfitSpaPointer->SystemPhysicalAddressRangeBase;
> +  NfitRegionMappingPointer->NVDIMMControlRegionStructureIndex =
> +    NfitControlRegionPointer->NVDIMMControlRegionStructureIndex;
> +}
> +
> +EFI_STATUS
> +AcpiNfitFillTableBySK (
> +  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerStart,
> +  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE **NfitSpaPointerNext,
> +  IN     UINTN                                                     Socket
> +  )
> +{
> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer;
> +  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer;
> +  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer;
> +  PLATFORM_INFO_HOB                                         *PlatformHob;
> +  VOID                                                      *Hob;
> +  UINT64                                                    NvdRegionBase,
> +                                                            NvdRegionSize;
> +  UINTN NvdCount, MaxNvdCount, RegionCount;
> +  UINTN RegionId, NvdRegionIndex, NvdIndex;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL
> +      || NfitSpaPointerStart == NULL
> +      || NfitSpaPointerNext == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PlatformHob    = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +  NvdRegionIndex = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdRegionNum;
> +  NvdIndex       = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdNum;
> +  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
> +    /* Table Type 0: SPA Range Structure */
> +    NfitSpaPointer = NfitSpaPointerStart;
> +    CopyMem (
> +      (VOID *)NfitSpaPointer,
> +      (VOID *)&NfitSPATemplate,
> +      sizeof (NfitSPATemplate)
> +      );
> +    RegionId      = NvdData[Socket].NvdRegionId[0];
> +    NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
> +    NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
> +    NvdRegionIndex++;
> +    AcpiNfitFillSPA (
> +      NfitSpaPointer,
> +      NvdRegionIndex,
> +      NvdRegionBase,
> +      NvdRegionSize
> +      );
> +
> +    NfitControlRegionPointer =
> +      (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
> +      (NfitSpaPointer + 1);
> +    for (NvdCount = 0; NvdCount < NVDIMM_NUM_PER_SK; NvdCount++) {
> +      if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
> +        continue;
> +      }
> +      NvdIndex++;
> +      /* Table Type 4: NVDIMM Control Region Structure Mark */
> +      CopyMem (
> +        (VOID *)NfitControlRegionPointer,
> +        (VOID *)&NvdimmControlRegionTemplate,
> +        sizeof (NvdimmControlRegionTemplate)
> +        );
> +      NfitFillControlRegion (
> +        NfitControlRegionPointer,
> +        &NvdData[Socket].NvdInfo[NvdCount],
> +        NvdIndex
> +        );
> +
> +      NfitRegionMappingPointer =
> +        (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
> +        (NfitControlRegionPointer + 1);
> +
> +      /* Table Type 1: NVDIMM Region Mapping Structure */
> +      CopyMem (
> +        (VOID *)NfitRegionMappingPointer,
> +        (VOID *)&NvdimmRegionMappingTemplate,
> +        sizeof (NvdimmRegionMappingTemplate)
> +        );
> +      NfitFillRegionMapping (
> +        NfitRegionMappingPointer,
> +        NfitControlRegionPointer,
> +        NfitSpaPointer,
> +        &NvdData[Socket].NvdInfo[NvdCount],
> +        NvdIndex - 1
> +        );
> +
> +      NfitControlRegionPointer =
> +        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
> +        (NfitRegionMappingPointer + 1);
> +    }
> +    NfitSpaPointer =
> +      (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
> +      NfitControlRegionPointer;
> +  } else { /* NVDIMM_NON_HASHED */
> +    NfitSpaPointer = NfitSpaPointerStart;
> +    for (RegionCount = 0; RegionCount < NvdData[Socket].NvdRegionNum;
> +         RegionCount++)
> +    {
> +      /* Table Type 0: SPA Range Structure */
> +      CopyMem (
> +        (VOID *)NfitSpaPointer,
> +        (VOID *)&NfitSPATemplate,
> +        sizeof (NfitSPATemplate)
> +        );
> +      RegionId      = NvdData[Socket].NvdRegionId[RegionCount];
> +      NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
> +      NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
> +      NvdRegionIndex++;
> +      AcpiNfitFillSPA (
> +        NfitSpaPointer,
> +        NvdRegionIndex,
> +        NvdRegionBase,
> +        NvdRegionSize
> +        );
> +
> +      NfitControlRegionPointer =
> +        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
> +        (NfitSpaPointer + 1);
> +      NvdCount = ((NvdRegionBase == PLATFORM_NVDIMM_SK0_NHASHED_REGION0) ||
> +                  (NvdRegionBase == PLATFORM_NVDIMM_SK1_NHASHED_REGION0)) ?
> +                 0 : PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
> +      MaxNvdCount = NvdCount + PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
> +      for (; NvdCount < MaxNvdCount; NvdCount++) {
> +        if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
> +          continue;
> +        }
> +        NvdIndex++;
> +
> +        /* Table Type 4: NVDIMM Control Region Structure Mark */
> +        CopyMem (
> +          (VOID *)NfitControlRegionPointer,
> +          (VOID *)&NvdimmControlRegionTemplate,
> +          sizeof (NvdimmControlRegionTemplate)
> +          );
> +        NfitFillControlRegion (
> +          NfitControlRegionPointer,
> +          &NvdData[Socket].NvdInfo[NvdCount],
> +          NvdIndex
> +          );
> +
> +        NfitRegionMappingPointer =
> +          (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
> +          (NfitControlRegionPointer + 1);
> +
> +        /* Table Type 1: NVDIMM Region Mapping Structure */
> +        CopyMem (
> +          (VOID *)NfitRegionMappingPointer,
> +          (VOID *)&NvdimmRegionMappingTemplate,
> +          sizeof (NvdimmRegionMappingTemplate)
> +          );
> +        NfitFillRegionMapping (
> +          NfitRegionMappingPointer,
> +          NfitControlRegionPointer,
> +          NfitSpaPointer,
> +          &NvdData[Socket].NvdInfo[NvdCount],
> +          NvdIndex - 1
> +          );
> +
> +        NfitControlRegionPointer =
> +          (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
> +          (NfitRegionMappingPointer + 1);
> +      }
> +      NfitSpaPointer =
> +        (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
> +        NfitControlRegionPointer;
> +    }
> +  }
> +  /* Update NfitSpaPointerNext */
> +  *NfitSpaPointerNext = NfitSpaPointer;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AcpiNfitFillTable (
> +  IN EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer
> +  )
> +{
> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerNext;
> +
> +  if (NfitTablePointer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  NfitSpaPointerNext = (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
> +                       (NfitTablePointer + 1);
> +
> +  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
> +    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK0);
> +  }
> +
> +  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
> +    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK1);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/*
> + * Install NFIT table.
> + */
> +EFI_STATUS
> +AcpiInstallNfitTable (
> +  VOID
> +  )
> +{
> +  EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer;
> +  EFI_ACPI_TABLE_PROTOCOL                      *AcpiTableProtocol;
> +  UINTN                                        NfitTableKey  = 0;
> +  EFI_STATUS                                   Status;
> +  UINTN                                        Size;
> +  UINTN                                        NvdRegionNum;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = AcpiNvdDataInit (NVDIMM_SK0);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Status = AcpiNvdDataInit (NVDIMM_SK1);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  NvdRegionNum = NvdData[NVDIMM_SK0].NvdRegionNum +
> +                 NvdData[NVDIMM_SK1].NvdRegionNum;
> +  if (NvdRegionNum == 0) {
> +    return EFI_INVALID_PARAMETER; /* No NVDIMM Region */
> +  }
> +  Size = sizeof (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE);
> +  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
> +    Size +=
> +      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
> +       NvdData[NVDIMM_SK0].NvdRegionNum) +
> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
> +       NvdData[NVDIMM_SK0].NvdNum) +
> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
> +       NvdData[NVDIMM_SK0].NvdNum);
> +  }
> +  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
> +    Size +=
> +      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
> +       NvdData[NVDIMM_SK1].NvdRegionNum) +
> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
> +       NvdData[NVDIMM_SK1].NvdNum) +
> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
> +       NvdData[NVDIMM_SK1].NvdNum);
> +  }
> +  NfitTablePointer =
> +    (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *)AllocateZeroPool (Size);
> +  if (NfitTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyMem (
> +    (VOID *)NfitTablePointer,
> +    (VOID *)&NFITTableHeaderTemplate,
> +    sizeof (NFITTableHeaderTemplate)
> +    );
> +
> +  NfitTablePointer->Header.Length = Size;
> +
> +  Status = AcpiNfitFillTable (NfitTablePointer);
> +  if (EFI_ERROR (Status)) {
> +    FreePool ((VOID *)NfitTablePointer);
> +    return Status;
> +  }
> +  AcpiTableChecksum (
> +    (UINT8 *)NfitTablePointer,
> +    NfitTablePointer->Header.Length
> +    );
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)NfitTablePointer,
> +                                NfitTablePointer->Header.Length,
> +                                &NfitTableKey
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    FreePool ((VOID *)NfitTablePointer);
> +  }
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
> new file mode 100644
> index 000000000000..296ae57aada0
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
> @@ -0,0 +1,196 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/AcpiPccLib.h>
> +#include "AcpiPlatform.h"
> +
> +EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS PcctSubspaceTemplate = {
> +  EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS,
> +  sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS),
> +  0,                        // PlatformInterrupt
> +  0,                        // PlatformInterruptFlags
> +  0,                        // Reserved
> +  0,                        // BaseAddress
> +  0x100,                    // AddressLength
> +  { 0, 0x20, 0, 0x3, 0x0 }, // DoorbellRegister
> +  0,                        // DoorbellPreserve
> +  0x53000040,               // DoorbellWrite
> +  1,                        // NominalLatency
> +  1,                        // MaximumPeriodicAccessRate
> +  1,                        // MinimumRequestTurnaroundTime
> +  { 0, 0x20, 0, 0x3, 0x0 }, // PlatformInterruptAckRegister
> +  0,                        // PlatformInterruptAckPreserve
> +  0x10001,                  // PlatformInterruptAckWrite
> +};
> +
> +EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER PcctTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER,
> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION
> +    ),
> +  EFI_ACPI_6_3_PCCT_FLAGS_PLATFORM_INTERRUPT,
> +};
> +
> +EFI_STATUS
> +AcpiPcctInit (
> +  VOID
> +  )
> +{
> +  UINT8  NumberOfSockets;
> +  UINT8  Socket;
> +  UINT16 Doorbell;
> +  UINT16 Subspace;
> +
> +  NumberOfSockets = GetNumberOfActiveSockets ();
> +  Subspace = 0;
> +
> +  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
> +    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
> +      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
> +        continue;
> +      }
> +      AcpiPccInitSharedMemory (Socket, Doorbell, Subspace);
> +      AcpiPccUnmaskDoorbellInterrupt (Socket, Doorbell);
> +
> +      Subspace++;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Install PCCT table.
> +
> +  Each socket has 16 PCC subspaces corresponding to 16 Mailbox/Doorbell channels
> +    0 - 7  : PMpro subspaces
> +    8 - 15 : SMpro subspaces
> +
> +  Please note that some SMpro/PMpro Doorbell are reserved for private use.
> +  The reserved Doorbells are filtered by using the ACPI_PCC_AVAILABLE_DOORBELL_MASK
> +  and ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS macro.
> +
> +**/
> +EFI_STATUS
> +AcpiInstallPcctTable (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                                               Status;
> +  EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *PcctTablePointer;
> +  EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS   *PcctEntryPointer;
> +  EFI_PHYSICAL_ADDRESS                                     PccSharedMemPointer;
> +  EFI_ACPI_TABLE_PROTOCOL                                  *AcpiTableProtocol;
> +  UINTN                                                    PcctTableKey;
> +  UINT8                                                    NumberOfSockets;
> +  UINT8                                                    Socket;
> +  UINT16                                                   Doorbell;
> +  UINT16                                                   Subspace;
> +  UINT16                                                   NumberOfSubspaces;
> +  UINTN                                                    Size;
> +  UINTN                                                    DoorbellAddress;
> +
> +  Subspace = 0;
> +  NumberOfSockets = GetNumberOfActiveSockets ();
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  NumberOfSubspaces = ACPI_PCC_MAX_SUBPACE_PER_SOCKET * NumberOfSockets;
> +
> +  AcpiPccAllocateSharedMemory (&PccSharedMemPointer, NumberOfSubspaces);
> +  if (PccSharedMemPointer == 0) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
> +          NumberOfSubspaces * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
> +
> +  PcctTablePointer = (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)AllocateZeroPool (Size);
> +  if (PcctTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  PcctEntryPointer = (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)
> +                      ((UINT64)PcctTablePointer + sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER));
> +
> +  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
> +    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
> +      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
> +        continue;
> +      }
> +
> +      CopyMem (
> +        &PcctEntryPointer[Subspace],
> +        &PcctSubspaceTemplate,
> +        sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS)
> +        );
> +
> +      PcctEntryPointer[Subspace].BaseAddress = (UINT64)PccSharedMemPointer + ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace;
> +      PcctEntryPointer[Subspace].AddressLength = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE;
> +
> +      DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
> +
> +      PcctEntryPointer[Subspace].DoorbellRegister.Address = DoorbellAddress + DB_OUT_REG_OFST;
> +      PcctEntryPointer[Subspace].PlatformInterrupt = MailboxGetDoorbellInterruptNumber (Socket, Doorbell);
> +      PcctEntryPointer[Subspace].PlatformInterruptAckRegister.Address = DoorbellAddress + DB_STATUS_REG_OFST;
> +
> +      if (Doorbell == ACPI_PCC_CPPC_DOORBELL_ID) {
> +        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_URGENT_CPPC_MESSAGE;
> +        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_CPPC_NOMINAL_LATENCY_US;
> +        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US;
> +      } else {
> +        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_TYPICAL_PCC_MESSAGE;
> +        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_NOMINAL_LATENCY_US;
> +        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US;
> +      }
> +      PcctEntryPointer[Subspace].MaximumPeriodicAccessRate = ACPI_PCC_MAX_PERIODIC_ACCESS_RATE;
> +
> +      Subspace++;
> +    }
> +  }
> +
> +  CopyMem (
> +    PcctTablePointer,
> +    &PcctTableHeaderTemplate,
> +    sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER)
> +    );
> +
> +  //
> +  // Recalculate the size
> +  //
> +  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
> +          Subspace * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
> +
> +  PcctTablePointer->Header.Length = Size;
> +  AcpiTableChecksum (
> +    (UINT8 *)PcctTablePointer,
> +    PcctTablePointer->Header.Length
> +    );
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)PcctTablePointer,
> +                                PcctTablePointer->Header.Length,
> +                                &PcctTableKey
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    AcpiPccFreeSharedMemory ();
> +    FreePool ((VOID *)PcctTablePointer);
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
> new file mode 100644
> index 000000000000..3ed3e98d00d2
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
> @@ -0,0 +1,178 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiApei.h"
> +#include "AcpiPlatform.h"
> +
> +STATIC EFI_EVENT mAcpiRegistration = NULL;
> +
> +/*
> + * This GUID must match the FILE_GUID in AcpiTables.inf of each boards
> + */
> +STATIC CONST EFI_GUID mAcpiCommonTableFile = { 0xCEFA2AEB, 0x357E, 0x4F48, { 0x80, 0x66, 0xEA, 0x95, 0x08, 0x53, 0x05, 0x6E } } ;
> +STATIC CONST EFI_GUID mJadeAcpiTableFile = { 0x5addbc13, 0x8634, 0x480c, { 0x9b, 0x94, 0x67, 0x1b, 0x78, 0x55, 0xcd, 0xb8 } };
> +/**
> + * Callback called when ACPI Protocol is installed
> + */
> +STATIC VOID
> +AcpiNotificationEvent (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS                                   Status;
> +  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
> +
> +  Status = LocateAndInstallAcpiFromFv (&mAcpiCommonTableFile);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = LocateAndInstallAcpiFromFv (&mJadeAcpiTableFile);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Find ACPI table RSD_PTR from the system table.
> +  //
> +  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);
> +  if (EFI_ERROR (Status)) {
> +    Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);
> +  }
> +
> +  if (!EFI_ERROR (Status) &&
> +      Rsdp != NULL &&
> +      Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION &&
> +      Rsdp->RsdtAddress != 0)
> +  {
> +    // ARM Platforms must set the RSDT address to NULL
> +    Rsdp->RsdtAddress = 0;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "[%a:%d]-\n", __FUNCTION__, __LINE__));
> +}
> +
> +VOID
> +EFIAPI
> +InstallAcpiOnReadyToBoot (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = AcpiInstallMadtTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Installed MADT table\n"));
> +  }
> +
> +  Status = AcpiInstallPpttTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Installed PPTT table\n"));
> +  }
> +
> +  Status = AcpiInstallSlitTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Installed SLIT table\n"));
> +  }
> +
> +  Status = AcpiInstallSratTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Installed SRAT table\n"));
> +  }
> +
> +  Status = AcpiInstallPcctTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Installed PCCT table\n"));
> +  }
> +
> +  Status = AcpiInstallNfitTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Installed NFIT table\n"));
> +  }
> +
> +  Status = AcpiPopulateBert ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "Populate BERT record\n"));
> +  }
> +
> +  //
> +  // Close the event, so it will not be signalled again.
> +  //
> +  gBS->CloseEvent (Event);
> +}
> +
> +VOID
> +EFIAPI
> +UpdateAcpiOnExitBootServices (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = AcpiPatchDsdtTable ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "DSDT Table updated!\n"));
> +  }
> +
> +  // Configure ACPI Platform Error Interfaces
> +  Status = AcpiApeiUpdate ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "APEI Table updated!\n"));
> +  }
> +
> +  // Configure PCC mailbox base address and unmask interrupt
> +  Status = AcpiPcctInit ();
> +  if (!EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_INFO, "PCCT Table updated!\n"));
> +  }
> +
> +  //
> +  // Close the event, so it will not be signalled again.
> +  //
> +  gBS->CloseEvent (Event);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiPlatformDxeInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_EVENT  ReadyToBootEvent;
> +  EFI_EVENT  ExitBootServicesEvent;
> +  EFI_STATUS Status;
> +
> +  EfiCreateProtocolNotifyEvent (
> +    &gEfiAcpiTableProtocolGuid,
> +    TPL_CALLBACK,
> +    AcpiNotificationEvent,
> +    NULL,
> +    &mAcpiRegistration
> +    );
> +
> +  Status = gBS->CreateEvent (
> +                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
> +                  TPL_CALLBACK,
> +                  UpdateAcpiOnExitBootServices,
> +                  NULL,
> +                  &ExitBootServicesEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  InstallAcpiOnReadyToBoot,
> +                  NULL,
> +                  &gEfiEventReadyToBootGuid,
> +                  &ReadyToBootEvent
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
> new file mode 100644
> index 000000000000..97adb66beed3
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
> @@ -0,0 +1,378 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiPlatform.h"
> +
> +EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR PPTTProcessorTemplate = {
> +  EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR,
> +  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR),
> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
> +  {0}, /* Flags */
> +  0,   /* Parent */
> +  0,   /* AcpiProcessorId */
> +  0    /* NumberOfPrivateResources */
> +};
> +
> +EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE PPTTCacheTemplate = {
> +  EFI_ACPI_6_3_PPTT_TYPE_CACHE,
> +  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE),
> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
> +  {0}, /* Flags */
> +  0,   /* NextLevelOfCache */
> +  0,   /* Size */
> +  0,   /* NumberOfSets */
> +  0,   /* Associativity */
> +  {0}, /* Attributes */
> +  0
> +};
> +
> +EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER PPTTTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
> +    0, /* need fill in */
> +    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
> +    ),
> +};
> +
> +STATIC EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *PpttTablePointer;
> +STATIC UINT32                                                  PpttClusterOffset[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET];
> +STATIC UINT32                                                  PpttSocketOffset[PLATFORM_CPU_MAX_SOCKET];
> +STATIC UINT32                                                  PpttRootOffset;
> +STATIC UINT32                                                  PpttL1DataCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
> +STATIC UINT32                                                  PpttL1InstructionCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
> +STATIC UINT32                                                  PpttL2CacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
> +STATIC UINT32                                                  PpttSLCCacheOffset[PLATFORM_CPU_MAX_SOCKET];
> +
> +UINT32
> +AcpiPpttProcessorCoreNode (
> +  VOID   *EntryPointer,
> +  UINT32 CpuId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
> +  UINT32                                *ResPointer;
> +  UINTN                                 ClusterIdPerSocket, CoreIdPerCpm, SocketId;
> +
> +  CopyMem (
> +    PpttProcessorEntryPointer,
> +    &PPTTProcessorTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
> +    );
> +
> +  ClusterIdPerSocket = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM;
> +  SocketId = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) / PLATFORM_CPU_MAX_CPM;
> +  CoreIdPerCpm = CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM;
> +  PpttProcessorEntryPointer->Flags.AcpiProcessorIdValid = 1;
> +  PpttProcessorEntryPointer->Flags.NodeIsALeaf = 1;
> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
> +  PpttProcessorEntryPointer->AcpiProcessorId = (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) | (ClusterIdPerSocket << 8) | CoreIdPerCpm;
> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttClusterOffset[CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM];
> +  PpttProcessorEntryPointer->NumberOfPrivateResources = 2; /* L1I + L1D */
> +
> +  ResPointer = (UINT32 *)((UINT64)EntryPointer +
> +                          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
> +  ResPointer[0] = PpttL1InstructionCacheOffset[CpuId];
> +  ResPointer[1] = PpttL1DataCacheOffset[CpuId];
> +
> +  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32);
> +
> +  return PpttProcessorEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttClusterNode (
> +  VOID   *EntryPointer,
> +  UINT32 ClusterId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
> +
> +  PpttClusterOffset[ClusterId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +
> +  CopyMem (
> +    PpttProcessorEntryPointer,
> +    &PPTTProcessorTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
> +    );
> +
> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttSocketOffset[ClusterId / PLATFORM_CPU_MAX_CPM];
> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
> +
> +  return PpttProcessorEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttSocketNode (
> +  VOID   *EntryPointer,
> +  UINT32 SocketId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
> +  UINT32                                *ResPointer;
> +
> +  PpttSocketOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +
> +  CopyMem (
> +    PpttProcessorEntryPointer,
> +    &PPTTProcessorTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
> +    );
> +
> +  PpttProcessorEntryPointer->Flags.PhysicalPackage = 1;
> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttRootOffset;
> +
> +  PpttProcessorEntryPointer->NumberOfPrivateResources = 1;
> +  ResPointer = (UINT32 *)((UINT64)EntryPointer + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
> +  ResPointer[0] = PpttSLCCacheOffset[SocketId];
> +
> +  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32);
> +
> +  return PpttProcessorEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttRootNode (
> +  VOID *EntryPointer
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
> +
> +  PpttRootOffset = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +
> +  CopyMem (
> +    PpttProcessorEntryPointer,
> +    &PPTTProcessorTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
> +    );
> +
> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
> +
> +  return PpttProcessorEntryPointer->Length;
> +}
> +
> +STATIC VOID
> +AcpiPpttFillCacheSizeInfo (
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *Node,
> +  UINT32                            Level
> +  )
> +{
> +  UINT64 CacheCCSIDR;
> +  UINT32 CacheLineSize;
> +  UINT32 Count;
> +
> +  CacheCCSIDR = ReadCCSIDR (Level);
> +
> +  CacheLineSize = 1;
> +  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
> +  while (Count-- > 0) {
> +    CacheLineSize *= 2;
> +  }
> +
> +  Node->Flags.LineSizeValid = 1;
> +  Node->Flags.NumberOfSetsValid = 1;
> +  Node->Flags.AssociativityValid = 1;
> +  Node->Flags.SizePropertyValid = 1;
> +  Node->Flags.CacheTypeValid = 1;
> +  Node->NumberOfSets = CCSIDR_NUMSETS (CacheCCSIDR) + 1;
> +  Node->Associativity = CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1;
> +  Node->LineSize = CacheLineSize;
> +  Node->Size = Node->NumberOfSets *
> +               Node->Associativity *
> +               Node->LineSize;
> +}
> +
> +STATIC UINT32
> +AcpiPpttL1DataCacheNode (
> +  VOID   *EntryPointer,
> +  UINT32 CpuId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
> +
> +  PpttL1DataCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +  CopyMem (
> +    PpttCacheEntryPointer,
> +    &PPTTCacheTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
> +    );
> +
> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
> +  PpttCacheEntryPointer->Attributes.CacheType = 0x0; /* Data Cache */
> +  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
> +
> +  return PpttCacheEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttL1InstructionCacheNode (
> +  VOID   *EntryPointer,
> +  UINT32 CpuId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
> +
> +  PpttL1InstructionCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +  CopyMem (
> +    PpttCacheEntryPointer,
> +    &PPTTCacheTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
> +    );
> +
> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
> +  PpttCacheEntryPointer->Attributes.CacheType = 0x1; /* Instruction Cache */
> +  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
> +
> +  return PpttCacheEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttL2CacheNode (
> +  VOID   *EntryPointer,
> +  UINT32 CpuId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
> +
> +  PpttL2CacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +  CopyMem (
> +    PpttCacheEntryPointer,
> +    &PPTTCacheTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
> +    );
> +
> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 2);
> +  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
> +  PpttCacheEntryPointer->NextLevelOfCache = 0;
> +
> +  return PpttCacheEntryPointer->Length;
> +}
> +
> +STATIC UINT32
> +AcpiPpttSLCCacheNode (
> +  VOID   *EntryPointer,
> +  UINT32 SocketId
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
> +
> +  PpttSLCCacheOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
> +  CopyMem (
> +    PpttCacheEntryPointer,
> +    &PPTTCacheTemplate,
> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
> +    );
> +
> +  PpttCacheEntryPointer->Flags.LineSizeValid = 1;
> +  PpttCacheEntryPointer->Flags.NumberOfSetsValid = 1;
> +  PpttCacheEntryPointer->Flags.AssociativityValid = 1;
> +  PpttCacheEntryPointer->Flags.SizePropertyValid = 1;
> +  PpttCacheEntryPointer->Flags.CacheTypeValid = 1;
> +
> +  PpttCacheEntryPointer->Size = 0x2000000; /* 32 MB */
> +  PpttCacheEntryPointer->NumberOfSets = 0x400; /* 1024 sets per 1MB HN-F */
> +
> +  PpttCacheEntryPointer->Associativity = 0x10; /* 16-way set-associative */
> +  PpttCacheEntryPointer->LineSize = 0x40; /* 64 bytes */
> +  PpttCacheEntryPointer->NextLevelOfCache = 0;
> +
> +  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
> +
> +  return PpttCacheEntryPointer->Length;
> +}
> +
> +/*
> + *  Install PPTT table.
> + */
> +EFI_STATUS
> +AcpiInstallPpttTable (
> +  VOID
> +  )
> +{
> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = NULL;
> +  EFI_ACPI_TABLE_PROTOCOL               *AcpiTableProtocol;
> +  UINTN                                 PpttTableKey  = 0;
> +  UINTN                                 Count;
> +  EFI_STATUS                            Status;
> +  UINTN                                 Size;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Size = sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER) +
> +          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) +                                                        /* Root node */
> +          (PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                                /* SLC node */
> +          (PLATFORM_CPU_MAX_SOCKET * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32))) +        /* Socket node */
> +          (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)) +     /* Cluster node */
> +          (PLATFORM_CPU_MAX_NUM_CORES * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32))) + /* Core node */
> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1I node */
> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1D node */
> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE));                              /* L2 node */
> +
> +  PpttTablePointer =
> +    (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *)AllocateZeroPool (Size);
> +  if (PpttTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  PpttProcessorEntryPointer =
> +    (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *)((UINT64)PpttTablePointer +
> +                                              sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER));
> +
> +  Size = 0;
> +  Size += AcpiPpttRootNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size));
> +
> +  for (Count = 0; Count < PLATFORM_CPU_MAX_SOCKET; Count++) {
> +    Size += AcpiPpttSLCCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +    Size += AcpiPpttSocketNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +  }
> +
> +  for (Count = 0; Count < PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET; Count++) {
> +    Size += AcpiPpttClusterNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +  }
> +
> +  for (Count = 0; Count < PLATFORM_CPU_MAX_NUM_CORES; Count++) {
> +    Size += AcpiPpttL2CacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +    Size += AcpiPpttL1InstructionCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +    Size += AcpiPpttL1DataCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +    Size += AcpiPpttProcessorCoreNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
> +  }
> +
> +  CopyMem (
> +    PpttTablePointer,
> +    &PPTTTableHeaderTemplate,
> +    sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER)
> +    );
> +
> +  Size += sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER);
> +  PpttTablePointer->Header.Length = Size;
> +
> +  AcpiTableChecksum (
> +    (UINT8 *)PpttTablePointer,
> +    PpttTablePointer->Header.Length
> +    );
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)PpttTablePointer,
> +                                PpttTablePointer->Header.Length,
> +                                &PpttTableKey
> +                                );
> +  FreePool ((VOID *)PpttTablePointer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
> new file mode 100644
> index 000000000000..60acdb9dd5db
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
> @@ -0,0 +1,190 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiPlatform.h"
> +
> +#define MAX_NODES_PER_SOCKET          4
> +#define SELF_DISTANCE                 10
> +#define REMOTE_DISTANCE               20
> +
> +EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER SLITTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,
> +    0, /* need fill in */
> +    EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION
> +    ),
> +  0,
> +};
> +
> +VOID
> +ComputeCoordinatesForNode (
> +  UINTN Node,
> +  UINTN *X,
> +  UINTN *Y
> +  )
> +{
> +  switch (Node) {
> +  case 0:
> +    *X = 0;
> +    *Y = 0;
> +    break;
> +  case 1:
> +    *X = 1;
> +    *Y = 0;
> +    break;
> +  case 2:
> +    *X = 0;
> +    *Y = 1;
> +    break;
> +  case 3:
> +    *X = 1;
> +    *Y = 1;
> +    break;
> +  default:
> +    *X = 0;
> +    *Y = 0;
> +    break;
> +  }
> +}
> +
> +/**
> +  Compute the distance between between two nodes on socket.
> +**/
> +UINT8
> +ComputeSlitDistanceOnSocket (
> +  UINTN Node1,
> +  UINTN Node2
> +  )
> +{
> +  UINTN X1, Y1, X2, Y2;
> +  UINTN XDistance, YDistance;
> +
> +  ComputeCoordinatesForNode (Node1, &X1, &Y1);
> +  ComputeCoordinatesForNode (Node2, &X2, &Y2);
> +
> +  XDistance = ABS ((INTN)(X1 - X2));
> +  YDistance = ABS ((INTN)(Y1 - Y2));
> +
> +  return (UINT8)(XDistance + YDistance + SELF_DISTANCE);
> +}
> +
> +/**
> +  Compute the distance between between two nodes on
> +  different sockets.
> +  Node1 - local socket node number
> +  Node2 - remote socket node number
> +**/
> +UINT8
> +ComputeSlitDistanceOnRemoteSocket (
> +  UINTN LocalNode,
> +  UINTN RemoteNode
> +  )
> +{
> +  UINTN LocalDistance, RemoteDistance;
> +
> +  //
> +  // Mesh forwards traffic between sockets over both CCIX links when going from
> +  // one quadrant to another. For example, memory access from Node 0 to Node 4
> +  // results in traffic being split between RCA0 and 1. Hence distance is
> +  // different only between upper half and lower half of sockets and not
> +  // between quadrants. Hemisphere configuration is not impacted as there
> +  // is no upper-half.
> +  //
> +  LocalDistance = 0;
> +  RemoteDistance = 0;
> +  if (LocalNode >= (MAX_NODES_PER_SOCKET / 2)) {
> +    LocalDistance = 1;
> +  }
> +  if (RemoteNode >= (MAX_NODES_PER_SOCKET / 2)) {
> +    RemoteDistance = 1;
> +  }
> +
> +  return (UINT8)(LocalDistance + RemoteDistance + REMOTE_DISTANCE);
> +}
> +
> +UINT8
> +ComputeSlitDistance (
> +  UINTN Node1,
> +  UINTN Node2,
> +  UINTN DomainsPerSocket
> +  )
> +{
> +  UINT8 Distance;
> +
> +  Distance = 0;
> +  if ((Node1 / DomainsPerSocket) == (Node2 / DomainsPerSocket)) {
> +    Distance = ComputeSlitDistanceOnSocket (
> +                 Node1 % DomainsPerSocket,
> +                 Node2 % DomainsPerSocket
> +                 );
> +  } else {
> +    Distance = ComputeSlitDistanceOnRemoteSocket (
> +                 Node1 % DomainsPerSocket,
> +                 Node2 % DomainsPerSocket
> +                 );
> +  }
> +
> +  return Distance;
> +}
> +
> +EFI_STATUS
> +AcpiInstallSlitTable (
> +  VOID
> +  )
> +{
> +  EFI_ACPI_TABLE_PROTOCOL                                        *AcpiTableProtocol;
> +  EFI_STATUS                                                     Status;
> +  UINTN                                                          NumDomain, Count, Count1;
> +  EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *SlitTablePointer;
> +  UINT8                                                          *TmpPtr;
> +  UINTN                                                          SlitTableKey;
> +  UINTN                                                          NumDomainPerSocket;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  NumDomainPerSocket = CpuGetNumberOfSubNumaRegion ();
> +  NumDomain = NumDomainPerSocket * GetNumberOfActiveSockets ();
> +
> +  SlitTablePointer = (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *)
> +                     AllocateZeroPool (sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain);
> +  if (SlitTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyMem ((VOID *)SlitTablePointer, (VOID *)&SLITTableHeaderTemplate, sizeof (SLITTableHeaderTemplate));
> +  SlitTablePointer->NumberOfSystemLocalities = NumDomain;
> +  TmpPtr = (UINT8 *)SlitTablePointer + sizeof (SLITTableHeaderTemplate);
> +  for (Count = 0; Count < NumDomain; Count++) {
> +    for (Count1 = 0; Count1 < NumDomain; Count1++, TmpPtr++) {
> +      *TmpPtr = ComputeSlitDistance (Count, Count1, NumDomainPerSocket);
> +    }
> +  }
> +
> +  SlitTablePointer->Header.Length = sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain;
> +
> +  AcpiTableChecksum (
> +    (UINT8 *)SlitTablePointer,
> +    SlitTablePointer->Header.Length
> +    );
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)SlitTablePointer,
> +                                SlitTablePointer->Header.Length,
> +                                &SlitTableKey
> +                                );
> +  FreePool ((VOID *)SlitTablePointer);
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
> new file mode 100644
> index 000000000000..5f3b7007623a
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
> @@ -0,0 +1,274 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/ArmMpCoreInfo.h>
> +#include "AcpiPlatform.h"
> +
> +EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER SRATTableHeaderTemplate = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
> +    0, /* need fill in */
> +    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION
> +    ),
> +  0x00000001,
> +  0x0000000000000000,
> +};
> +
> +EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE GicItsAffinityTemplate = {
> +  .Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY,
> +  sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE),
> +  .ProximityDomain = 0, /* ProximityDomain */
> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
> +  .ItsId = 0,
> +};
> +
> +STATIC
> +UINTN
> +SratCalculateNumMemoryRegion (
> +  VOID
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  UINTN              Count;
> +  UINT64             TmpVal;
> +  VOID               *Hob;
> +  UINTN              Result;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return 0;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  Result = 0;
> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +    TmpVal = PlatformHob->DramInfo.Size[Count];
> +    if (TmpVal > 0) {
> +      Result++;
> +    }
> +  }
> +
> +  return Result;
> +}
> +
> +STATIC
> +EFI_STATUS
> +SratAddMemAffinity (
> +  EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *SratMemAffinity
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  UINTN              Count, NumRegion;
> +  UINT64             RegionSize, RegionBase;
> +  VOID               *Hob;
> +  UINTN              ProximityDomain;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  NumRegion = 0;
> +
> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
> +    RegionSize = PlatformHob->DramInfo.Size[Count];
> +    RegionBase = PlatformHob->DramInfo.Base[Count];
> +    ProximityDomain = PlatformHob->DramInfo.Node[Count];
> +    if (RegionSize > 0) {
> +      ZeroMem ((VOID *)&SratMemAffinity[NumRegion], sizeof (SratMemAffinity[NumRegion]));
> +      SratMemAffinity[NumRegion].Flags = EFI_ACPI_6_3_MEMORY_ENABLED;
> +      if (PlatformHob->DramInfo.NvdRegion[Count] != 0) {
> +        /* Mark NVDIMM-N region as HOT_PLUGGABLE and NON-VOLATILE */
> +        SratMemAffinity[NumRegion].Flags |= EFI_ACPI_6_3_MEMORY_HOT_PLUGGABLE |
> +                                            EFI_ACPI_6_3_MEMORY_NONVOLATILE;
> +      }
> +      SratMemAffinity[NumRegion].LengthLow =
> +        (UINT32)(RegionSize & 0xFFFFFFFF);
> +      SratMemAffinity[NumRegion].LengthHigh =
> +        (UINT32)((RegionSize & 0xFFFFFFFF00000000ULL) >> 32);
> +      SratMemAffinity[NumRegion].AddressBaseLow =
> +        (UINT32)(RegionBase & 0xFFFFFFFF);
> +      SratMemAffinity[NumRegion].AddressBaseHigh =
> +        (UINT32)((RegionBase & 0xFFFFFFFF00000000ULL) >> 32);
> +      SratMemAffinity[NumRegion].ProximityDomain = (UINT32)(ProximityDomain);
> +      SratMemAffinity[NumRegion].Type = EFI_ACPI_6_3_MEMORY_AFFINITY;
> +      SratMemAffinity[NumRegion].Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
> +      NumRegion++;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +SratAddGiccAffinity (
> +  EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *SratGiccAffinity
> +  )
> +{
> +  ARM_PROCESSOR_TABLE *ArmProcessorTable;
> +  ARM_CORE_INFO       *ArmCoreInfoTable;
> +  UINTN               Count, NumNode, Idx;
> +  UINT32              AcpiProcessorUid;
> +  UINT8               Socket;
> +  UINT8               Cpm;
> +
> +  for (Idx = 0; Idx < gST->NumberOfTableEntries; Idx++) {
> +    if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Idx].VendorGuid))) {
> +      ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Idx].VendorTable;
> +      ArmCoreInfoTable = ArmProcessorTable->ArmCpus;
> +      break;
> +    }
> +  }
> +
> +  if (Idx == gST->NumberOfTableEntries) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Count = 0;
> +  NumNode = 0;
> +  while (Count != ArmProcessorTable->NumberOfEntries) {
> +    for (Idx = 0; Idx < ArmProcessorTable->NumberOfEntries; Idx++ ) {
> +      Socket = ArmCoreInfoTable[Idx].ClusterId;
> +      Cpm = (ArmCoreInfoTable[Idx].CoreId >> PLATFORM_CPM_UID_BIT_OFFSET);
> +      if (CpuGetSubNumNode (Socket, Cpm) != NumNode) {
> +        /* We add nodes based on ProximityDomain order */
> +        continue;
> +      }
> +      AcpiProcessorUid = (ArmCoreInfoTable[Idx].ClusterId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
> +                         ArmCoreInfoTable[Idx].CoreId;
> +      ZeroMem ((VOID *)&SratGiccAffinity[Count], sizeof (SratGiccAffinity[Count]));
> +      SratGiccAffinity[Count].AcpiProcessorUid = AcpiProcessorUid;
> +      SratGiccAffinity[Count].Flags = 1;
> +      SratGiccAffinity[Count].Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
> +      SratGiccAffinity[Count].Type = EFI_ACPI_6_3_GICC_AFFINITY;
> +      SratGiccAffinity[Count].ProximityDomain = CpuGetSubNumNode (Socket, Cpm);
> +      Count++;
> +    }
> +    NumNode++;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC UINT32
> +InstallGicItsAffinity (
> +  VOID   *EntryPointer,
> +  UINT32 Index
> +  )
> +{
> +  EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *ItsAffinityEntryPointer = EntryPointer;
> +  UINTN                                   Size;
> +
> +  Size = sizeof (GicItsAffinityTemplate);
> +  CopyMem (ItsAffinityEntryPointer, &GicItsAffinityTemplate, Size);
> +  return Size;
> +}
> +
> +STATIC
> +EFI_STATUS
> +SratAddGicItsAffinity (
> +  VOID *TmpPtr
> +  )
> +{
> +  UINTN Size = 0;
> +  UINTN Index;
> +
> +  /* Install Gic ITSAffinity */
> +  if (!IsSlaveSocketPresent ()) {
> +    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
> +      GicItsAffinityTemplate.ItsId = Index;
> +      GicItsAffinityTemplate.ProximityDomain = 0;
> +      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
> +    }
> +  }
> +
> +  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
> +    GicItsAffinityTemplate.ItsId = Index;
> +    GicItsAffinityTemplate.ProximityDomain = 0;
> +    Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
> +  }
> +
> +  if (IsSlaveSocketActive ()) {
> +    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
> +      GicItsAffinityTemplate.ItsId = Index;
> +      GicItsAffinityTemplate.ProximityDomain = 1;
> +      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +AcpiInstallSratTable (
> +  VOID
> +  )
> +{
> +  EFI_ACPI_TABLE_PROTOCOL                            *AcpiTableProtocol;
> +  EFI_STATUS                                         Status;
> +  EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratTablePointer;
> +  UINT8                                              *TmpPtr;
> +  UINTN                                              SratTableKey;
> +  UINTN                                              Size;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Size = sizeof (SRATTableHeaderTemplate) +
> +         SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) +
> +         GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) +
> +         ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate));
> +  if (IsSlaveSocketActive ()) {
> +    Size += (SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate);
> +  } else if (!IsSlaveSocketPresent ()) {
> +    Size += 2 * sizeof (GicItsAffinityTemplate); /* RCA0/1 */
> +  }
> +
> +  SratTablePointer = (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)AllocateZeroPool (Size);
> +  if (SratTablePointer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  CopyMem ((VOID *)SratTablePointer, (VOID *)&SRATTableHeaderTemplate, sizeof (SRATTableHeaderTemplate));
> +
> +  TmpPtr = (UINT8 *)SratTablePointer + sizeof (SRATTableHeaderTemplate);
> +  Status = SratAddMemAffinity ((EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)TmpPtr);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  TmpPtr += SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
> +  Status = SratAddGiccAffinity ((EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)TmpPtr);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  TmpPtr += GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
> +  SratAddGicItsAffinity ((VOID *)(UINT64)TmpPtr);
> +  SratTablePointer->Header.Length = Size;
> +
> +  AcpiTableChecksum (
> +    (UINT8 *)SratTablePointer,
> +    SratTablePointer->Header.Length
> +    );
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                (VOID *)SratTablePointer,
> +                                SratTablePointer->Header.Length,
> +                                &SratTableKey
> +                                );
> +  FreePool ((VOID *)SratTablePointer);
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
> new file mode 100755
> index 000000000000..023509412f04
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
> @@ -0,0 +1,5639 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Device(C000) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x0)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 0, 0xFD, 2}
> +  }) // Domain 0
> +}
> +
> +Device(C001) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 1, 0xFD, 2}
> +  }) // Domain 1
> +}
> +
> +Device(C002) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 2, 0xFD, 2}
> +  }) // Domain 2
> +}
> +
> +Device(C003) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 3, 0xFD, 2}
> +  }) // Domain 3
> +}
> +
> +Device(C004) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 4, 0xFD, 2}
> +  }) // Domain 4
> +}
> +
> +Device(C005) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 5, 0xFD, 2}
> +  }) // Domain 5
> +}
> +
> +Device(C006) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 6, 0xFD, 2}
> +  }) // Domain 6
> +}
> +
> +Device(C007) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 7, 0xFD, 2}
> +  }) // Domain 7
> +}
> +
> +Device(C008) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 8, 0xFD, 2}
> +  }) // Domain 8
> +}
> +
> +Device(C009) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 9, 0xFD, 2}
> +  }) // Domain 9
> +}
> +
> +Device(C010) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 10, 0xFD, 2}
> +  }) // Domain 10
> +}
> +
> +Device(C011) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 11, 0xFD, 2}
> +  }) // Domain 11
> +}
> +
> +Device(C012) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 12, 0xFD, 2}
> +  }) // Domain 12
> +}
> +
> +Device(C013) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 13, 0xFD, 2}
> +  }) // Domain 13
> +}
> +
> +Device(C014) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 14, 0xFD, 2}
> +  }) // Domain 14
> +}
> +
> +Device(C015) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 15, 0xFD, 2}
> +  }) // Domain 15
> +}
> +
> +Device(C016) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 16, 0xFD, 2}
> +  }) // Domain 16
> +}
> +
> +Device(C017) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 17, 0xFD, 2}
> +  }) // Domain 17
> +}
> +
> +Device(C018) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 18, 0xFD, 2}
> +  }) // Domain 18
> +}
> +
> +Device(C019) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 19, 0xFD, 2}
> +  }) // Domain 19
> +}
> +
> +Device(C020) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xa00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 20, 0xFD, 2}
> +  }) // Domain 20
> +}
> +
> +Device(C021) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xa01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 21, 0xFD, 2}
> +  }) // Domain 21
> +}
> +
> +Device(C022) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xb00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 22, 0xFD, 2}
> +  }) // Domain 22
> +}
> +
> +Device(C023) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xb01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 23, 0xFD, 2}
> +  }) // Domain 23
> +}
> +
> +Device(C024) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xc00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 24, 0xFD, 2}
> +  }) // Domain 24
> +}
> +
> +Device(C025) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xc01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 25, 0xFD, 2}
> +  }) // Domain 25
> +}
> +
> +Device(C026) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xd00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 26, 0xFD, 2}
> +  }) // Domain 26
> +}
> +
> +Device(C027) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xd01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 27, 0xFD, 2}
> +  }) // Domain 27
> +}
> +
> +Device(C028) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xe00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 28, 0xFD, 2}
> +  }) // Domain 28
> +}
> +
> +Device(C029) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xe01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 29, 0xFD, 2}
> +  }) // Domain 29
> +}
> +
> +Device(C030) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xf00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 30, 0xFD, 2}
> +  }) // Domain 30
> +}
> +
> +Device(C031) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0xf01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 31, 0xFD, 2}
> +  }) // Domain 31
> +}
> +
> +Device(C032) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 32, 0xFD, 2}
> +  }) // Domain 32
> +}
> +
> +Device(C033) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 33, 0xFD, 2}
> +  }) // Domain 33
> +}
> +
> +Device(C034) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 34, 0xFD, 2}
> +  }) // Domain 34
> +}
> +
> +Device(C035) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 35, 0xFD, 2}
> +  }) // Domain 35
> +}
> +
> +Device(C036) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 36, 0xFD, 2}
> +  }) // Domain 36
> +}
> +
> +Device(C037) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 37, 0xFD, 2}
> +  }) // Domain 37
> +}
> +
> +Device(C038) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 38, 0xFD, 2}
> +  }) // Domain 38
> +}
> +
> +Device(C039) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 39, 0xFD, 2}
> +  }) // Domain 39
> +}
> +
> +Device(C040) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 40, 0xFD, 2}
> +  }) // Domain 40
> +}
> +
> +Device(C041) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 41, 0xFD, 2}
> +  }) // Domain 41
> +}
> +
> +Device(C042) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 42, 0xFD, 2}
> +  }) // Domain 42
> +}
> +
> +Device(C043) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 2)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 2)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 2)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 2)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 2)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 2)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 43, 0xFD, 2}
> +  }) // Domain 43
> +}
> +
> +Device(C044) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 44, 0xFD, 2}
> +  }) // Domain 44
> +}
> +
> +Device(C045) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 45, 0xFD, 2}
> +  }) // Domain 45
> +}
> +
> +Device(C046) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 46, 0xFD, 2}
> +  }) // Domain 46
> +}
> +
> +Device(C047) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 47, 0xFD, 2}
> +  }) // Domain 47
> +}
> +
> +Device(C048) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 48, 0xFD, 2}
> +  }) // Domain 48
> +}
> +
> +Device(C049) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 49, 0xFD, 2}
> +  }) // Domain 49
> +}
> +
> +Device(C050) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 50, 0xFD, 2}
> +  }) // Domain 50
> +}
> +
> +Device(C051) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 2)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 51, 0xFD, 2}
> +  }) // Domain 51
> +}
> +
> +Device(C052) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 52, 0xFD, 2}
> +  }) // Domain 52
> +}
> +
> +Device(C053) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 53, 0xFD, 2}
> +  }) // Domain 53
> +}
> +
> +Device(C054) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 54, 0xFD, 2}
> +  }) // Domain 54
> +}
> +
> +Device(C055) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 55, 0xFD, 2}
> +  }) // Domain 5
> +}
> +
> +Device(C056) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 56, 0xFD, 2}
> +  }) // Domain 56
> +}
> +
> +Device(C057) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 57, 0xFD, 2}
> +  }) // Domain 57
> +}
> +
> +Device(C058) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 58, 0xFD, 2}
> +  }) // Domain 58
> +}
> +
> +Device(C059) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 59, 0xFD, 2}
> +  }) // Domain 59
> +}
> +
> +Device(C060) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 60, 0xFD, 2}
> +  }) // Domain 60
> +}
> +
> +Device(C061) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 61, 0xFD, 2}
> +  }) // Domain 61
> +}
> +
> +Device(C062) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 62, 0xFD, 2}
> +  }) // Domain 62
> +}
> +
> +Device(C063) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x1f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 63, 0xFD, 2}
> +  }) // Domain 63
> +}
> +
> +Device(C064) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 64, 0xFD, 2}
> +  }) // Domain 64
> +}
> +
> +Device(C065) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 65, 0xFD, 2}
> +  }) // Domain 65
> +}
> +
> +Device(C066) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 66, 0xFD, 2}
> +  }) // Domain 66
> +}
> +
> +Device(C067) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 67, 0xFD, 2}
> +  }) // Domain 67
> +}
> +
> +Device(C068) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 68, 0xFD, 2}
> +  }) // Domain 68
> +}
> +
> +Device(C069) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 69, 0xFD, 2}
> +  }) // Domain 69
> +}
> +
> +Device(C070) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 70, 0xFD, 2}
> +  }) // Domain 70
> +}
> +
> +Device(C071) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 71, 0xFD, 2}
> +  }) // Domain 71
> +}
> +
> +Device(C072) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 72, 0xFD, 2}
> +  }) // Domain 72
> +}
> +
> +Device(C073) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 73, 0xFD, 2}
> +  }) // Domain 73
> +}
> +
> +Device(C074) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 74, 0xFD, 2}
> +  }) // Domain 74
> +}
> +
> +Device(C075) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 75, 0xFD, 2}
> +  }) // Domain 75
> +}
> +
> +Device(C076) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 76, 0xFD, 2}
> +  }) // Domain 76
> +}
> +
> +Device(C077) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 77, 0xFD, 2}
> +  }) // Domain 77
> +}
> +
> +Device(C078) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 78, 0xFD, 2}
> +  }) // Domain 78
> +}
> +
> +Device(C079) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 79, 0xFD, 2}
> +  }) // Domain 79
> +}
> +
> +Device(C080) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 80, 0xFD, 2}
> +  }) // Domain 80
> +}
> +
> +Device(C081) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 81, 0xFD, 2}
> +  }) // Domain 81
> +}
> +
> +Device(C082) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 82, 0xFD, 2}
> +  }) // Domain 82
> +}
> +
> +Device(C083) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 83, 0xFD, 2}
> +  }) // Domain 83
> +}
> +
> +Device(C084) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 84, 0xFD, 2}
> +  }) // Domain 84
> +}
> +
> +Device(C085) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 85, 0xFD, 2}
> +  }) // Domain 85
> +}
> +
> +Device(C086) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 86, 0xFD, 2}
> +  }) // Domain 86
> +}
> +
> +Device(C087) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 87, 0xFD, 2}
> +  }) // Domain 87
> +}
> +
> +Device(C088) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 88, 0xFD, 2}
> +  }) // Domain 88
> +}
> +
> +Device(C089) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 89, 0xFD, 2}
> +  }) // Domain 89
> +}
> +
> +Device(C090) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 90, 0xFD, 2}
> +  }) // Domain 90
> +}
> +
> +Device(C091) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 91, 0xFD, 2}
> +  }) // Domain 91
> +}
> +
> +Device(C092) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 92, 0xFD, 2}
> +  }) // Domain 92
> +}
> +
> +Device(C093) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 93, 0xFD, 2}
> +  }) // Domain 93
> +}
> +
> +Device(C094) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 94, 0xFD, 2}
> +  }) // Domain 94
> +}
> +
> +Device(C095) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x2f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 95, 0xFD, 2}
> +  }) // Domain 95
> +}
> +
> +Device(C096) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 96, 0xFD, 2}
> +  }) // Domain 96
> +}
> +
> +Device(C097) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 97, 0xFD, 2}
> +  }) // Domain 97
> +}
> +
> +Device(C098) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 98, 0xFD, 2}
> +  }) // Domain 98
> +}
> +
> +Device(C099) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 99, 0xFD, 2}
> +  }) // Domain 99
> +}
> +
> +Device(C100) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 100, 0xFD, 2}
> +  }) // Domain 100
> +}
> +
> +Device(C101) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 101, 0xFD, 2}
> +  }) // Domain 101
> +}
> +
> +Device(C102) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 102, 0xFD, 2}
> +  }) // Domain 102
> +}
> +
> +Device(C103) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 103, 0xFD, 2}
> +  }) // Domain 103
> +}
> +
> +Device(C104) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 104, 0xFD, 2}
> +  }) // Domain 104
> +}
> +
> +Device(C105) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 105, 0xFD, 2}
> +  }) // Domain 105
> +}
> +
> +Device(C106) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 106, 0xFD, 2}
> +  }) // Domain 106
> +}
> +
> +Device(C107) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 107, 0xFD, 2}
> +  }) // Domain 107
> +}
> +
> +Device(C108) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 108, 0xFD, 2}
> +  }) // Domain 108
> +}
> +
> +Device(C109) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 109, 0xFD, 2}
> +  }) // Domain 109
> +}
> +
> +Device(C110) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 110, 0xFD, 2}
> +  }) // Domain 110
> +}
> +
> +Device(C111) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 111, 0xFD, 2}
> +  }) // Domain 111
> +}
> +
> +Device(C112) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 112, 0xFD, 2}
> +  }) // Domain 112
> +}
> +
> +Device(C113) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 113, 0xFD, 2}
> +  }) // Domain 113
> +}
> +
> +Device(C114) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 114, 0xFD, 2}
> +  }) // Domain 114
> +}
> +
> +Device(C115) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 115, 0xFD, 2}
> +  }) // Domain 115
> +}
> +
> +Device(C116) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 116, 0xFD, 2}
> +  }) // Domain 116
> +}
> +
> +Device(C117) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 117, 0xFD, 2}
> +  }) // Domain 117
> +}
> +
> +Device(C118) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 118, 0xFD, 2}
> +  }) // Domain 118
> +}
> +
> +Device(C119) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 119, 0xFD, 2}
> +  }) // Domain 119
> +}
> +
> +Device(C120) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 120, 0xFD, 2}
> +  }) // Domain 120
> +}
> +
> +Device(C121) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 121, 0xFD, 2}
> +  }) // Domain 121
> +}
> +
> +Device(C122) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 122, 0xFD, 2}
> +  }) // Domain 122
> +}
> +
> +Device(C123) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 123, 0xFD, 2}
> +  }) // Domain 123
> +}
> +
> +Device(C124) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 124, 0xFD, 2}
> +  }) // Domain 124
> +}
> +
> +Device(C125) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 125, 0xFD, 2}
> +  }) // Domain 125
> +}
> +
> +Device(C126) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 126, 0xFD, 2}
> +  }) // Domain 126
> +}
> +
> +Device(C127) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x3f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 127, 0xFD, 2}
> +  }) // Domain 127
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
> new file mode 100755
> index 000000000000..b3cc7a1b00e4
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
> @@ -0,0 +1,5639 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Device(C128) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 128, 0xFD, 2}
> +  }) // Domain 128
> +}
> +
> +Device(C129) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 1219, 0xFD, 2}
> +  }) // Domain 129
> +}
> +
> +Device(C130) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 130, 0xFD, 2}
> +  }) // Domain 130
> +}
> +
> +Device(C131) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 131, 0xFD, 2}
> +  }) // Domain 131
> +}
> +
> +Device(C132) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 132, 0xFD, 2}
> +  }) // Domain 132
> +}
> +
> +Device(C133) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 133, 0xFD, 2}
> +  }) // Domain 133
> +}
> +
> +Device(C134) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 134, 0xFD, 2}
> +  }) // Domain 134
> +}
> +
> +Device(C135) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 135, 0xFD, 2}
> +  }) // Domain 135
> +}
> +
> +Device(C136) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 136, 0xFD, 2}
> +  }) // Domain 136
> +}
> +
> +Device(C137) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 137, 0xFD, 2}
> +  }) // Domain 137
> +}
> +
> +Device(C138) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 138, 0xFD, 2}
> +  }) // Domain 138
> +}
> +
> +Device(C139) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 139, 0xFD, 2}
> +  }) // Domain 139
> +}
> +
> +Device(C140) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 140, 0xFD, 2}
> +  }) // Domain 140
> +}
> +
> +Device(C141) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 141, 0xFD, 2}
> +  }) // Domain 141
> +}
> +
> +Device(C142) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 142, 0xFD, 2}
> +  }) // Domain 142
> +}
> +
> +Device(C143) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 143, 0xFD, 2}
> +  }) // Domain 143
> +}
> +
> +Device(C144) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 144, 0xFD, 2}
> +  }) // Domain 144
> +}
> +
> +Device(C145) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 145, 0xFD, 2}
> +  }) // Domain 145
> +}
> +
> +Device(C146) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 146, 0xFD, 2}
> +  }) // Domain 146
> +}
> +
> +Device(C147) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 147, 0xFD, 2}
> +  }) // Domain 147
> +}
> +
> +Device(C148) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 148, 0xFD, 2}
> +  }) // Domain 148
> +}
> +
> +Device(C149) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 149, 0xFD, 2}
> +  }) // Domain 149
> +}
> +
> +Device(C150) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 150, 0xFD, 2}
> +  }) // Domain 150
> +}
> +
> +Device(C151) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 151, 0xFD, 2}
> +  }) // Domain 151
> +}
> +
> +Device(C152) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 152, 0xFD, 2}
> +  }) // Domain 152
> +}
> +
> +Device(C153) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 153, 0xFD, 2}
> +  }) // Domain 153
> +}
> +
> +Device(C154) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 154, 0xFD, 2}
> +  }) // Domain 154
> +}
> +
> +Device(C155) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 155, 0xFD, 2}
> +  }) // Domain 155
> +}
> +
> +Device(C156) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 156, 0xFD, 2}
> +  }) // Domain 156
> +}
> +
> +Device(C157) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 157, 0xFD, 2}
> +  }) // Domain 157
> +}
> +
> +Device(C158) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 158, 0xFD, 2}
> +  }) // Domain 158
> +}
> +
> +Device(C159) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x10f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 159, 0xFD, 2}
> +  }) // Domain 159
> +}
> +
> +Device(C160) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 160, 0xFD, 2}
> +  }) // Domain 160
> +}
> +
> +Device(C161) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 161, 0xFD, 2}
> +  }) // Domain 161
> +}
> +
> +Device(C162) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 162, 0xFD, 2}
> +  }) // Domain 162
> +}
> +
> +Device(C163) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 163, 0xFD, 2}
> +  }) // Domain 163
> +}
> +
> +Device(C164) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 164, 0xFD, 2}
> +  }) // Domain 164
> +}
> +
> +Device(C165) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 165, 0xFD, 2}
> +  }) // Domain 165
> +}
> +
> +Device(C166) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 166, 0xFD, 2}
> +  }) // Domain 166
> +}
> +
> +Device(C167) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 167, 0xFD, 2}
> +  }) // Domain 167
> +}
> +
> +Device(C168) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 168, 0xFD, 2}
> +  }) // Domain 168
> +}
> +
> +Device(C169) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 169, 0xFD, 2}
> +  }) // Domain 169
> +}
> +
> +Device(C170) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 170, 0xFD, 2}
> +  }) // Domain 170
> +}
> +
> +Device(C171) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 171, 0xFD, 2}
> +  }) // Domain 171
> +}
> +
> +Device(C172) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 172, 0xFD, 2}
> +  }) // Domain 172
> +}
> +
> +Device(C173) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 173, 0xFD, 2}
> +  }) // Domain 173
> +}
> +
> +Device(C174) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 174, 0xFD, 2}
> +  }) // Domain 174
> +}
> +
> +Device(C175) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 175, 0xFD, 2}
> +  }) // Domain 175
> +}
> +
> +Device(C176) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 176, 0xFD, 2}
> +  }) // Domain 176
> +}
> +
> +Device(C177) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 177, 0xFD, 2}
> +  }) // Domain 177
> +}
> +
> +Device(C178) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 178, 0xFD, 2}
> +  }) // Domain 178
> +}
> +
> +Device(C179) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 179, 0xFD, 2}
> +  }) // Domain 179
> +}
> +
> +Device(C180) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 180, 0xFD, 2}
> +  }) // Domain 180
> +}
> +
> +Device(C181) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 181, 0xFD, 2}
> +  }) // Domain 181
> +}
> +
> +Device(C182) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 182, 0xFD, 2}
> +  }) // Domain 182
> +}
> +
> +Device(C183) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 183, 0xFD, 2}
> +  }) // Domain 183
> +}
> +
> +Device(C184) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 184, 0xFD, 2}
> +  }) // Domain 184
> +}
> +
> +Device(C185) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 185, 0xFD, 2}
> +  }) // Domain 185
> +}
> +
> +Device(C186) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 186, 0xFD, 2}
> +  }) // Domain 186
> +}
> +
> +Device(C187) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 187, 0xFD, 2}
> +  }) // Domain 187
> +}
> +
> +Device(C188) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 188, 0xFD, 2}
> +  }) // Domain 188
> +}
> +
> +Device(C189) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 189, 0xFD, 2}
> +  }) // Domain 189
> +}
> +
> +Device(C190) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 190, 0xFD, 2}
> +  }) // Domain 190
> +}
> +
> +Device(C191) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x11f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 191, 0xFD, 2}
> +  }) // Domain 191
> +}
> +
> +Device(C192) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 192, 0xFD, 2}
> +  }) // Domain 192
> +}
> +
> +Device(C193) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 193, 0xFD, 2}
> +  }) // Domain 193
> +}
> +
> +Device(C194) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 194, 0xFD, 2}
> +  }) // Domain 194
> +}
> +
> +Device(C195) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 195, 0xFD, 2}
> +  }) // Domain 195
> +}
> +
> +Device(C196) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 196, 0xFD, 2}
> +  }) // Domain 196
> +}
> +
> +Device(C197) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 197, 0xFD, 2}
> +  }) // Domain 197
> +}
> +
> +Device(C198) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 198, 0xFD, 2}
> +  }) // Domain 198
> +}
> +
> +Device(C199) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 199, 0xFD, 2}
> +  }) // Domain 199
> +}
> +
> +Device(C200) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 200, 0xFD, 2}
> +  }) // Domain 200
> +}
> +
> +Device(C201) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 201, 0xFD, 2}
> +  }) // Domain 201
> +}
> +
> +Device(C202) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 202, 0xFD, 2}
> +  }) // Domain 202
> +}
> +
> +Device(C203) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 203, 0xFD, 2}
> +  }) // Domain 203
> +}
> +
> +Device(C204) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 204, 0xFD, 2}
> +  }) // Domain 204
> +}
> +
> +Device(C205) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 205, 0xFD, 2}
> +  }) // Domain 205
> +}
> +
> +Device(C206) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 206, 0xFD, 2}
> +  }) // Domain 206
> +}
> +
> +Device(C207) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 207, 0xFD, 2}
> +  }) // Domain 207
> +}
> +
> +Device(C208) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 208, 0xFD, 2}
> +  }) // Domain 208
> +}
> +
> +Device(C209) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 209, 0xFD, 2}
> +  }) // Domain 209
> +}
> +
> +Device(C210) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 210, 0xFD, 2}
> +  }) // Domain 210
> +}
> +
> +Device(C211) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 211, 0xFD, 2}
> +  }) // Domain 211
> +}
> +
> +Device(C212) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 212, 0xFD, 2}
> +  }) // Domain 212
> +}
> +
> +Device(C213) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 213, 0xFD, 2}
> +  }) // Domain 213
> +}
> +
> +Device(C214) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 214, 0xFD, 2}
> +  }) // Domain 214
> +}
> +
> +Device(C215) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 215, 0xFD, 2}
> +  }) // Domain 215
> +}
> +
> +Device(C216) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 216, 0xFD, 2}
> +  }) // Domain 216
> +}
> +
> +Device(C217) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 217, 0xFD, 2}
> +  }) // Domain 217
> +}
> +
> +Device(C218) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 218, 0xFD, 2}
> +  }) // Domain 218
> +}
> +
> +Device(C219) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 219, 0xFD, 2}
> +  }) // Domain 219
> +}
> +
> +Device(C220) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 220, 0xFD, 2}
> +  }) // Domain 220
> +}
> +
> +Device(C221) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 221, 0xFD, 2}
> +  }) // Domain 221
> +}
> +
> +Device(C222) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 222, 0xFD, 2}
> +  }) // Domain 222
> +}
> +
> +Device(C223) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x12f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 17)},         // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 17)},         // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 17)},         // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 17)},         // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 17)},         // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 17)},         // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 17)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 17)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 17)},         // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 17)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 17)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 223, 0xFD, 2}
> +  }) // Domain 223
> +}
> +
> +Device(C224) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13000)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 224, 0xFD, 2}
> +  }) // Domain 224
> +}
> +
> +Device(C225) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13001)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 225, 0xFD, 2}
> +  }) // Domain 225
> +}
> +
> +Device(C226) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13100)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 226, 0xFD, 2}
> +  }) // Domain 226
> +}
> +
> +Device(C227) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13101)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 227, 0xFD, 2}
> +  }) // Domain 227
> +}
> +
> +Device(C228) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13200)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 228, 0xFD, 2}
> +  }) // Domain 228
> +}
> +
> +Device(C229) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13201)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 229, 0xFD, 2}
> +  }) // Domain 229
> +}
> +
> +Device(C230) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13300)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 230, 0xFD, 2}
> +  }) // Domain 230
> +}
> +
> +Device(C231) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13301)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 231, 0xFD, 2}
> +  }) // Domain 231
> +}
> +
> +Device(C232) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13400)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 232, 0xFD, 2}
> +  }) // Domain 232
> +}
> +
> +Device(C233) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13401)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 233, 0xFD, 2}
> +  }) // Domain 233
> +}
> +
> +Device(C234) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13500)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 234, 0xFD, 2}
> +  }) // Domain 234
> +}
> +
> +Device(C235) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13501)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 235, 0xFD, 2}
> +  }) // Domain 235
> +}
> +
> +Device(C236) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13600)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 236, 0xFD, 2}
> +  }) // Domain 236
> +}
> +
> +Device(C237) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13601)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 237, 0xFD, 2}
> +  }) // Domain 237
> +}
> +
> +Device(C238) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13700)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 238, 0xFD, 2}
> +  }) // Domain 238
> +}
> +
> +Device(C239) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13701)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 239, 0xFD, 2}
> +  }) // Domain 239
> +}
> +
> +Device(C240) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13800)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 240, 0xFD, 2}
> +  }) // Domain 240
> +}
> +
> +Device(C241) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13801)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 241, 0xFD, 2}
> +  }) // Domain 241
> +}
> +
> +Device(C242) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13900)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 242, 0xFD, 2}
> +  }) // Domain 242
> +}
> +
> +Device(C243) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13901)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 243, 0xFD, 2}
> +  }) // Domain 243
> +}
> +
> +Device(C244) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13a00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 244, 0xFD, 2}
> +  }) // Domain 244
> +}
> +
> +Device(C245) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13a01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 245, 0xFD, 2}
> +  }) // Domain 245
> +}
> +
> +Device(C246) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13b00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 246, 0xFD, 2}
> +  }) // Domain 246
> +}
> +
> +Device(C247) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13b01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 247, 0xFD, 2}
> +  }) // Domain 247
> +}
> +
> +Device(C248) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13c00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 248, 0xFD, 2}
> +  }) // Domain 248
> +}
> +
> +Device(C249) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13c01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 249, 0xFD, 2}
> +  }) // Domain 249
> +}
> +
> +Device(C250) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13d00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 250, 0xFD, 2}
> +  }) // Domain 250
> +}
> +
> +Device(C251) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13d01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 251, 0xFD, 2}
> +  }) // Domain 251
> +}
> +
> +Device(C252) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13e00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 252, 0xFD, 2}
> +  }) // Domain 252
> +}
> +
> +Device(C253) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13e01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 253, 0xFD, 2}
> +  }) // Domain 253
> +}
> +
> +Device(C254) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13f00)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package() {
> +    Package() {5, 0, 254, 0xFD, 2}
> +  }) // Domain 254
> +}
> +
> +Device(C255) {
> +  Name(_HID, "ACPI0007")
> +  Name(_UID, 0x13f01)
> +
> +  Method (_LPI, 0, NotSerialized) {
> +    return(PLPI)
> +  }
> +
> +  Name(PCPC, Package() {
> +    23,                                                         // NumEntries
> +    3,                                                          // Revision
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
> +  })
> +  If (LEqual(CPCE, 0x1)) {
> +    Method (_CPC, 0, NotSerialized) {
> +      return(PCPC)
> +    }
> +  }
> +  //Performance State dependency
> +  Name(_PSD, Package(){
> +    Package() {5, 0, 255, 0xFD, 2}
> +  }) // Domain 255
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
> new file mode 100755
> index 000000000000..00c09340b957
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
> @@ -0,0 +1,127 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Name (CPCE, 1)                       // CPPC Enable
> +Name (LPIE, 0)                       // LPI Enable
> +
> +Method (_OSC, 4, Serialized) {         // _OSC: Operating System Capabilities
> +  CreateDWordField (Arg3, 0x00, STS0)
> +  CreateDWordField (Arg3, 0x04, CAP0)
> +  If (LEqual(Arg0, ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48")) /* Platform-wide Capabilities */) {
> +    If (LNotEqual(Arg1, One)) {
> +      And(STS0, 0xFFFFFFE0, STS0)
> +      Or(STS0, 0x0A, STS0)          // Unrecognized Revision, OSC failure
> +    } Else {
> +      If (LEqual(And(CAP0, 0x100), 0x100)) {
> +        And(CAP0, 0xFFFFFEFF, CAP0) // No support for OS Initiated LPI
> +        And(STS0, 0xFFFFFFE0, STS0)
> +        Or(STS0, 0x12, STS0)
> +      }
> +      If (LEqual(LPIE, 0x1)) {
> +        Or(CAP0, 0x80, CAP0)        // Support for LPI
> +      } Else {
> +        And(CAP0, 0xFFFFFF7F, CAP0) // No support for LPI
> +      }
> +      If (LEqual(CPCE, 0x1)) {
> +        Or(CAP0, 0x40, CAP0)        // Support for CPPCv2
> +      } Else {
> +        And(CAP0, 0xFFFFFFBF, CAP0) // No support for CPPCv2
> +      }
> +    }
> +  } Else {
> +    And(STS0, 0xFFFFFFE0, STS0)
> +    Or(STS0, 0x06, STS0)            // Unrecognized Revision, Unrecognized UUID
> +  }
> +  Return (Arg3)
> +}
> +
> +Name(PLPI, Package() {
> +  0,                     // Version
> +  1,                     // Level Index
> +  2,                     // Count
> +  // WFI for CPU (NS-WFI)
> +  Package() {
> +    1,                   // Min residency (uS)
> +    1,                   // Wake latency (uS)
> +    1,                   // Flags
> +    0,                   // Arch Context Flags
> +    100,                 // Residency Counter Frequency
> +    0,                   // No parent state
> +    ResourceTemplate () {
> +      // Register Entry method
> +      Register (FFixedHW,
> +        0x20,            // Bit Width
> +        0x00,            // Bit Offset
> +        0xFFFFFFFF,      // Address
> +        0x03,            // Access Size
> +      )
> +    },
> +    ResourceTemplate() { // Null Residency Counter
> +      Register (SystemMemory, 0, 0, 0, 0)
> +    },
> +    ResourceTemplate() { // Null Usage Counter
> +      Register (SystemMemory, 0, 0, 0, 0)
> +    },
> +    "Standby",
> +  },
> +  // Retention state for CPU (S-WFI)
> +  Package() {
> +    2,                   // Min residency (uS)
> +    2,                   // Wake latency (uS)
> +    1,                   // Flags
> +    0,                   // Arch Context Flags
> +    100,                 // Residency Counter Frequency
> +    1,                   // Parent node can be in Standby states
> +    ResourceTemplate () {
> +      // Register Entry method
> +      Register (FFixedHW,
> +        0x20,            // Bit Width
> +        0x00,            // Bit Offset
> +        0x00000001,      // Address
> +        0x03,            // Access Size
> +      )
> +    },
> +    ResourceTemplate() { // Null Residency Counter
> +      Register (SystemMemory, 0, 0, 0, 0)
> +    },
> +    ResourceTemplate() { // Null Usage Counter
> +      Register (SystemMemory, 0, 0, 0, 0)
> +    },
> +    "Standby_ATF"
> +  },
> +})
> +
> +Device (SYST) {            // System state
> +  Name(_HID, "ACPI0010")
> +  Name(_UID, 1)
> +  Name (_LPI, Package() {
> +    0,                     // Version
> +    0,                     // Level Index
> +    1,                     // Count
> +    // Retention state for Cluster
> +    Package() {
> +      100,               // Min residency (uS)
> +      100,               // Wake latency (uS)
> +      1,                   // Flags
> +      0,                   // Arch Context Flags
> +      100,                 // Residency Counter Frequency
> +      0,                   // No Parent State
> +      0x02000100,          // Integer Entry method
> +      ResourceTemplate() { // Null Residency Counter
> +        Register (SystemMemory, 0, 0, 0, 0)
> +      },
> +      ResourceTemplate() { // Null Usage Counter
> +        Register (SystemMemory, 0, 0, 0, 0)
> +      },
> +      "Standby"
> +    },
> +  })
> +
> +  Include ("CPU-S0.asi")
> +  Include ("CPU-S1.asi")
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
> new file mode 100755
> index 000000000000..b9e2da79b5ef
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
> @@ -0,0 +1,575 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
> +  //
> +  // Board Model
> +  Name(\BDMD, "Jade Board")
> +  Name(TPMF, 0)  // TPM presence
> +  Name(AERF, 0)  // PCIe AER Firmware-First
> +  Scope(\_SB) {
> +
> +    Include ("CPU.asi")
> +    Include ("PMU.asi")
> +
> +    //
> +    // Hardware Monitor
> +    Device(HM00) {
> +      Name(_HID, "APMC0D29")
> +      Name(_UID, "HWM0")
> +      Name(_DDN, "HWM0")
> +      Name(_CCA, ONE)
> +      Name(_STR, Unicode("Hardware Monitor Device"))
> +      Method(_STA, 0, NotSerialized) {
> +        return (0xF)
> +      }
> +      Name (_DSD, Package () {
> +        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +        Package() {
> +          Package() {"pcc-channel", 14}
> +        }
> +      })
> +    }
> +
> +    //
> +    // Hardware Monitor
> +    Device(HM01) {
> +      Name(_HID, "APMC0D29")
> +      Name(_UID, "HWM1")
> +      Name(_DDN, "HWM1")
> +      Name(_CCA, ONE)
> +      Name(_STR, Unicode("Hardware Monitor Device"))
> +      Method(_STA, 0, NotSerialized) {
> +        return (0xF)
> +      }
> +      Name (_DSD, Package () {
> +        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +        Package() {
> +          Package() {"pcc-channel", 29}
> +        }
> +      })
> +    }
> +
> +    //
> +    // Hardware Monitor
> +    Device(HM02) {
> +      Name(_HID, "AMPC0005")
> +      Name(_UID, "HWM2")
> +      Name(_DDN, "HWM2")
> +      Name(_CCA, ONE)
> +      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
> +      Method(_STA, 0, NotSerialized) {
> +        return (0xF)
> +      }
> +      Name(_CRS, ResourceTemplate() {
> +        QWordMemory (
> +          ResourceProducer,     // ResourceUsage
> +          PosDecode,            // Decode
> +          MinFixed,             // IsMinFixed
> +          MaxFixed,             // IsMaxFixed
> +          Cacheable,            // Cacheable
> +          ReadWrite,            // ReadAndWrite
> +          0x0000000000000000,   // AddressGranularity - GRA
> +          0x0000000088900000,   // AddressMinimum - MIN
> +          0x000000008891FFFF,   // AddressMaximum - MAX
> +          0x0000000000000000,   // AddressTranslation - TRA
> +          0x0000000000020000    // RangeLength - LEN
> +        )
> +      })
> +    }
> +
> +    //
> +    // Hardware Monitor
> +    Device(HM03) {
> +      Name(_HID, "AMPC0005")
> +      Name(_UID, "HWM3")
> +      Name(_DDN, "HWM3")
> +      Name(_CCA, ONE)
> +      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
> +      Method(_STA, 0, NotSerialized) {
> +        return (0xF)
> +      }
> +      Name(_CRS, ResourceTemplate() {
> +        QWordMemory (
> +          ResourceProducer,     // ResourceUsage
> +          PosDecode,            // Decode
> +          MinFixed,             // IsMinFixed
> +          MaxFixed,             // IsMaxFixed
> +          Cacheable,            // Cacheable
> +          ReadWrite,            // ReadAndWrite
> +          0x0000000000000000,   // AddressGranularity - GRA
> +          0x0000000088920000,   // AddressMinimum - MIN
> +          0x000000008893FFFF,   // AddressMaximum - MAX
> +          0x0000000000000000,   // AddressTranslation - TRA
> +          0x0000000000020000    // RangeLength - LEN
> +        )
> +      })
> +    }
> +
> +    //
> +    // DesignWare I2C on AHBC bus
> +    Device(I2C4) {
> +      Name(_HID, "APMC0D0F")
> +      Name(_UID, 4)
> +      Name(_STR, Unicode("Altra I2C Device"))
> +      Method(_STA, 0, NotSerialized) {
> +        return (0x0f)
> +      }
> +      Name(_CCA, ONE)
> +      Name(_CRS, ResourceTemplate() {
> +        QWordMemory (
> +          ResourceProducer,     // ResourceUsage
> +          PosDecode,            // Decode
> +          MinFixed,             // IsMinFixed
> +          MaxFixed,             // IsMaxFixed
> +          NonCacheable,         // Cacheable
> +          ReadWrite,            // ReadAndWrite
> +          0x0000000000000000,   // AddressGranularity - GRA
> +          0x00001000026B0000,   // AddressMinimum - MIN
> +          0x00001000026BFFFF,   // AddressMaximum - MAX
> +          0x0000000000000000,   // AddressTranslation - TRA
> +          0x0000000000010000    // RangeLength - LEN
> +        )
> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 105 }
> +      })
> +      Device (IPI) {
> +        Name(_HID, "AMPC0004")
> +        Name(_CID, "IPI0001")
> +        Name(_STR, Unicode("IPMI_SSIF"))
> +        Name(_UID, 0)
> +        Name(_CCA, ONE)
> +        Method(_STA, 0, NotSerialized) {
> +          Return (0x0f)
> +        }
> +        Method(_IFT) {
> +          Return(0x04) // IPMI SSIF
> +        }
> +        Method(_ADR) {
> +          Return(0x10) // SSIF slave address
> +        }
> +        Method(_SRV) {
> +          Return(0x0200) // IPMI Specification Revision
> +        }
> +        Name(_CRS, ResourceTemplate ()
> +        {
> +          I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80,
> +          AddressingMode7Bit, "\\_SB.I2C4",
> +          0x00, ResourceConsumer,,
> +          )
> +        })
> +      }
> +      Name(SSCN, Package() { 0x3E2, 0x47D, 0 })
> +      Name(FMCN, Package() { 0xA4, 0x13F, 0 })
> +    }
> +
> +    //
> +    // Report APEI Errors to GHES via SCI notification.
> +    // SCI notification requires one GED and one HED Device
> +    //     GED = Generic Event Device (ACPI0013)
> +    //     HED = Hardware Error Device (PNP0C33)
> +    //
> +    Device(GED0) {
> +        Name(_HID, "ACPI0013")
> +        Name(_UID, Zero)
> +        Method(_STA) {
> +          Return (0xF)
> +        }
> +        Name(_CRS, ResourceTemplate () {
> +          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 84 } // GHES
> +        })
> +        Method(_EVT, 1, Serialized) {
> +          Switch (ToInteger(Arg0)) {
> +            Case (84) { // GHES interrupt
> +              Notify (HED0, 0x80)
> +            }
> +          }
> +        }
> +    }
> +
> +    // Shutdown button using GED.
> +    Device(GED1) {
> +        Name(_HID, "ACPI0013")
> +        Name(_CID, "ACPI0013")
> +        Name(_UID, One)
> +        Method(_STA) {
> +          Return (0xF)
> +        }
> +        Name(_CRS, ResourceTemplate () {
> +          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 327 }
> +        })
> +        OperationRegion(PDDR, SystemMemory, 0x1000027B0004, 4)
> +        Field(PDDR, DWordAcc, NoLock, Preserve) {
> +          STDI, 8
> +        }
> +
> +        OperationRegion(INTE, SystemMemory, 0x1000027B0030, 4)
> +        Field(INTE, DWordAcc, NoLock, Preserve) {
> +          STDE, 8
> +        }
> +
> +        OperationRegion(INTT, SystemMemory, 0x1000027B0034, 4)
> +        Field(INTT, DWordAcc, NoLock, Preserve) {
> +          TYPE, 8
> +        }
> +
> +        OperationRegion(INTP, SystemMemory, 0x1000027B0038, 4)
> +        Field(INTP, DWordAcc, NoLock, Preserve) {
> +          POLA, 8
> +        }
> +
> +        OperationRegion(INTS, SystemMemory, 0x1000027B003c, 4)
> +        Field(INTS, DWordAcc, NoLock, Preserve) {
> +          STDS, 8
> +        }
> +
> +        OperationRegion(INTC, SystemMemory, 0x1000027B0040, 4)
> +        Field(INTC, DWordAcc, NoLock, Preserve) {
> +          SINT, 8
> +        }
> +
> +        OperationRegion(INTM, SystemMemory, 0x1000027B0044, 4)
> +        Field(INTM, DWordAcc, NoLock, Preserve) {
> +          MASK, 8
> +        }
> +
> +        Method(_INI, 0, NotSerialized) {
> +          // Set level type, low active (shutdown)
> +          Store (0x00, TYPE)
> +          Store (0x00, POLA)
> +          // Set Input type (shutdown)
> +          Store (0x00, STDI)
> +          // Enable interrupt (shutdown)
> +          Store (0x80, STDE)
> +          // Unmask the interrupt.
> +          Store (0x00, MASK)
> +        }
> +        Method(_EVT, 1, Serialized) {
> +          Switch (ToInteger(Arg0)) {
> +            Case (327) {
> +              if (And (STDS, 0x80)) {
> +                //Clear the interrupt.
> +                Store (0x80, SINT)
> +                // Notify OSPM the power button is pressed
> +                Notify (\_SB.PWRB, 0x80)
> +              }
> +            }
> +          }
> +        }
> +    }
> +
> +    // Power button device description
> +    Device(PWRB) {
> +        Name(_HID, EISAID("PNP0C0C"))
> +        Name(_ADR, 0)
> +        Name(_UID, 0)
> +        Name(_CCA, ONE)
> +        Method(_STA, 0, Notserialized) {
> +            Return (0x0b)
> +        }
> +    }
> +
> +    //
> +    // UART0 PL011
> +    Device(URT0) {
> +      Name(_HID, "ARMH0011")
> +      Name(_UID, 0)
> +      Name(_CCA, ONE)
> +      Method(_STA, 0, NotSerialized) {
> +        return (0x0f)
> +      }
> +      Name(_CRS, ResourceTemplate() {
> +        QWordMemory (
> +          ResourceProducer,     // ResourceUsage
> +          PosDecode,            // Decode
> +          MinFixed,             // IsMinFixed
> +          MaxFixed,             // IsMaxFixed
> +          NonCacheable,         // Cacheable
> +          ReadWrite,            // ReadAndWrite
> +          0x0000000000000000,   // AddressGranularity - GRA
> +          0x0000100002600000,   // AddressMinimum - MIN
> +          0x0000100002600FFF,   // AddressMaximum - MAX
> +          0x0000000000000000,   // AddressTranslation - TRA
> +          0x0000000000001000    // RangeLength - LEN
> +        )
> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 98 }
> +      })
> +    } // UART0
> +
> +    //
> +    // UART2 PL011
> +    Device(URT2) {
> +      Name(_HID, "ARMH0011")
> +      Name(_UID, 1)
> +      Name(_CCA, ONE)
> +      Method(_STA, 0, NotSerialized) {
> +        return (0x0f)
> +      }
> +      Name(_CRS, ResourceTemplate() {
> +        QWordMemory (
> +          ResourceProducer,     // ResourceUsage
> +          PosDecode,            // Decode
> +          MinFixed,             // IsMinFixed
> +          MaxFixed,             // IsMaxFixed
> +          NonCacheable,         // Cacheable
> +          ReadWrite,            // ReadAndWrite
> +          0x0000000000000000,   // AddressGranularity - GRA
> +          0x0000100002620000,   // AddressMinimum - MIN
> +          0x0000100002620FFF,   // AddressMaximum - MAX
> +          0x0000000000000000,   // AddressTranslation - TRA
> +          0x0000000000001000    // RangeLength - LEN
> +        )
> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 100 }
> +      })
> +    } // UART1
> +
> +    Device(HED0)
> +    {
> +        Name(_HID, EISAID("PNP0C33"))
> +        Name(_UID, Zero)
> +    }
> +
> +    Device(NVDR) {
> +      Name(_HID, "ACPI0012")
> +      Method(_STA, 0, NotSerialized) {
> +        return (0xf)
> +      }
> +      Method (_DSM, 0x4, Serialized) {
> +        // Not support any functions for now
> +        Return (Buffer() {0})
> +      }
> +      Device (NVD1) {
> +        Name(_ADR, 0x0330)
> +        Name(SMRT, Buffer(13) {0})
> +        CreateDWordField(SMRT, 0, BSTA)
> +        CreateWordField(SMRT, 4, BHTH)
> +        CreateWordField(SMRT, 6, BTMP)
> +        CreateByteField(SMRT, 8, BETH)
> +        CreateByteField(SMRT, 9, BWTH)
> +        CreateByteField(SMRT, 10, BNLF)
> +        OperationRegion(BUF1, SystemMemory, 0x88980000, 16)
> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
> +          STAT, 32, //Status
> +          HLTH, 16, //Module Health
> +          CTMP, 16, //Module Current Status
> +          ETHS, 8, //Error Threshold Status
> +          WTHS, 8, //Warning Threshold Status
> +          NVLF, 8, //NVM Lifetime
> +          ,     40 //Reserve
> +        }
> +        Method (_DSM, 0x4, Serialized) {
> +          //Accept only MSF Family type NVDIMM DSM functions
> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
> +            //Handle Func 0 query implemented commands
> +            If(LEqual(Arg2, 0)) {
> +              //Check revision and returned proper implemented commands
> +              //Support only health check for now
> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
> +            }
> +            //Handle MSF DSM Func 11 Get Smart and Health Info
> +            If(LEqual(Arg2, 11)) {
> +              Store(\_SB.NVDR.NVD1.STAT, BSTA)
> +              Store(\_SB.NVDR.NVD1.HLTH, BHTH)
> +              Store(\_SB.NVDR.NVD1.CTMP, BTMP)
> +              Store(\_SB.NVDR.NVD1.ETHS, BETH)
> +              Store(\_SB.NVDR.NVD1.WTHS, BWTH)
> +              Store(\_SB.NVDR.NVD1.NVLF, BNLF)
> +              Return (SMRT)
> +            }
> +          }
> +          Return (Buffer() {0})
> +        }
> +        Method(_STA, 0, NotSerialized) {
> +          return (0xf)
> +        }
> +      }
> +      Device (NVD2) {
> +        Name(_ADR, 0x0770)
> +        Name(SMRT, Buffer(13) {0})
> +        CreateDWordField(SMRT, 0, BSTA)
> +        CreateWordField(SMRT, 4, BHTH)
> +        CreateWordField(SMRT, 6, BTMP)
> +        CreateByteField(SMRT, 8, BETH)
> +        CreateByteField(SMRT, 9, BWTH)
> +        CreateByteField(SMRT, 10, BNLF)
> +        OperationRegion(BUF1, SystemMemory, 0x88988000, 16)
> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
> +          STAT, 32, //Status
> +          HLTH, 16, //Module Health
> +          CTMP, 16, //Module Current Status
> +          ETHS, 8, //Error Threshold Status
> +          WTHS, 8, //Warning Threshold Status
> +          NVLF, 8, //NVM Lifetime
> +          ,     40 //Reserve
> +        }
> +        Method (_DSM, 0x4, Serialized) {
> +          //Accept only MSF Family type NVDIMM DSM functions
> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
> +            //Handle Func 0 query implemented commands
> +            If(LEqual(Arg2, 0)) {
> +              //Check revision and returned proper implemented commands
> +              //Support only health check for now
> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
> +            }
> +            //Handle MSF DSM Func 11 Get Smart and Health Info
> +            If(LEqual(Arg2, 11)) {
> +              Store(\_SB.NVDR.NVD2.STAT, BSTA)
> +              Store(\_SB.NVDR.NVD2.HLTH, BHTH)
> +              Store(\_SB.NVDR.NVD2.CTMP, BTMP)
> +              Store(\_SB.NVDR.NVD2.ETHS, BETH)
> +              Store(\_SB.NVDR.NVD2.WTHS, BWTH)
> +              Store(\_SB.NVDR.NVD2.NVLF, BNLF)
> +              Return (SMRT)
> +            }
> +          }
> +          Return (Buffer() {0})
> +        }
> +        Method(_STA, 0, NotSerialized) {
> +          return (0xf)
> +        }
> +      }
> +      Device (NVD3) {
> +        Name(_ADR, 0x1330)
> +        Name(SMRT, Buffer(13) {0})
> +        CreateDWordField(SMRT, 0, BSTA)
> +        CreateWordField(SMRT, 4, BHTH)
> +        CreateWordField(SMRT, 6, BTMP)
> +        CreateByteField(SMRT, 8, BETH)
> +        CreateByteField(SMRT, 9, BWTH)
> +        CreateByteField(SMRT, 10, BNLF)
> +        OperationRegion(BUF1, SystemMemory, 0xC0080000, 16)
> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
> +          STAT, 32, //Status
> +          HLTH, 16, //Module Health
> +          CTMP, 16, //Module Current Status
> +          ETHS, 8, //Error Threshold Status
> +          WTHS, 8, //Warning Threshold Status
> +          NVLF, 8, //NVM Lifetime
> +          ,     40 //Reserve
> +        }
> +        Method (_DSM, 0x4, Serialized) {
> +          //Accept only MSF Family type NVDIMM DSM functions
> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
> +            //Handle Func 0 query implemented commands
> +            If(LEqual(Arg2, 0)) {
> +              //Check revision and returned proper implemented commands
> +              //Support only health check for now
> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
> +            }
> +            //Handle MSF DSM Func 11 Get Smart and Health Info
> +            If(LEqual(Arg2, 11)) {
> +              Store(\_SB.NVDR.NVD3.STAT, BSTA)
> +              Store(\_SB.NVDR.NVD3.HLTH, BHTH)
> +              Store(\_SB.NVDR.NVD3.CTMP, BTMP)
> +              Store(\_SB.NVDR.NVD3.ETHS, BETH)
> +              Store(\_SB.NVDR.NVD3.WTHS, BWTH)
> +              Store(\_SB.NVDR.NVD3.NVLF, BNLF)
> +              Return (SMRT)
> +            }
> +          }
> +          Return (Buffer() {0})
> +        }
> +        Method(_STA, 0, NotSerialized) {
> +          return (0xf)
> +        }
> +      }
> +      Device (NVD4) {
> +        Name(_ADR, 0x1770)
> +        Name(SMRT, Buffer(13) {0})
> +        CreateDWordField(SMRT, 0, BSTA)
> +        CreateWordField(SMRT, 4, BHTH)
> +        CreateWordField(SMRT, 6, BTMP)
> +        CreateByteField(SMRT, 8, BETH)
> +        CreateByteField(SMRT, 9, BWTH)
> +        CreateByteField(SMRT, 10, BNLF)
> +        OperationRegion(BUF1, SystemMemory, 0xC0088000, 16)
> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
> +          STAT, 32, //Status
> +          HLTH, 16, //Module Health
> +          CTMP, 16, //Module Current Status
> +          ETHS, 8, //Error Threshold Status
> +          WTHS, 8, //Warning Threshold Status
> +          NVLF, 8, //NVM Lifetime
> +          ,     40 //Reserve
> +        }
> +        Method (_DSM, 0x4, Serialized) {
> +          //Accept only MSF Family type NVDIMM DSM functions
> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
> +            //Handle Func 0 query implemented commands
> +            If(LEqual(Arg2, 0)) {
> +              //Check revision and returned proper implemented commands
> +              //Support only health check for now
> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
> +            }
> +            //Handle MSF DSM Func 11 Get Smart and Health Info
> +            If(LEqual(Arg2, 11)) {
> +              Store(\_SB.NVDR.NVD4.STAT, BSTA)
> +              Store(\_SB.NVDR.NVD4.HLTH, BHTH)
> +              Store(\_SB.NVDR.NVD4.CTMP, BTMP)
> +              Store(\_SB.NVDR.NVD4.ETHS, BETH)
> +              Store(\_SB.NVDR.NVD4.WTHS, BWTH)
> +              Store(\_SB.NVDR.NVD4.NVLF, BNLF)
> +              Return (SMRT)
> +            }
> +          }
> +          Return (Buffer() {0})
> +        }
> +        Method(_STA, 0, NotSerialized) {
> +          return (0xf)
> +        }
> +      }
> +    }
> +
> +    Device (TPM0) {
> +      //
> +      // TPM 2.0
> +      //
> +
> +      //
> +      // TAG for patching TPM2.0 _HID
> +      //
> +      Name (_HID, "NNNN0000")
> +      Name (_CID, "MSFT0101")
> +      Name (_UID, 0)
> +
> +      Name (CRBB, 0x10000000)
> +      Name (CRBL, 0x10000000)
> +
> +      Name (RBUF, ResourceTemplate () {
> +        Memory32Fixed (ReadWrite, 0x88500000, 0x1000, PCRE)
> +      })
> +
> +      Method (_CRS, 0x0, Serialized) {
> +        // Declare fields in PCRE
> +        CreateDWordField(RBUF, ^PCRE._BAS, BASE)
> +        CreateDWordField(RBUF, ^PCRE._LEN, LENG)
> +
> +        // Store updatable values into them
> +        Store(CRBB, BASE)
> +        Store(CRBL, LENG)
> +
> +        Return (RBUF)
> +      }
> +
> +      Method (_STR,0) {
> +        Return (Unicode ("TPM 2.0 Device"))
> +      }
> +
> +      Method (_STA, 0) {
> +        if (TPMF) {
> +          Return (0x0f)  //Enable resources
> +        }
> +        Return (0x0)
> +      }
> +    }
> +
> +    Include ("PCI-S0.Rca01.asi")
> +    Include ("PCI-S0.asi")
> +    Include ("PCI-S1.asi")
> +    Include ("PCI-PDRC.asi")
> +  }
> +} // DSDT
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
> new file mode 100644
> index 000000000000..16c00c35e3fe
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
> @@ -0,0 +1,217 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +  // Motherboard resource consumption for PCIE resource reservation
> +  // as upstream discussion "ACPI namespace details for ARM64"
> +  Device (PDRC) {
> +    Name (_HID, EISAID("PNP0C02"))
> +    Name (_UID, 1)
> +    // S0 Start here
> +    Name (PDRS, ResourceTemplate() {
> +      QWordMemory (              // PCIE0 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00003BFFF0000000,   // AddressMinimum - MIN
> +        0x00003BFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE1 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00003FFFF0000000,   // AddressMinimum - MIN
> +        0x00003FFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE2 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000023FFF0000000,   // AddressMinimum - MIN
> +        0x000023FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE3 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000027FFF0000000,   // AddressMinimum - MIN
> +        0x000027FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE4 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00002BFFF0000000,   // AddressMinimum - MIN
> +        0x00002BFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE5 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00002FFFF0000000,   // AddressMinimum - MIN
> +        0x00002FFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      // S1 Start here
> +      QWordMemory (              // PCIE6 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00007BFFF0000000,   // AddressMinimum - MIN
> +        0x00007BFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE7 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00007FFFF0000000,   // AddressMinimum - MIN
> +        0x00007FFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE8 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000063FFF0000000,   // AddressMinimum - MIN
> +        0x000063FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIE9 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000067FFF0000000,   // AddressMinimum - MIN
> +        0x000067FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +      QWordMemory (              // PCIEA 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00006BFFF0000000,   // AddressMinimum - MIN
> +        0x00006BFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIEB 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00006FFFF0000000,   // AddressMinimum - MIN
> +        0x00006FFFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIEC 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000033FFF0000000,   // AddressMinimum - MIN
> +        0x000033FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (              // PCIED 256M CFG region for ECAM
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x000037FFF0000000,   // AddressMinimum - MIN
> +        0x000037FFFFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    // Current Resource Settings
> +    Method (_CRS, 0, Serialized) {
> +      Return (PDRS)
> +    }
> +  }
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
> new file mode 100755
> index 000000000000..67e1518ebf88
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
> @@ -0,0 +1,681 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +  // PCI0 RCA0
> +  Device (PCI0) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 12)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI0")
> +    Name (_STR, Unicode("PCIe 0 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 128/129/130/131 respectively. PCI0 RCA0
> +      //
> +      Package() {0x0001FFFF, 0, 0, 128},
> +      Package() {0x0001FFFF, 1, 0, 129},
> +      Package() {0x0001FFFF, 2, 0, 130},
> +      Package() {0x0001FFFF, 3, 0, 131},
> +      Package() {0x0002FFFF, 0, 0, 128},
> +      Package() {0x0002FFFF, 1, 0, 129},
> +      Package() {0x0002FFFF, 2, 0, 130},
> +      Package() {0x0002FFFF, 3, 0, 131},
> +      Package() {0x0003FFFF, 0, 0, 128},
> +      Package() {0x0003FFFF, 1, 0, 129},
> +      Package() {0x0003FFFF, 2, 0, 130},
> +      Package() {0x0003FFFF, 3, 0, 131},
> +      Package() {0x0004FFFF, 0, 0, 128},
> +      Package() {0x0004FFFF, 1, 0, 129},
> +      Package() {0x0004FFFF, 2, 0, 130},
> +      Package() {0x0004FFFF, 3, 0, 131},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x33FFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000040000000,   // AddressMinimum - MIN
> +        0x000000004FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000300000000000,   // AddressMinimum - MIN
> +        0x000033FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI0 RCA0
> +
> +  // PCI1 RCA1
> +  Device (PCI1) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 13)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI1")
> +    Name (_STR, Unicode("PCIe 1 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 132/133/134/135 respectively. PCI1 RCA1
> +      //
> +      Package() {0x0001FFFF, 0, 0, 132},
> +      Package() {0x0001FFFF, 1, 0, 133},
> +      Package() {0x0001FFFF, 2, 0, 134},
> +      Package() {0x0001FFFF, 3, 0, 135},
> +      Package() {0x0002FFFF, 0, 0, 132},
> +      Package() {0x0002FFFF, 1, 0, 133},
> +      Package() {0x0002FFFF, 2, 0, 134},
> +      Package() {0x0002FFFF, 3, 0, 135},
> +      Package() {0x0003FFFF, 0, 0, 132},
> +      Package() {0x0003FFFF, 1, 0, 133},
> +      Package() {0x0003FFFF, 2, 0, 134},
> +      Package() {0x0003FFFF, 3, 0, 135},
> +      Package() {0x0004FFFF, 0, 0, 132},
> +      Package() {0x0004FFFF, 1, 0, 133},
> +      Package() {0x0004FFFF, 2, 0, 134},
> +      Package() {0x0004FFFF, 3, 0, 135},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x37FFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000050000000,   // AddressMinimum - MIN
> +        0x000000005FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000010000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        Cacheable,            // Cacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000340000000000,   // AddressMinimum - MIN
> +        0x000037FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI1 RCA1
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
> new file mode 100755
> index 000000000000..7c05c6768a0e
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
> @@ -0,0 +1,2078 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +  // PCI2 RCA2
> +  Device (PCI2) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 1)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI2")
> +    Name (_STR, Unicode("PCIe 2 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 136/137/138/139 respectively. PCI2 RCA2
> +      //
> +      Package() {0x0001FFFF, 0, 0, 136},
> +      Package() {0x0001FFFF, 1, 0, 137},
> +      Package() {0x0001FFFF, 2, 0, 138},
> +      Package() {0x0001FFFF, 3, 0, 139},
> +      Package() {0x0002FFFF, 0, 0, 136},
> +      Package() {0x0002FFFF, 1, 0, 137},
> +      Package() {0x0002FFFF, 2, 0, 138},
> +      Package() {0x0002FFFF, 3, 0, 139},
> +      Package() {0x0003FFFF, 0, 0, 136},
> +      Package() {0x0003FFFF, 1, 0, 137},
> +      Package() {0x0003FFFF, 2, 0, 138},
> +      Package() {0x0003FFFF, 3, 0, 139},
> +      Package() {0x0004FFFF, 0, 0, 136},
> +      Package() {0x0004FFFF, 1, 0, 137},
> +      Package() {0x0004FFFF, 2, 0, 138},
> +      Package() {0x0004FFFF, 3, 0, 139},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x3BFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE80000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000030000000,   // AddressMinimum - MIN
> +        0x0000000037FFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000380000000000,   // AddressMinimum - MIN
> +        0x00003BFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP, 0) // PCI _OSC Support Field value
> +    Name (CTRL, 0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3,0,CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI2 RCA2
> +
> +  // PCI3 RCA3
> +  Device (PCI3) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 0)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI3")
> +    Name (_STR, Unicode("PCIe 3 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 140/141/142/143 respectively. PCI3 RCA3
> +      //
> +      Package() {0x0001FFFF, 0, 0, 140},
> +      Package() {0x0001FFFF, 1, 0, 141},
> +      Package() {0x0001FFFF, 2, 0, 142},
> +      Package() {0x0001FFFF, 3, 0, 143},
> +      Package() {0x0002FFFF, 0, 0, 140},
> +      Package() {0x0002FFFF, 1, 0, 141},
> +      Package() {0x0002FFFF, 2, 0, 142},
> +      Package() {0x0002FFFF, 3, 0, 143},
> +      Package() {0x0003FFFF, 0, 0, 140},
> +      Package() {0x0003FFFF, 1, 0, 141},
> +      Package() {0x0003FFFF, 2, 0, 142},
> +      Package() {0x0003FFFF, 3, 0, 143},
> +      Package() {0x0004FFFF, 0, 0, 140},
> +      Package() {0x0004FFFF, 1, 0, 141},
> +      Package() {0x0004FFFF, 2, 0, 142},
> +      Package() {0x0004FFFF, 3, 0, 143},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x3FFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to Return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE00000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000038000000,   // AddressMinimum - MIN
> +        0x000000003FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00003C0000000000,   // AddressMinimum - MIN
> +        0x00003FFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP, 0) // PCI _OSC Support Field value
> +    Name (CTRL, 0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI3 RCA3
> +
> +  // PCI4 RCB0
> +  Device (PCI4) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 2)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI4")
> +    Name (_STR, Unicode("PCIe 4 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 144/145/146/147 respectively. PCI4 RCB0
> +      //
> +      Package() {0x0001FFFF, 0, 0, 144},
> +      Package() {0x0001FFFF, 1, 0, 145},
> +      Package() {0x0001FFFF, 2, 0, 146},
> +      Package() {0x0001FFFF, 3, 0, 147},
> +      Package() {0x0002FFFF, 0, 0, 144},
> +      Package() {0x0002FFFF, 1, 0, 145},
> +      Package() {0x0002FFFF, 2, 0, 146},
> +      Package() {0x0002FFFF, 3, 0, 147},
> +      Package() {0x0003FFFF, 0, 0, 144},
> +      Package() {0x0003FFFF, 1, 0, 145},
> +      Package() {0x0003FFFF, 2, 0, 146},
> +      Package() {0x0003FFFF, 3, 0, 147},
> +      Package() {0x0004FFFF, 0, 0, 144},
> +      Package() {0x0004FFFF, 1, 0, 145},
> +      Package() {0x0004FFFF, 2, 0, 146},
> +      Package() {0x0004FFFF, 3, 0, 147},
> +      Package() {0x0005FFFF, 0, 0, 144},
> +      Package() {0x0005FFFF, 1, 0, 145},
> +      Package() {0x0005FFFF, 2, 0, 146},
> +      Package() {0x0005FFFF, 3, 0, 147},
> +      Package() {0x0006FFFF, 0, 0, 144},
> +      Package() {0x0006FFFF, 1, 0, 145},
> +      Package() {0x0006FFFF, 2, 0, 146},
> +      Package() {0x0006FFFF, 3, 0, 147},
> +      Package() {0x0007FFFF, 0, 0, 144},
> +      Package() {0x0007FFFF, 1, 0, 145},
> +      Package() {0x0007FFFF, 2, 0, 146},
> +      Package() {0x0007FFFF, 3, 0, 147},
> +      Package() {0x0008FFFF, 0, 0, 144},
> +      Package() {0x0008FFFF, 1, 0, 145},
> +      Package() {0x0008FFFF, 2, 0, 146},
> +      Package() {0x0008FFFF, 3, 0, 147},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x23FFF0000000)
> +    }
> +
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FEC0000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000001000000,   // AddressMinimum - MIN
> +        0x0000000007FFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000007000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000200000000000,   // AddressMinimum - MIN
> +        0x000023FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2))
> +        {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI4 RCB0
> +
> +  // PCI5 RCB1
> +  Device (PCI5) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID,"PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 3)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI5")
> +    Name (_STR, Unicode("PCIe 5 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 148/149/150/151 respectively. PCI5 RCB1
> +      //
> +      Package() {0x0001FFFF, 0, 0, 148},
> +      Package() {0x0001FFFF, 1, 0, 149},
> +      Package() {0x0001FFFF, 2, 0, 150},
> +      Package() {0x0001FFFF, 3, 0, 151},
> +      Package() {0x0002FFFF, 0, 0, 148},
> +      Package() {0x0002FFFF, 1, 0, 149},
> +      Package() {0x0002FFFF, 2, 0, 150},
> +      Package() {0x0002FFFF, 3, 0, 151},
> +      Package() {0x0003FFFF, 0, 0, 148},
> +      Package() {0x0003FFFF, 1, 0, 149},
> +      Package() {0x0003FFFF, 2, 0, 150},
> +      Package() {0x0003FFFF, 3, 0, 151},
> +      Package() {0x0004FFFF, 0, 0, 148},
> +      Package() {0x0004FFFF, 1, 0, 149},
> +      Package() {0x0004FFFF, 2, 0, 150},
> +      Package() {0x0004FFFF, 3, 0, 151},
> +      Package() {0x0005FFFF, 0, 0, 148},
> +      Package() {0x0005FFFF, 1, 0, 149},
> +      Package() {0x0005FFFF, 2, 0, 150},
> +      Package() {0x0005FFFF, 3, 0, 151},
> +      Package() {0x0006FFFF, 0, 0, 148},
> +      Package() {0x0006FFFF, 1, 0, 149},
> +      Package() {0x0006FFFF, 2, 0, 150},
> +      Package() {0x0006FFFF, 3, 0, 151},
> +      Package() {0x0007FFFF, 0, 0, 148},
> +      Package() {0x0007FFFF, 1, 0, 149},
> +      Package() {0x0007FFFF, 2, 0, 150},
> +      Package() {0x0007FFFF, 3, 0, 151},
> +      Package() {0x0008FFFF, 0, 0, 148},
> +      Package() {0x0008FFFF, 1, 0, 149},
> +      Package() {0x0008FFFF, 2, 0, 150},
> +      Package() {0x0008FFFF, 3, 0, 151},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x27FFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FF00000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000008000000,   // AddressMinimum - MIN
> +        0x000000000FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000240000000000,   // AddressMinimum - MIN
> +        0x000027FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP, 0) // PCI _OSC Support Field value
> +    Name (CTRL, 0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +            Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +            Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2))
> +        {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI5 RCB1
> +
> +
> +  // PCI6 RCB2
> +  Device (PCI6) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID,"PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID,"PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 4)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI6")
> +    Name (_STR, Unicode("PCIe 6 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 152/153/154/155 respectively. PCI6 RCB2
> +      //
> +      Package() {0x0001FFFF, 0, 0, 152},
> +      Package() {0x0001FFFF, 1, 0, 153},
> +      Package() {0x0001FFFF, 2, 0, 154},
> +      Package() {0x0001FFFF, 3, 0, 155},
> +      Package() {0x0002FFFF, 0, 0, 152},
> +      Package() {0x0002FFFF, 1, 0, 153},
> +      Package() {0x0002FFFF, 2, 0, 154},
> +      Package() {0x0002FFFF, 3, 0, 155},
> +      Package() {0x0003FFFF, 0, 0, 152},
> +      Package() {0x0003FFFF, 1, 0, 153},
> +      Package() {0x0003FFFF, 2, 0, 154},
> +      Package() {0x0003FFFF, 3, 0, 155},
> +      Package() {0x0004FFFF, 0, 0, 152},
> +      Package() {0x0004FFFF, 1, 0, 153},
> +      Package() {0x0004FFFF, 2, 0, 154},
> +      Package() {0x0004FFFF, 3, 0, 155},
> +      Package() {0x0005FFFF, 0, 0, 152},
> +      Package() {0x0005FFFF, 1, 0, 153},
> +      Package() {0x0005FFFF, 2, 0, 154},
> +      Package() {0x0005FFFF, 3, 0, 155},
> +      Package() {0x0006FFFF, 0, 0, 152},
> +      Package() {0x0006FFFF, 1, 0, 153},
> +      Package() {0x0006FFFF, 2, 0, 154},
> +      Package() {0x0006FFFF, 3, 0, 155},
> +      Package() {0x0007FFFF, 0, 0, 152},
> +      Package() {0x0007FFFF, 1, 0, 153},
> +      Package() {0x0007FFFF, 2, 0, 154},
> +      Package() {0x0007FFFF, 3, 0, 155},
> +      Package() {0x0008FFFF, 0, 0, 152},
> +      Package() {0x0008FFFF, 1, 0, 153},
> +      Package() {0x0008FFFF, 2, 0, 154},
> +      Package() {0x0008FFFF, 3, 0, 155},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x2BFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000010000000,   // AddressMinimum - MIN
> +        0x0000000017FFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000280000000000,   // AddressMinimum - MIN
> +        0x00002BFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3,0,CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3,4,CDW2)
> +        CreateDWordField (Arg3,8,CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2,SUPP)
> +        Store (CDW3,CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL,0x1E,CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1,One)) {
> +          Or (CDW1,0x08,CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3,CTRL)) {
> +          Or (CDW1,0x10,CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL,CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1,4,CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI6 RCB2
> +
> +  // PCI7 RCB3
> +  Device (PCI7) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID,"PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID,"PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 5)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCI7")
> +    Name (_STR, Unicode("PCIe 7 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 156/157/158/159 respectively. PCI7 RCB3
> +      //
> +      Package() {0x0001FFFF, 0, 0, 156},
> +      Package() {0x0001FFFF, 1, 0, 157},
> +      Package() {0x0001FFFF, 2, 0, 158},
> +      Package() {0x0001FFFF, 3, 0, 159},
> +      Package() {0x0002FFFF, 0, 0, 156},
> +      Package() {0x0002FFFF, 1, 0, 157},
> +      Package() {0x0002FFFF, 2, 0, 158},
> +      Package() {0x0002FFFF, 3, 0, 159},
> +      Package() {0x0003FFFF, 0, 0, 156},
> +      Package() {0x0003FFFF, 1, 0, 157},
> +      Package() {0x0003FFFF, 2, 0, 158},
> +      Package() {0x0003FFFF, 3, 0, 159},
> +      Package() {0x0004FFFF, 0, 0, 156},
> +      Package() {0x0004FFFF, 1, 0, 157},
> +      Package() {0x0004FFFF, 2, 0, 158},
> +      Package() {0x0004FFFF, 3, 0, 159},
> +      Package() {0x0005FFFF, 0, 0, 156},
> +      Package() {0x0005FFFF, 1, 0, 157},
> +      Package() {0x0005FFFF, 2, 0, 158},
> +      Package() {0x0005FFFF, 3, 0, 159},
> +      Package() {0x0006FFFF, 0, 0, 156},
> +      Package() {0x0006FFFF, 1, 0, 157},
> +      Package() {0x0006FFFF, 2, 0, 158},
> +      Package() {0x0006FFFF, 3, 0, 159},
> +      Package() {0x0007FFFF, 0, 0, 156},
> +      Package() {0x0007FFFF, 1, 0, 157},
> +      Package() {0x0007FFFF, 2, 0, 158},
> +      Package() {0x0007FFFF, 3, 0, 159},
> +      Package() {0x0008FFFF, 0, 0, 156},
> +      Package() {0x0008FFFF, 1, 0, 157},
> +      Package() {0x0008FFFF, 2, 0, 158},
> +      Package() {0x0008FFFF, 3, 0, 159},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x2FFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000018000000,   // AddressMinimum - MIN
> +        0x000000001FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00002C0000000000,   // AddressMinimum - MIN
> +        0x00002FFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3,0,CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3,4,CDW2)
> +        CreateDWordField (Arg3,8,CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2,SUPP)
> +        Store (CDW3,CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL,0x1E,CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1,One)) {
> +          Or (CDW1,0x08,CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3,CTRL)) {
> +          Or (CDW1,0x10,CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL,CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1,4,CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCI7 RCB3
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
> new file mode 100755
> index 000000000000..2757f3124b83
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
> @@ -0,0 +1,2087 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +  //
> +  // S1 Start here
> +  //
> +
> +  // PCIE6 S1 RCA2
> +  Device (PCIA) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID,"PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID,"PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 6)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCIA")
> +    Name (_STR, Unicode("PCIe 10 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 136/137/138/139 + 320 respectively. PCIA RCA2
> +      //
> +      Package() {0x0001FFFF, 0, 0, 456},
> +      Package() {0x0001FFFF, 1, 0, 457},
> +      Package() {0x0001FFFF, 2, 0, 458},
> +      Package() {0x0001FFFF, 3, 0, 459},
> +      Package() {0x0002FFFF, 0, 0, 456},
> +      Package() {0x0002FFFF, 1, 0, 457},
> +      Package() {0x0002FFFF, 2, 0, 458},
> +      Package() {0x0002FFFF, 3, 0, 459},
> +      Package() {0x0003FFFF, 0, 0, 456},
> +      Package() {0x0003FFFF, 1, 0, 457},
> +      Package() {0x0003FFFF, 2, 0, 458},
> +      Package() {0x0003FFFF, 3, 0, 459},
> +      Package() {0x0004FFFF, 0, 0, 456},
> +      Package() {0x0004FFFF, 1, 0, 457},
> +      Package() {0x0004FFFF, 2, 0, 458},
> +      Package() {0x0004FFFF, 3, 0, 459},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x7BFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FF80000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000070000000,   // AddressMinimum - MIN
> +        0x0000000077FFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000780000000000,   // AddressMinimum - MIN
> +        0x00007BFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3,0,CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3,4,CDW2)
> +        CreateDWordField (Arg3,8,CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2,SUPP)
> +        Store (CDW3,CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL,0x1E,CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1,One)) {
> +          Or (CDW1,0x08,CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3,CTRL)) {
> +          Or (CDW1,0x10,CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL,CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1,4,CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCIA RCA2
> +
> +  // PCIEB RCA3
> +  Device (PCIB) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID,"PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID,"PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 7)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCIB")
> +    Name (_STR, Unicode("PCIe 11 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 140/141/142/143 + 320 respectively. PCIB RCA3
> +      //
> +      Package() {0x0001FFFF, 0, 0, 460},
> +      Package() {0x0001FFFF, 1, 0, 461},
> +      Package() {0x0001FFFF, 2, 0, 462},
> +      Package() {0x0001FFFF, 3, 0, 463},
> +      Package() {0x0002FFFF, 0, 0, 460},
> +      Package() {0x0002FFFF, 1, 0, 461},
> +      Package() {0x0002FFFF, 2, 0, 462},
> +      Package() {0x0002FFFF, 3, 0, 463},
> +      Package() {0x0003FFFF, 0, 0, 460},
> +      Package() {0x0003FFFF, 1, 0, 461},
> +      Package() {0x0003FFFF, 2, 0, 462},
> +      Package() {0x0003FFFF, 3, 0, 463},
> +      Package() {0x0004FFFF, 0, 0, 460},
> +      Package() {0x0004FFFF, 1, 0, 461},
> +      Package() {0x0004FFFF, 2, 0, 462},
> +      Package() {0x0004FFFF, 3, 0, 463},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x7FFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FFC0000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000078000000,   // AddressMinimum - MIN
> +        0x000000007FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00007C0000000000,   // AddressMinimum - MIN
> +        0x00007FFFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3,0,CDW1)
> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3,4,CDW2)
> +        CreateDWordField (Arg3,8,CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2,SUPP)
> +        Store (CDW3,CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL,0x1E,CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1,One)) {
> +            Or (CDW1,0x08,CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3,CTRL)) {
> +            Or (CDW1,0x10,CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL,CDW3)
> +        Return (Arg3)
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1,4,CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCIB RCA3
> +
> +  // PCIC RCB0
> +  Device (PCIC) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 8)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCIC")
> +    Name (_STR, Unicode("PCIe 12 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 144/145/146/147 + 320 respectively. PCIC RCB0
> +      //
> +      Package() {0x0001FFFF, 0, 0, 464},
> +      Package() {0x0001FFFF, 1, 0, 465},
> +      Package() {0x0001FFFF, 2, 0, 466},
> +      Package() {0x0001FFFF, 3, 0, 467},
> +      Package() {0x0002FFFF, 0, 0, 464},
> +      Package() {0x0002FFFF, 1, 0, 465},
> +      Package() {0x0002FFFF, 2, 0, 466},
> +      Package() {0x0002FFFF, 3, 0, 467},
> +      Package() {0x0003FFFF, 0, 0, 464},
> +      Package() {0x0003FFFF, 1, 0, 465},
> +      Package() {0x0003FFFF, 2, 0, 466},
> +      Package() {0x0003FFFF, 3, 0, 467},
> +      Package() {0x0004FFFF, 0, 0, 464},
> +      Package() {0x0004FFFF, 1, 0, 465},
> +      Package() {0x0004FFFF, 2, 0, 466},
> +      Package() {0x0004FFFF, 3, 0, 467},
> +      Package() {0x0005FFFF, 0, 0, 464},
> +      Package() {0x0005FFFF, 1, 0, 465},
> +      Package() {0x0005FFFF, 2, 0, 466},
> +      Package() {0x0005FFFF, 3, 0, 467},
> +      Package() {0x0006FFFF, 0, 0, 464},
> +      Package() {0x0006FFFF, 1, 0, 465},
> +      Package() {0x0006FFFF, 2, 0, 466},
> +      Package() {0x0006FFFF, 3, 0, 467},
> +      Package() {0x0007FFFF, 0, 0, 464},
> +      Package() {0x0007FFFF, 1, 0, 465},
> +      Package() {0x0007FFFF, 2, 0, 466},
> +      Package() {0x0007FFFF, 3, 0, 467},
> +      Package() {0x0008FFFF, 0, 0, 464},
> +      Package() {0x0008FFFF, 1, 0, 465},
> +      Package() {0x0008FFFF, 2, 0, 466},
> +      Package() {0x0008FFFF, 3, 0, 467},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x63FFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000040000000,   // AddressMinimum - MIN
> +        0x0000000047FFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000600000000000,   // AddressMinimum - MIN
> +        0x000063FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCIC RCB0
> +
> +  // PCID RCB1
> +  Device (PCID) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 9)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCID")
> +    Name (_STR, Unicode("PCIe 13 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 148/149/150/151 + 320 respectively. PCID RCB1
> +      //
> +      Package() {0x0001FFFF, 0, 0, 468},
> +      Package() {0x0001FFFF, 1, 0, 469},
> +      Package() {0x0001FFFF, 2, 0, 470},
> +      Package() {0x0001FFFF, 3, 0, 471},
> +      Package() {0x0002FFFF, 0, 0, 468},
> +      Package() {0x0002FFFF, 1, 0, 469},
> +      Package() {0x0002FFFF, 2, 0, 470},
> +      Package() {0x0002FFFF, 3, 0, 471},
> +      Package() {0x0003FFFF, 0, 0, 468},
> +      Package() {0x0003FFFF, 1, 0, 469},
> +      Package() {0x0003FFFF, 2, 0, 470},
> +      Package() {0x0003FFFF, 3, 0, 471},
> +      Package() {0x0004FFFF, 0, 0, 468},
> +      Package() {0x0004FFFF, 1, 0, 469},
> +      Package() {0x0004FFFF, 2, 0, 470},
> +      Package() {0x0004FFFF, 3, 0, 471},
> +      Package() {0x0005FFFF, 0, 0, 468},
> +      Package() {0x0005FFFF, 1, 0, 469},
> +      Package() {0x0005FFFF, 2, 0, 470},
> +      Package() {0x0005FFFF, 3, 0, 471},
> +      Package() {0x0006FFFF, 0, 0, 468},
> +      Package() {0x0006FFFF, 1, 0, 469},
> +      Package() {0x0006FFFF, 2, 0, 470},
> +      Package() {0x0006FFFF, 3, 0, 471},
> +      Package() {0x0007FFFF, 0, 0, 468},
> +      Package() {0x0007FFFF, 1, 0, 469},
> +      Package() {0x0007FFFF, 2, 0, 470},
> +      Package() {0x0007FFFF, 3, 0, 471},
> +      Package() {0x0008FFFF, 0, 0, 468},
> +      Package() {0x0008FFFF, 1, 0, 469},
> +      Package() {0x0008FFFF, 2, 0, 470},
> +      Package() {0x0008FFFF, 3, 0, 471},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x67FFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000048000000,   // AddressMinimum - MIN
> +        0x000000004FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000640000000000,   // AddressMinimum - MIN
> +        0x000067FFDFFFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCID RCB1
> +
> +  // PCIE RCB2
> +  Device (PCIE) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 10)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCIE")
> +    Name (_STR, Unicode("PCIe 14 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 152/153/154/155 + 320 respectively. PCIE RCB2
> +      //
> +      Package() {0x0001FFFF, 0, 0, 472},
> +      Package() {0x0001FFFF, 1, 0, 473},
> +      Package() {0x0001FFFF, 2, 0, 474},
> +      Package() {0x0001FFFF, 3, 0, 475},
> +      Package() {0x0002FFFF, 0, 0, 472},
> +      Package() {0x0002FFFF, 1, 0, 473},
> +      Package() {0x0002FFFF, 2, 0, 474},
> +      Package() {0x0002FFFF, 3, 0, 475},
> +      Package() {0x0003FFFF, 0, 0, 472},
> +      Package() {0x0003FFFF, 1, 0, 473},
> +      Package() {0x0003FFFF, 2, 0, 474},
> +      Package() {0x0003FFFF, 3, 0, 475},
> +      Package() {0x0004FFFF, 0, 0, 472},
> +      Package() {0x0004FFFF, 1, 0, 473},
> +      Package() {0x0004FFFF, 2, 0, 474},
> +      Package() {0x0004FFFF, 3, 0, 475},
> +      Package() {0x0005FFFF, 0, 0, 472},
> +      Package() {0x0005FFFF, 1, 0, 473},
> +      Package() {0x0005FFFF, 2, 0, 474},
> +      Package() {0x0005FFFF, 3, 0, 475},
> +      Package() {0x0006FFFF, 0, 0, 472},
> +      Package() {0x0006FFFF, 1, 0, 473},
> +      Package() {0x0006FFFF, 2, 0, 474},
> +      Package() {0x0006FFFF, 3, 0, 475},
> +      Package() {0x0007FFFF, 0, 0, 472},
> +      Package() {0x0007FFFF, 1, 0, 473},
> +      Package() {0x0007FFFF, 2, 0, 474},
> +      Package() {0x0007FFFF, 3, 0, 475},
> +      Package() {0x0008FFFF, 0, 0, 472},
> +      Package() {0x0008FFFF, 1, 0, 473},
> +      Package() {0x0008FFFF, 2, 0, 474},
> +      Package() {0x0008FFFF, 3, 0, 475},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x6BFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000050000000,   // AddressMinimum - MIN
> +        0x0000000057FFFFFF,   // AddressMaximum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000680000000000,   // AddressMinimum - MIN
> +        0x00006BFFDFFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCIE RCB2
> +
> +  // PCIF RCB3
> +  Device (PCIF) {
> +    //
> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
> +    // Section 6.1.5
> +    //
> +
> +    Name (_HID, "PNP0A08")
> +    Name (_CCA, ONE)
> +
> +    Method (_STA, 0, NotSerialized) {
> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
> +                                        // run-time patching as the representation of 0 is special
> +                                        // encoding and cannot be patched to expand with extra bytes
> +                                        // easily. As such, we default to 0xF and patch this based
> +                                        // on whether the port was enabled or not by the BIOS.
> +    }
> +
> +    //
> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
> +    // root complex for use with pre-PCIe operating systems.
> +    // Section 6.1.2
> +    //
> +
> +    Name (_CID, "PNP0A03")
> +
> +    //
> +    // Declare the segment number of this root complex. Most systems only
> +    // have one segment, which is numbered 0.
> +    // Section 6.5.6
> +    //
> +
> +    Name (_SEG, 11)
> +
> +    //
> +    // Declare the base bus number, which is the bus number of the root
> +    // bus in this root complex. This is usually 0, but need not be.
> +    // For root complexes supporting multiple root busses, this should
> +    // be the lowest numbered root bus.
> +    // Section 6.5.5
> +    //
> +
> +    Name (_BBN, 0)
> +
> +    //
> +    // The _UID value provides a way of uniquely identifying a device
> +    // in the case where more than one instance of a specific device
> +    // is implemented with the same _HID/_CID. For systems with a
> +    // single root complex, this is usually just 0. For systems with
> +    // multiple root complexes, this should be different for each
> +    // root complex.
> +    // Section 6.1.12
> +    //
> +
> +    Name (_UID, "PCIF")
> +    Name (_STR, Unicode("PCIe 15 Device"))
> +
> +    //
> +    // Declare the PCI Routing Table.
> +    // This defines SPI mappings of the four line-based interrupts
> +    // associated with the root complex and hierarchy below it.
> +    // Section 6.2.12
> +    //
> +
> +    Name (_PRT, Package() {
> +
> +      //
> +      // Routing for device 0, all functions.
> +      // Note: ARM doesn't support LNK nodes, so the third param
> +      // is 0 and the fourth param is the SPI number of the interrupt
> +      // line. In this example, the A/B/C/D interrupts are wired to
> +      // SPI lines 156/157/158/159 + 320 respectively. PCIF RCB3
> +      //
> +      Package() {0x0001FFFF, 0, 0, 476},
> +      Package() {0x0001FFFF, 1, 0, 477},
> +      Package() {0x0001FFFF, 2, 0, 478},
> +      Package() {0x0001FFFF, 3, 0, 479},
> +      Package() {0x0002FFFF, 0, 0, 476},
> +      Package() {0x0002FFFF, 1, 0, 477},
> +      Package() {0x0002FFFF, 2, 0, 478},
> +      Package() {0x0002FFFF, 3, 0, 479},
> +      Package() {0x0003FFFF, 0, 0, 476},
> +      Package() {0x0003FFFF, 1, 0, 477},
> +      Package() {0x0003FFFF, 2, 0, 478},
> +      Package() {0x0003FFFF, 3, 0, 479},
> +      Package() {0x0004FFFF, 0, 0, 476},
> +      Package() {0x0004FFFF, 1, 0, 477},
> +      Package() {0x0004FFFF, 2, 0, 478},
> +      Package() {0x0004FFFF, 3, 0, 479},
> +      Package() {0x0005FFFF, 0, 0, 476},
> +      Package() {0x0005FFFF, 1, 0, 477},
> +      Package() {0x0005FFFF, 2, 0, 478},
> +      Package() {0x0005FFFF, 3, 0, 479},
> +      Package() {0x0006FFFF, 0, 0, 476},
> +      Package() {0x0006FFFF, 1, 0, 477},
> +      Package() {0x0006FFFF, 2, 0, 478},
> +      Package() {0x0006FFFF, 3, 0, 479},
> +      Package() {0x0007FFFF, 0, 0, 476},
> +      Package() {0x0007FFFF, 1, 0, 477},
> +      Package() {0x0007FFFF, 2, 0, 478},
> +      Package() {0x0007FFFF, 3, 0, 479},
> +      Package() {0x0008FFFF, 0, 0, 476},
> +      Package() {0x0008FFFF, 1, 0, 477},
> +      Package() {0x0008FFFF, 2, 0, 478},
> +      Package() {0x0008FFFF, 3, 0, 479},
> +    })
> +
> +    //
> +    // Declare the resources assigned to this root complex.
> +    // Section 6.2.2
> +    //
> +    Method (_CBA, 0, Serialized) {
> +      Return (0x6FFFF0000000)
> +    }
> +
> +    //
> +    // Declare a ResourceTemplate buffer to return the resource
> +    // requirements from _CRS.
> +    // Section 19.5.109
> +    //
> +
> +    Name (RBUF, ResourceTemplate () {
> +
> +      //
> +      // Declare the range of bus numbers assigned to this root
> +      // complex. In this example, the minimum bus number will be
> +      // 0, the maximum bus number will be 0xFF, supporting
> +      // 256 busses total.
> +      // Section 19.5.141
> +      //
> +
> +      WordBusNumber (
> +        ResourceProducer,
> +        MinFixed,   // IsMinFixed
> +        MaxFixed,   // IsMaxFixed
> +        PosDecode,  // Decode
> +        0,          // AddressGranularity
> +        0,          // AddressMinimum - Minimum Bus Number
> +        255,        // AddressMaximum - Maximum Bus Number
> +        0,          // AddressTranslation - Set to 0
> +        256)        // RangeLength - Number of Busses
> +
> +      //
> +      // Declare the memory range to be used for BAR memory
> +      // windows. This declares a 4GB region starting at
> +      // 0x4000000000.
> +      // Section 19.5.80
> +      //
> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x0000000058000000,   // AddressMinimum - MIN
> +        0x000000005FFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x0000000008000000    // RangeLength - LEN
> +      )
> +
> +      QWordMemory (
> +        ResourceProducer,     // ResourceUsage
> +        PosDecode,            // Decode
> +        MinFixed,             // IsMinFixed
> +        MaxFixed,             // IsMaxFixed
> +        NonCacheable,         // NonCacheable
> +        ReadWrite,            // ReadAndWrite
> +        0x0000000000000000,   // AddressGranularity - GRA
> +        0x00006C0000000000,   // AddressMinimum - MIN
> +        0x00006FFFDFFFFFFF,   // AddressMinimum - MAX
> +        0x0000000000000000,   // AddressTranslation - TRA
> +        0x000003FFE0000000    // RangeLength - LEN
> +      )
> +    })
> +
> +    Method (_CRS, 0, Serialized) {
> +      Return (RBUF)
> +    }
> +
> +    //
> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
> +    //
> +    // Argments:
> +    //   Arg0  A Buffer containing a UUID
> +    //   Arg1  An Integer containing a Revision ID of the buffer format
> +    //   Arg2  An Integer containing a count of entries in Arg3
> +    //   Arg3  A Buffer containing a list of DWORD capabilities
> +    // Return Value:
> +    //   A Buffer containing a list of capabilities
> +    // See the APCI spec, Section 6.2.10,
> +    // and the PCI FW spec, Section 4.5.
> +    //
> +    // The following is an example, and may need modification for
> +    // specific implementations.
> +    //
> +
> +    Name (SUPP,0) // PCI _OSC Support Field value
> +    Name (CTRL,0) // PCI _OSC Control Field value
> +
> +    Method (_OSC, 4) {
> +
> +      //
> +      // Look for the PCI Host Bridge Interface UUID.
> +      // Section 6.2.10.3
> +      //
> +
> +      //
> +      // Create DWord-adressable fields from the Capabilities Buffer
> +      // Create CDW1 outside the test as it's used in the else clause.
> +      //
> +
> +      CreateDWordField (Arg3, 0, CDW1)
> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
> +
> +        CreateDWordField (Arg3, 4, CDW2)
> +        CreateDWordField (Arg3, 8, CDW3)
> +
> +        //
> +        // Save Capabilities DWord 2 & 3
> +        //
> +
> +        Store (CDW2, SUPP)
> +        Store (CDW3, CTRL)
> +
> +        //
> +        // Only allow native hot plug control if OS supports:
> +        //  ASPM
> +        //  Clock PM
> +        //  MSI/MSI-X
> +        //
> +
> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
> +
> +          //
> +          // Mask bit 0 (and undefined bits)
> +          //
> +
> +          And (CTRL, 0x1E, CTRL)
> +        }
> +
> +        //
> +        // Never allow native Hot plug, PME.
> +        // Never allow SHPC (no SHPC controller in this system).
> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
> +        // Allows PCI Express Capability Structure control
> +        //
> +
> +        If (AERF) {
> +          And (CTRL, 0x10, CTRL)
> +        } Else {
> +          And (CTRL, 0x18, CTRL)
> +        }
> +
> +        //
> +        // Check for unknown revision.
> +        //
> +
> +        If (LNotEqual (Arg1, One)) {
> +          Or (CDW1, 0x08, CDW1)
> +        }
> +
> +        //
> +        // Check if capabilities bits were masked.
> +        //
> +
> +        If (LNotEqual (CDW3, CTRL)) {
> +          Or (CDW1, 0x10, CDW1)
> +        }
> +
> +        //
> +        // Update DWORD3 in the buffer.
> +        //
> +
> +        Store (CTRL, CDW3)
> +        Return (Arg3)
> +
> +      } Else {
> +
> +        //
> +        // Unrecognized UUID
> +        //
> +
> +        Or (CDW1, 4, CDW1)
> +        Return (Arg3)
> +      }
> +    } // End _OSC
> +
> +    //
> +    // Declare a _DSM method for various functions called by the OS.
> +    // See the APCI spec, Section 9.14.1,
> +    // and the PCI FW spec, Section 4.6.
> +    // See also:
> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
> +    //
> +
> +    Method (_DSM, 0x4, Serialized) {
> +
> +      //
> +      // Match against the _DSM PCI GUID.
> +      //
> +
> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
> +
> +        Switch (ToInteger(Arg2)) {
> +          //
> +          // Function 0: Return supported functions as a bitfield
> +          // with one bit for each supported function.
> +          // Bit 0 must always be set, as that represents
> +          // function 0 (which is what is being called here).
> +          // Support for different functions may depend on
> +          // the revision ID of the interface, passed as Arg1.
> +          //
> +
> +          Case (0) {
> +
> +              //
> +              // Functions 0-7 are supported.
> +              //
> +
> +              Return (Buffer() {0x01})
> +          }
> +        }
> +      }
> +
> +      //
> +      // If not one of the function identifiers we recognize, then return a buffer
> +      // with bit 0 set to 0 indicating no functions supported.
> +      //
> +
> +      Return (Buffer() {0})
> +    }
> +
> +    //
> +    // Root Port 0 Device within the Root Complex.
> +    //
> +    Device (RP0) {
> +      //
> +      // Device 0, Function 0.
> +      //
> +
> +      Name (_ADR, 0x00000000)
> +    }
> +
> +    Method (_PXM, 0, NotSerialized) {
> +      // Patch by code
> +      Return(0xFF)
> +    }
> +  } // PCIF RCB3
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
> new file mode 100755
> index 000000000000..0e9db557d925
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
> @@ -0,0 +1,1303 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Device(CMN0) {
> +  Name(_HID, "ARMHC600") // Device Identification Objects
> +  Name(_CID, "ARMHC600")
> +  Name(_UID, 0)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("CMN0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +  QWordMemory (
> +    ResourceConsumer,     // ResourceUsage
> +    PosDecode,            // Decode
> +    MinFixed,             // IsMinFixed
> +    MaxFixed,             // IsMaxFixed
> +    NonCacheable,         // Cacheable
> +    ReadWrite,            // ReadAndWrite
> +    0x0000000000000000,   // AddressGranularity - GRA
> +    0x0000100010000000,   // AddressMinimum - MIN
> +    0x000010001fffffff,   // AddressMaximum - MAX
> +    0x0000000000000000,   // AddressTranslation - TRA
> +    0x0000000010000000    // RangeLength - LEN
> +  )
> +  QWordMemory (
> +    ResourceConsumer,     // ResourceUsage
> +    PosDecode,            // Decode
> +    MinFixed,             // IsMinFixed
> +    MaxFixed,             // IsMaxFixed
> +    NonCacheable,         // Cacheable
> +    ReadWrite,            // ReadAndWrite
> +    0x0000000000000000,   // AddressGranularity - GRA
> +    0x0000100012500000,   // AddressMinimum - MIN
> +    0x00001000164fffff,   // AddressMaximum - MAX
> +    0x0000000000000000,   // AddressTranslation - TRA
> +    0x0000000004000000    // RangeLength - LEN
> +  )
> +  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 314 }
> +  })
> +}
> +
> +Device(MC00) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008C000A00,   // AddressMinimum - MIN
> +      0x000010008C000BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC01) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 1)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008C400A00,   // AddressMinimum - MIN
> +      0x000010008C400BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC02) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 2)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU2"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008C800A00,   // AddressMinimum - MIN
> +      0x000010008C800BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC03) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 3)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU3"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008CC00A00,   // AddressMinimum - MIN
> +      0x000010008CC00BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC04) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 4)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU4"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008D000A00,   // AddressMinimum - MIN
> +      0x000010008D000BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC05) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 5)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU5"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008D400A00,   // AddressMinimum - MIN
> +      0x000010008D400BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC06) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 6)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU6"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008D800A00,   // AddressMinimum - MIN
> +      0x000010008D800BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(MC07) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 7)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 0: MCU7"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000010008DC00A00,   // AddressMinimum - MIN
> +      0x000010008DC00BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
> +  })
> +}
> +
> +Device(DU00) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 64 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x000000,
> +          0x000100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU01) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 65 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x010000,
> +          0x010100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU02) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x2)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x2 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 66 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x020000,
> +          0x020100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU03) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x3)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x3 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 67 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x030000,
> +          0x030100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU04) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 68 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x040000,
> +          0x040100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU05) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 69 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x050000,
> +          0x050100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU06) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x6)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x6 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 71 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x060000,
> +          0x060100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU07) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x7)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x7 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 80 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x070000,
> +          0x070100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU08) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x8)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x8 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 81 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x080000,
> +          0x080100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU09) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x9)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x9 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 82 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x090000,
> +          0x090100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0A) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xA)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xA Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 83 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0A0000,
> +          0x0A0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0B) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xB)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xB Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 115 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0B0000,
> +          0x0B0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0C) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xC)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xC Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 116 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0C0000,
> +          0x0C0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0D) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xD)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xD Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 221 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0D0000,
> +          0x0D0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0E) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xE)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xE Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 222 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0E0000,
> +          0x0E0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU0F) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0xF)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0xF Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 223 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x0F0000,
> +          0x0F0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU10) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x10)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x10 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 248 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100000,
> +          0x100100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU11) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x11)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x11 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 249 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x110000,
> +          0x110100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU12) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x12)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x12 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 250 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x120000,
> +          0x120100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU13) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x13)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x13 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 251 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x130000,
> +          0x130100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU14) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x14)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x14 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 252 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x140000,
> +          0x140100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU15) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x15)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x15 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 253 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x150000,
> +          0x150100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU16) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x16)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x16 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 254 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x160000,
> +          0x160100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU17) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x17)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x17 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 255 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x170000,
> +          0x170100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU18) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x18)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x18 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 297 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x180000,
> +          0x180100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU19) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x19)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x19 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 298 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x190000,
> +          0x190100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1A) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1A)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1A Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 299 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1A0000,
> +          0x1A0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1B) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1B)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1B Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 300 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1B0000,
> +          0x1B0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1C) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1C)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1C Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 301 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1C0000,
> +          0x1C0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1D) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1D)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1D Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 313 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1D0000,
> +          0x1D0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1E) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1E)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1E Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 316 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1E0000,
> +          0x1E0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU1F) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x1F)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x1F Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 317 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1F0000,
> +          0x1F0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU20) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x20)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x20 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 318 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x200000,
> +          0x200100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU21) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x21)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x21 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 319 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x210000,
> +          0x210100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU22) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x22)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x22 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 344 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x220000,
> +          0x220100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU23) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x23)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x23 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 345 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x230000,
> +          0x230100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU24) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x24)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x24 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 346 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x240000,
> +          0x240100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU25) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x25)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x25 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 347 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x250000,
> +          0x250100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU26) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x26)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x26 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 348 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x260000,
> +          0x260100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU27) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x27)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x27 Socket 0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 349 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x270000,
> +          0x270100
> +        }
> +      }
> +    }
> +  })
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
> new file mode 100755
> index 000000000000..1ae1bac8098b
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
> @@ -0,0 +1,1303 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Device(CMN1) {
> +  Name(_HID, "ARMHC600") // Device Identification Objects
> +  Name(_CID, "ARMHC600")
> +  Name(_UID, 1)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("CMN1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +  QWordMemory (
> +    ResourceConsumer,     // ResourceUsage
> +    PosDecode,            // Decode
> +    MinFixed,             // IsMinFixed
> +    MaxFixed,             // IsMaxFixed
> +    NonCacheable,         // Cacheable
> +    ReadWrite,            // ReadAndWrite
> +    0x0000000000000000,   // AddressGranularity - GRA
> +    0x0000500010000000,   // AddressMinimum - MIN
> +    0x000050001fffffff,   // AddressMaximum - MAX
> +    0x0000000000000000,   // AddressTranslation - TRA
> +    0x0000000010000000    // RangeLength - LEN
> +  )
> +  QWordMemory (
> +    ResourceConsumer,     // ResourceUsage
> +    PosDecode,            // Decode
> +    MinFixed,             // IsMinFixed
> +    MaxFixed,             // IsMaxFixed
> +    NonCacheable,         // Cacheable
> +    ReadWrite,            // ReadAndWrite
> +    0x0000000000000000,   // AddressGranularity - GRA
> +    0x0000500012500000,   // AddressMinimum - MIN
> +    0x00005000164fffff,   // AddressMaximum - MAX
> +    0x0000000000000000,   // AddressTranslation - TRA
> +    0x0000000004000000    // RangeLength - LEN
> +  )
> +  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 634 }
> +  })
> +}
> +
> +Device(MC10) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 8)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU0"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008C000A00,   // AddressMinimum - MIN
> +      0x000050008C000BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC11) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 9)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008C400A00,   // AddressMinimum - MIN
> +      0x000050008C400BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC12) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xa)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU2"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008C800A00,   // AddressMinimum - MIN
> +      0x000050008C800BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC13) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xb)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU3"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008CC00A00,   // AddressMinimum - MIN
> +      0x000050008CC00BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC14) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xc)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU4"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008D000A00,   // AddressMinimum - MIN
> +      0x000050008D000BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC15) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xd)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU5"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008D400A00,   // AddressMinimum - MIN
> +      0x000050008D400BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC16) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xe)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU6"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008D800A00,   // AddressMinimum - MIN
> +      0x000050008D800BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(MC17) {
> +  Name(_HID, "ARMHD620")
> +  Name(_CID, "ARMHD620")
> +  Name(_UID, 0xf)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("Socket 1: MCU7"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    QWordMemory (
> +      ResourceProducer,     // ResourceUsage
> +      PosDecode,            // Decode
> +      MinFixed,             // IsMinFixed
> +      MaxFixed,             // IsMaxFixed
> +      NonCacheable,         // Cacheable
> +      ReadWrite,            // ReadAndWrite
> +      0x0000000000000000,   // AddressGranularity - GRA
> +      0x000050008DC00A00,   // AddressMinimum - MIN
> +      0x000050008DC00BFF,   // AddressMaximum - MAX
> +      0x0000000000000000,   // AddressTranslation - TRA
> +      0x0000000000000200    // RangeLength - LEN
> +    )
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
> +  })
> +}
> +
> +Device(DU40) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x40)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x40 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 384 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100000000,
> +          0x100000100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU41) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x41)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x41 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 385 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100010000,
> +          0x100010100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU42) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x42)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x42 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 386 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100020000,
> +          0x100020100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU43) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x43)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x43 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 387 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100030000,
> +          0x100030100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU44) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x44)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x44 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 388 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100040000,
> +          0x100040100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU45) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x45)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x45 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 389 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100050000,
> +          0x100050100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU46) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x46)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x46 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 391 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100060000,
> +          0x100060100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU47) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x47)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x47 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 400 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100070000,
> +          0x100070100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU48) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x48)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x48 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 401 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100080000,
> +          0x100080100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU49) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x49)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x49 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 402 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100090000,
> +          0x100090100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4A) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4A)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4A Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 403 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000A0000,
> +          0x1000A0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4B) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4B)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4B Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 435 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000B0000,
> +          0x1000B0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4C) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4C)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4C Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 436 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000C0000,
> +          0x1000C0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4D) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4D)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4D Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 541 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000D0000,
> +          0x1000D0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4E) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4E)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4E Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 542 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000E0000,
> +          0x1000E0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU4F) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x4F)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x4F Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 543 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1000F0000,
> +          0x1000F0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU50) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x50)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x50 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 568 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100100000,
> +          0x100100100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU51) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x51)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x51 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 569 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100110000,
> +          0x100110100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU52) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x52)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x52 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 570 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100120000,
> +          0x100120100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU53) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x53)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x53 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 571 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100130000,
> +          0x100130100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU54) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x54)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x54 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 572 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100140000,
> +          0x100140100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU55) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x55)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x55 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 573 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100150000,
> +          0x100150100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU56) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x56)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x56 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 574 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100160000,
> +          0x100160100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU57) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x57)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x57 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 575 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100170000,
> +          0x100170100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU58) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x58)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x58 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 617 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100180000,
> +          0x100180100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU59) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x59)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x59 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 618 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100190000,
> +          0x100190100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5A) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5A)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5A Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 619 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001A0000,
> +          0x1001A0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5B) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5B)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5B Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 620 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001B0000,
> +          0x1001B0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5C) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5C)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5C Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 621 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001C0000,
> +          0x1001C0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5D) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5D)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5D Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 633 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001D0000,
> +          0x1001D0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5E) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5E)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5E Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 636 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001E0000,
> +          0x1001E0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU5F) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x5F)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x5F Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 637 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x1001F0000,
> +          0x1001F0100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU60) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x60)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x60 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 638 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100200000,
> +          0x100200100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU61) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x61)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x61 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 639 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100210000,
> +          0x100210100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU62) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x62)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x62 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 664 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100220000,
> +          0x100220100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU63) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x63)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x63 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 665 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100230000,
> +          0x100230100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU64) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x64)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x64 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 666 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100240000,
> +          0x100240100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU65) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x65)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x65 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 667 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100250000,
> +          0x100250100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU66) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x66)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x66 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 668 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100260000,
> +          0x100260100
> +        }
> +      }
> +    }
> +  })
> +}
> +
> +Device(DU67) {
> +  Name(_HID, "ARMHD500")
> +  Name(_CID, "ARMHD500")
> +  Name(_UID, 0x67)
> +  Name(_CCA, ONE)
> +  Name(_STR, Unicode("DSU CPM 0x67 Socket 1"))
> +  Method(_STA, 0, NotSerialized) {
> +    Return (0x0f)
> +  }
> +  Name(_CRS, ResourceTemplate() {
> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 669 }
> +  })
> +  Name (_DSD, Package () {
> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
> +    Package () {
> +      Package (2) {
> +        "cpus",
> +        Package (2) {
> +          0x100270000,
> +          0x100270100
> +        }
> +      }
> +    }
> +  })
> +}
> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
> new file mode 100644
> index 000000000000..0d177de8696d
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
> @@ -0,0 +1,10 @@
> +/** @file
> +
> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +Include ("PMU-S0.asi")
> +Include ("PMU-S1.asi")
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
> new file mode 100644
> index 000000000000..a80f1e81b24f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
> @@ -0,0 +1,33 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <AcpiHeader.h>
> +
> +#define BOOT_ERROR_REGION_LENGTH  0x50000
> +#define BOOT_ERROR_REGION_BASE    0x0000000088230000
> +
> +#pragma pack(1)
> +
> +EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER Bert = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE,
> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER,
> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_REVISION
> +  ),
> +  BOOT_ERROR_REGION_LENGTH,
> +  BOOT_ERROR_REGION_BASE
> +};
> +
> +#pragma pack()
> +
> +//
> +// Reference the table being generated to prevent the optimizer from removing
> +// the data structure from the executable
> +//
> +VOID* CONST ReferenceAcpiTable = &Bert;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
> new file mode 100644
> index 000000000000..bc2bbded11fd
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
> @@ -0,0 +1,87 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/AcpiLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/PcdLib.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <IndustryStandard/DebugPort2Table.h>
> +#include <AcpiHeader.h>
> +
> +#pragma pack(1)
> +
> +#define DBG2_NUM_DEBUG_PORTS                       1
> +#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS   1
> +#define DBG2_NAMESPACESTRING_FIELD_SIZE            10
> +#define SERIAL_PORT_PL011_UART_ADDR_SIZE           0x8
> +
> +#define NAME_STR_UART2     {'\\', '_', 'S', 'B', '.', 'U', 'R', 'T', '2', '\0'}
> +
> +typedef struct {
> +  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
> +  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;
> +  UINT32                                        AddressSize;
> +  UINT8                                         NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];
> +} DBG2_DEBUG_DEVICE_INFORMATION;
> +
> +typedef struct {
> +  EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE       Description;
> +  DBG2_DEBUG_DEVICE_INFORMATION                 Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS];
> +} DBG2_TABLE;
> +
> +
> +#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) {                                    \
> +    {                                                                                                                 \
> +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,         /* UINT8     Revision */                        \
> +      sizeof (DBG2_DEBUG_DEVICE_INFORMATION),                         /* UINT16    Length */                          \
> +      NumReg,                                                         /* UINT8     NumberofGenericAddressRegisters */ \
> +      DBG2_NAMESPACESTRING_FIELD_SIZE,                                /* UINT16    NameSpaceStringLength */           \
> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString),     /* UINT16    NameSpaceStringOffset */           \
> +      0,                                                              /* UINT16    OemDataLength */                   \
> +      0,                                                              /* UINT16    OemDataOffset */                   \
> +      EFI_ACPI_DBG2_PORT_TYPE_SERIAL,                                 /* UINT16    Port Type */                       \
> +      SubType,                                                        /* UINT16    Port Subtype */                    \
> +      {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE},               /* UINT8     Reserved[2] */                     \
> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16    BaseAddressRegister Offset */      \
> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize)          /* UINT16    AddressSize Offset */              \
> +    },                                                                                                                \
> +    ARM_GAS32 (UartBase),                            /* EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
> +    UartAddrLen,                                     /* UINT32  AddressSize */                                        \
> +    UartNameStr                                      /* UINT8   NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE] */   \
> +  }
> +
> +
> +STATIC DBG2_TABLE Dbg2 = {
> +  {
> +    __ACPI_HEADER (
> +      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
> +      DBG2_TABLE,
> +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
> +    ),
> +    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
> +    DBG2_NUM_DEBUG_PORTS                                 /* UINT32  NumberDbgDeviceInfo */
> +  },
> +  {
> +    // Kernel Debug Port
> +    DBG2_DEBUG_PORT_DDI (
> +      DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,
> +      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART,
> +      FixedPcdGet64 (PcdSerialDbgRegisterBase),
> +      SERIAL_PORT_PL011_UART_ADDR_SIZE,
> +      NAME_STR_UART2
> +      ),
> +  }
> +};
> +
> +#pragma pack()
> +
> +//
> +// Reference the table being generated to prevent the optimizer from removing
> +// the data structure from the executable
> +//
> +VOID* CONST ReferenceAcpiTable = &Dbg2;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
> new file mode 100755
> index 000000000000..9607b2e403e0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
> @@ -0,0 +1,165 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +[0004]                          Signature : "EINJ"    [Error Injection table]
> +[0004]                       Table Length : 00000150
> +[0001]                           Revision : 01
> +[0001]                           Checksum : 09
> +[0006]                             Oem ID : "Ampere"
> +[0008]                       Oem Table ID : "Altra   "
> +[0004]                       Oem Revision : 00000001
> +[0004]                    Asl Compiler ID : "INTL"
> +[0004]              Asl Compiler Revision : 20100528
> +
> +[0004]            Injection Header Length : 00000030
> +[0001]                              Flags : 00
> +[0003]                           Reserved : 000000
> +[0004]              Injection Entry Count : 00000009
> +
> +[0001]                             Action : 00 [Begin Operation]
> +[0001]                        Instruction : 00 [Read Register]
> +[0001]              Flags (decoded below) : 00
> +                   Preserve Register Bits : 0
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088220000
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 01 [Get Trigger Table]
> +[0001]                        Instruction : 00 [Read Register]
> +[0001]              Flags (decoded below) : 00
> +                   Preserve Register Bits : 0
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088220040
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 08 [Set Error Type With Address]
> +[0001]                        Instruction : 02 [Write Register]
> +[0001]              Flags (decoded below) : 01
> +                   Preserve Register Bits : 1
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 20
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 03 [DWord Access:32]
> +[0008]                            Address : 0000000088221000
> +
> +[0008]                              Value : 00000000
> +[0008]                               Mask : FFFFFFFF
> +
> +[0001]                             Action : 02 [Set Error Type]
> +[0001]                        Instruction : 02 [Write Register]
> +[0001]              Flags (decoded below) : 01
> +                   Preserve Register Bits : 1
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 20
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [DWord Access:64]
> +[0008]                            Address : 0000000088220080
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 03 [Get Error Type]
> +[0001]                        Instruction : 00 [Read Register]
> +[0001]              Flags (decoded below) : 00
> +                   Preserve Register Bits : 0
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 00000000882200c0
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 04 [End Operation]
> +[0001]                        Instruction : 03 [Write Register Value]
> +[0001]              Flags (decoded below) : 01
> +                   Preserve Register Bits : 1
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088220100
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 05 [Execute Operation]
> +[0001]                        Instruction : 03 [Write Register Value]
> +[0001]              Flags (decoded below) : 01
> +                   Preserve Register Bits : 1
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 20
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 03 [DWord Access:32]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                              Value : B1A00000
> +[0008]                               Mask : FFFFFFFF
> +
> +[0001]                             Action : 06 [Check Busy Status]
> +[0001]                        Instruction : 01 [Read Register Value]
> +[0001]              Flags (decoded below) : 00
> +                   Preserve Register Bits : 0
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088220140
> +
> +[0008]                              Value : 0000000000000001
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> +
> +[0001]                             Action : 07 [Get Command Status]
> +[0001]                        Instruction : 00 [Read Register]
> +[0001]              Flags (decoded below) : 01
> +                   Preserve Register Bits : 1
> +[0001]                           Reserved : 00
> +
> +[0012]                    Register Region : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088220180
> +
> +[0008]                              Value : 0000000000000000
> +[0008]                               Mask : FFFFFFFFFFFFFFFF
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
> new file mode 100644
> index 000000000000..5be828f1cdf0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
> @@ -0,0 +1,87 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <AcpiHeader.h>
> +
> +//
> +// This macro defines the FADT flag options.
> +//
> +#define FADT_FLAGS  (EFI_ACPI_6_3_HW_REDUCED_ACPI | \
> +                     EFI_ACPI_6_3_PWR_BUTTON)
> +
> +
> +EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE,
> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
> +  ),
> +  0,                                                                        // UINT32     FirmwareCtrl
> +  0,                                                                        // UINT32     Dsdt
> +  EFI_ACPI_RESERVED_BYTE,                                                   // UINT8      Reserved0
> +  EFI_ACPI_6_3_PM_PROFILE_PERFORMANCE_SERVER,                               // UINT8      PreferredPmProfile
> +  0,                                                                        // UINT16     SciInt
> +  0,                                                                        // UINT32     SmiCmd
> +  0,                                                                        // UINT8      AcpiEnable
> +  0,                                                                        // UINT8      AcpiDisable
> +  0,                                                                        // UINT8      S4BiosReq
> +  0,                                                                        // UINT8      PstateCnt
> +  0,                                                                        // UINT32     Pm1aEvtBlk
> +  0,                                                                        // UINT32     Pm1bEvtBlk
> +  0,                                                                        // UINT32     Pm1aCntBlk
> +  0,                                                                        // UINT32     Pm1bCntBlk
> +  0,                                                                        // UINT32     Pm2CntBlk
> +  0,                                                                        // UINT32     PmTmrBlk
> +  0,                                                                        // UINT32     Gpe0Blk
> +  0,                                                                        // UINT32     Gpe1Blk
> +  0,                                                                        // UINT8      Pm1EvtLen
> +  0,                                                                        // UINT8      Pm1CntLen
> +  0,                                                                        // UINT8      Pm2CntLen
> +  0,                                                                        // UINT8      PmTmrLen
> +  0,                                                                        // UINT8      Gpe0BlkLen
> +  0,                                                                        // UINT8      Gpe1BlkLen
> +  0,                                                                        // UINT8      Gpe1Base
> +  0,                                                                        // UINT8      CstCnt
> +  0,                                                                        // UINT16     PLvl2Lat
> +  0,                                                                        // UINT16     PLvl3Lat
> +  0,                                                                        // UINT16     FlushSize
> +  0,                                                                        // UINT16     FlushStride
> +  0,                                                                        // UINT8      DutyOffset
> +  0,                                                                        // UINT8      DutyWidth
> +  0,                                                                        // UINT8      DayAlrm
> +  0,                                                                        // UINT8      MonAlrm
> +  0,                                                                        // UINT8      Century
> +  0,                                                                        // UINT16     IaPcBootArch
> +  0,                                                                        // UINT8      Reserved1
> +  FADT_FLAGS,                                                               // UINT32     Flags
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  ResetReg
> +  0,                                                                        // UINT8      ResetValue
> +  EFI_ACPI_6_3_ARM_PSCI_COMPLIANT,                                          // UINT16     ArmBootArchFlags
> +  EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,                 // UINT8      MinorRevision
> +  0,                                                                        // UINT64     XFirmwareCtrl
> +  0,                                                                        // UINT64     XDsdt
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk
> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk
> +  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepControlReg
> +  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg
> +  0                                                                         // UINT64 HypervisorVendorIdentity
> +};
> +
> +//
> +// Reference the table being generated to prevent the optimizer from removing the
> +// data structure from the executable
> +//
> +VOID* CONST ReferenceAcpiTable = &Fadt;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
> new file mode 100644
> index 000000000000..3824bd6bb956
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
> @@ -0,0 +1,180 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/PcdLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <AcpiHeader.h>
> +
> +#define SYSTEM_TIMER_BASE_ADDRESS       0xFFFFFFFFFFFFFFFF
> +#define CNT_READ_BASE_ADDRESS           0xFFFFFFFFFFFFFFFF
> +
> +#define SECURE_TIMER_EL1_GSIV           0x1D
> +#define NON_SECURE_TIMER_EL1_GSIV       0x1E
> +#define VIRTUAL_TIMER_GSIV              0x1B
> +#define NON_SECURE_EL2_GSIV             0x1A
> +
> +#define GTDT_TIMER_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
> +#define GTDT_TIMER_LEVEL_TRIGGERED  0
> +#define GTDT_TIMER_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
> +#define GTDT_TIMER_ACTIVE_HIGH      0
> +#define GTDT_TIMER_SAVE_CONTEXT     EFI_ACPI_6_3_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
> +#define GTDT_TIMER_LOSE_CONTEXT     0
> +
> +#define GTDT_GTIMER_FLAGS          (GTDT_TIMER_LOSE_CONTEXT | GTDT_TIMER_ACTIVE_HIGH | GTDT_TIMER_LEVEL_TRIGGERED)
> +
> +#define WATCHDOG_COUNT              FixedPcdGet32 (PcdWatchdogCount)
> +#define PLATFORM_TIMER_COUNT        (WATCHDOG_COUNT + 1)
> +#define TIMER_FRAMES_COUNT          3
> +
> +#define GT_BLOCK_CTL_BASE               0x0000100002700000
> +#define GT_BLOCK_FRAME0_CTL_BASE        0x0000100002710000
> +#define GT_BLOCK_FRAME0_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
> +#define GT_BLOCK_FRAME0_GSIV            0x58
> +
> +#define GT_BLOCK_FRAME1_CTL_BASE        0x0000100002720000
> +#define GT_BLOCK_FRAME1_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
> +#define GT_BLOCK_FRAME1_GSIV            0x59
> +
> +#define GT_BLOCK_FRAME2_CTL_BASE        0x0000100002730000
> +#define GT_BLOCK_FRAME2_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
> +#define GT_BLOCK_FRAME2_GSIV            0x5A
> +
> +#define GTX_TIMER_EDGE_TRIGGERED        EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE
> +#define GTX_TIMER_LEVEL_TRIGGERED       0
> +#define GTX_TIMER_ACTIVE_LOW            EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
> +#define GTX_TIMER_ACTIVE_HIGH           0
> +
> +#define GTX_TIMER_FLAGS                 (GTX_TIMER_ACTIVE_HIGH | GTX_TIMER_LEVEL_TRIGGERED)
> +
> +#define GTX_TIMER_SECURE                EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER
> +#define GTX_TIMER_NON_SECURE            0
> +#define GTX_TIMER_SAVE_CONTEXT          EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY
> +#define GTX_TIMER_LOSE_CONTEXT          0
> +
> +#define GTX_COMMON_FLAGS_S              (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_SECURE)
> +#define GTX_COMMON_FLAGS_NS             (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_NON_SECURE)
> +
> +#define SBSA_WATCHDOG_REFRESH_BASE     0x00001000027D0000
> +#define SBSA_WATCHDOG_CONTROL_BASE     0x00001000027C0000
> +#define SBSA_WATCHDOG_GSIV             0x5C
> +
> +#define SBSA_WATCHDOG_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
> +#define SBSA_WATCHDOG_LEVEL_TRIGGERED  0
> +#define SBSA_WATCHDOG_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
> +#define SBSA_WATCHDOG_ACTIVE_HIGH      0
> +#define SBSA_WATCHDOG_SECURE           EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER
> +#define SBSA_WATCHDOG_NON_SECURE       0
> +
> +#define SBSA_WATCHDOG_FLAGS            (SBSA_WATCHDOG_NON_SECURE | SBSA_WATCHDOG_ACTIVE_HIGH | SBSA_WATCHDOG_LEVEL_TRIGGERED)
> +
> +#pragma pack (1)
> +
> +typedef struct {
> +  EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE          Gtdt;
> +  EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE                  GtBlock;
> +  EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE            Frames[TIMER_FRAMES_COUNT];
> +#if (WATCHDOG_COUNT != 0)
> +  EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE     Watchdogs[WATCHDOG_COUNT];
> +#endif
> +} EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES;
> +
> +#pragma pack ()
> +
> +EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES Gtdt = {
> +  {
> +    __ACPI_HEADER (
> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES,
> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
> +    ),
> +    SYSTEM_TIMER_BASE_ADDRESS,                              // UINT64  CntControlBasePhysicalAddress
> +    EFI_ACPI_RESERVED_DWORD,                                // UINT32  Reserved
> +    SECURE_TIMER_EL1_GSIV,                                  // UINT32  SecurePL1TimerGSIV
> +    GTDT_GTIMER_FLAGS,                                      // UINT32  SecurePL1TimerFlags
> +    NON_SECURE_TIMER_EL1_GSIV,                              // UINT32  NonSecurePL1TimerGSIV
> +    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL1TimerFlags
> +    VIRTUAL_TIMER_GSIV,                                     // UINT32  VirtualTimerGSIV
> +    GTDT_GTIMER_FLAGS,                                      // UINT32  VirtualTimerFlags
> +    NON_SECURE_EL2_GSIV,                                    // UINT32  NonSecurePL2TimerGSIV
> +    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL2TimerFlags
> +    CNT_READ_BASE_ADDRESS,                                  // UINT64  CntReadBasePhysicalAddress
> +    PLATFORM_TIMER_COUNT,                                   // UINT32  PlatformTimerCount
> +    sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE),  // UINT32  PlatformTimerOffset
> +  },
> +  {
> +    EFI_ACPI_6_3_GTDT_GT_BLOCK,                           // UINT8 Type
> +    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT16 Length
> +      + sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE) *
> +        TIMER_FRAMES_COUNT,
> +    EFI_ACPI_RESERVED_BYTE,                               // UINT8 Reserved
> +    GT_BLOCK_CTL_BASE,                                    // UINT64 CntCtlBase
> +    TIMER_FRAMES_COUNT,                                   // UINT32 GTBlockTimerCount
> +    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT32 GTBlockTimerOffset
> +  },
> +  {
> +    {
> +      0,                                                    // UINT8 GTFrameNumber
> +      {EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
> +      GT_BLOCK_FRAME0_CTL_BASE,                             // UINT64 CntBaseX
> +      GT_BLOCK_FRAME0_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
> +      GT_BLOCK_FRAME0_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
> +      0,                                                    // UINT32 GTxVirtualTimerFlags
> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
> +    },
> +    {
> +      1,                                                    // UINT8 GTFrameNumber
> +      {EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
> +      GT_BLOCK_FRAME1_CTL_BASE,                             // UINT64 CntBaseX
> +      GT_BLOCK_FRAME1_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
> +      GT_BLOCK_FRAME1_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
> +      0,                                                    // UINT32 GTxVirtualTimerFlags
> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
> +    },
> +    {
> +      2,                                                    // UINT8 GTFrameNumber
> +      {EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE,
> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
> +      GT_BLOCK_FRAME2_CTL_BASE,                             // UINT64 CntBaseX
> +      GT_BLOCK_FRAME2_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
> +      GT_BLOCK_FRAME2_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
> +      0,                                                    // UINT32 GTxVirtualTimerFlags
> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
> +    },
> +  },
> +#if (WATCHDOG_COUNT != 0)
> +  {
> +    {
> +      EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG,                      // UINT8 Type
> +      sizeof(EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE),    // UINT16 Length
> +      EFI_ACPI_RESERVED_BYTE,                                       // UINT8 Reserved
> +      SBSA_WATCHDOG_REFRESH_BASE,                                   // UINT64 RefreshFramePhysicalAddress
> +      SBSA_WATCHDOG_CONTROL_BASE,                                   // UINT64 WatchdogControlFramePhysicalAddress
> +      SBSA_WATCHDOG_GSIV,                                           // UINT32 WatchdogTimerGSIV
> +      SBSA_WATCHDOG_FLAGS                                           // UINT32 WatchdogTimerFlags
> +    }
> +  }
> +#endif
> +};
> +
> +//
> +// Reference the table being generated to prevent the optimizer from removing the
> +// data structure from the executable
> +//
> +VOID* CONST ReferenceAcpiTable = &Gtdt;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
> new file mode 100644
> index 000000000000..4413428719b8
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
> @@ -0,0 +1,330 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +[0004]                          Signature : "HEST"    [Hardware Error Source Table]
> +[0004]                       Table Length : 00000308
> +[0001]                           Revision : 01
> +[0001]                           Checksum : 20
> +[0006]                             Oem ID : "Ampere"
> +[0008]                       Oem Table ID : "Altra   "
> +[0004]                       Oem Revision : 00000001
> +[0004]                    Asl Compiler ID : "INTL"
> +[0004]              Asl Compiler Revision : 20100528
> +
> +[0004]                 Error Source Count : 00000008
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0000
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200000
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1D00000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0001
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200008
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 00 [Polled]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1C00000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0002
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200010
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1F00000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0006
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200030
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1900000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0007
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200038
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000100000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1900001
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0003
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200018
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000500000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1D00000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0004
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200020
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 00 [Polled]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000500000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1C00000
> +
> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
> +[0002]                          Source Id : 0005
> +[0002]                  Related Source Id : FFFF
> +[0001]                           Reserved : 00
> +[0001]                            Enabled : 01
> +[0004]             Records To Preallocate : 00000001
> +[0004]            Max Sections Per Record : 00000001
> +[0004]                Max Raw Data Length : 00001000
> +
> +[0012]               Error Status Address : [Generic Address Structure]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000000088200028
> +
> +[0028]                             Notify : [Hardware Error Notification Structure]
> +[0001]                        Notify Type : 03 [SCI]
> +[0001]                      Notify Length : 1C
> +[0002]         Configuration Write Enable : 0000
> +[0004]                       PollInterval : 00000BB8
> +[0004]                             Vector : 00000000
> +[0004]            Polling Threshold Value : 00000000
> +[0004]           Polling Threshold Window : 00000000
> +[0004]              Error Threshold Value : 00000000
> +[0004]             Error Threshold Window : 00000000
> +
> +[0004]          Error Status Block Length : 00001000
> +
> +[0012]                  Read Ack Register : [Generic Address Structure v2]
> +[0001]                           Space ID : 00 [SystemMemory]
> +[0001]                          Bit Width : 40
> +[0001]                         Bit Offset : 00
> +[0001]               Encoded Access Width : 04 [QWord Access:64]
> +[0008]                            Address : 0000500000543010
> +
> +[0008]                  Read Ack Preserve : 00000000
> +[0008]                     Read Ack Write : B1F00000
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
> new file mode 100644
> index 000000000000..3c0a048552cf
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
> @@ -0,0 +1,17 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +[0004]                          Signature : "SDEI"
> +[0004]                       Table Length : 0000003E
> +[0001]                           Revision : 01
> +[0001]                           Checksum : 59
> +[0006]                             Oem ID : "Ampere"
> +[0008]                       Oem Table ID : "Altra "
> +[0004]                       Oem Revision : 00000001
> +[0004]                    Asl Compiler ID : "INTL"
> +[0004]              Asl Compiler Revision : 20160930
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
> new file mode 100644
> index 000000000000..42042f8a3474
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
> @@ -0,0 +1,81 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/PcdLib.h>
> +#include <Library/AcpiLib.h>
> +#include <IndustryStandard/Acpi63.h>
> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
> +#include <AcpiHeader.h>
> +
> +STATIC EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE Spcr = {
> +  __ACPI_HEADER (
> +    EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
> +    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE,
> +    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION
> +    ),
> +  // UINT8                                   InterfaceType;
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART,
> +  // UINT8                                   Reserved1[3];
> +  {
> +    EFI_ACPI_RESERVED_BYTE,
> +    EFI_ACPI_RESERVED_BYTE,
> +    EFI_ACPI_RESERVED_BYTE
> +  },
> +  // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  BaseAddress;
> +  ARM_GAS32 (FixedPcdGet64 (PcdSerialRegisterBase)),
> +  // UINT8                                   InterruptType;
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC,
> +  // UINT8                                   Irq;
> +  0,                                         // Not used on ARM
> +  // UINT32                                  GlobalSystemInterrupt;
> +  FixedPcdGet32 (PL011UartInterrupt),
> +  // UINT8                                   BaudRate;
> +#if (FixedPcdGet64 (PcdUartDefaultBaudRate) == 9600)
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600,
> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 19200)
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200,
> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 57600)
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600,
> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 115200)
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200,
> +#else
> +#error Unsupported SPCR Baud Rate
> +#endif
> +  // UINT8                                   Parity;
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY,
> +  // UINT8                                   StopBits;
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1,
> +  // UINT8                                   FlowControl;
> +  0,
> +  // UINT8                                   TerminalType;
> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8,
> +  // UINT8                                   Reserved2;
> +  EFI_ACPI_RESERVED_BYTE,
> +  // UINT16                                  PciDeviceId;
> +  0xFFFF,
> +  // UINT16                                  PciVendorId;
> +  0xFFFF,
> +  // UINT8                                   PciBusNumber;
> +  0x00,
> +  // UINT8                                   PciDeviceNumber;
> +  0x00,
> +  // UINT8                                   PciFunctionNumber;
> +  0x00,
> +  // UINT32                                  PciFlags;
> +  0x00000000,
> +  // UINT8                                   PciSegment;
> +  0x00,
> +  // UINT32                                  Reserved3;
> +  EFI_ACPI_RESERVED_DWORD
> +};
> +
> +//
> +// Reference the table being generated to prevent the optimizer from removing the
> +// data structure from the executable
> +//
> +VOID* CONST ReferenceAcpiTable = &Spcr;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
> new file mode 100755
> index 000000000000..cdb4bf5de9bf
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
> @@ -0,0 +1,15 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +DefinitionBlock("Ssdt.aml", "SSDT", 2, "Ampere", "Altra   ", 0x00000001)
> +{
> +    Method (MAIN, 0, NotSerialized)
> +    {
> +        Return (Zero)
> +    }
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
@ 2021-06-05  0:05   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-05  0:05 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:06 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Provides essential functions to initialize the PCIe Root Complex of
> Ampere Altra processor.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                   |    3 +
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc               |    1 +
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf  |   68 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h        |  164 +++
>  Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h                       |  203 ++++
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h       |  582 +++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h |   64 +
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h  |   30 +
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c       | 1266 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c    |  536 +++++++++
>  Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c  |  610 ++++++++++
>  11 files changed, 3527 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index d5b12a81e9bf..0d79673ce50a 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -37,6 +37,9 @@ [LibraryClasses]
>    ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>    MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>  
> +  ##  @libraryclass  Defines a set of methods to initialize Pcie
> +  PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h
> +
>    ##  @libraryclass  Defines a set of methods to access flash memory.
>    FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>  
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 11f50f2f09cd..fc8e0b40ee19 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -83,6 +83,7 @@ [LibraryClasses.common]
>    NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
>    MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
>    SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
> +  PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
>    AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>    TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
>    I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
> new file mode 100755
> index 000000000000..fe20d4675518
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
> @@ -0,0 +1,68 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PcieCoreLib
> +  FILE_GUID                      = 8ABFA0FC-313E-11E8-B467-0ED5F89F718B
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PcieCoreLib
> +
> +[Sources]
> +  PcieCore.c
> +  PcieCore.h
> +  PcieCoreCapCfg.h
> +  PcieCoreLib.c
> +  PciePatchAcpi.c
> +  PciePatchAcpi.h
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraBinPkg/AmpereAltraBinPkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[BuildOptions]
> +  *_*_*_CC_FLAGS = -Wno-error=switch -Wno-missing-braces

No. Actually add the braces.

> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  ArmLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  GpioLib
> +  IoLib
> +  MemoryAllocationLib
> +  PcdLib
> +  PcieBoardLib
> +  PciePhyLib
> +  SerialPortLib
> +  SystemFirmwareInterfaceLib
> +  TimerLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Pcd]
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
> +
> +[Protocols]
> +  gEfiAcpiTableProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> +  gEfiAcpiSdtProtocolGuid # PROTOCOL ALWAYS_CONSUMED
> +
> +[Guids]
> +  gPlatformHobGuid
> +
> +[Depex]
> +  gEfiAcpiTableProtocolGuid AND gEfiAcpiSdtProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
> new file mode 100644
> index 000000000000..99038454f534
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieCoreLib.h
> @@ -0,0 +1,164 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCI_CORE_LIB_H_
> +#define PCI_CORE_LIB_H_
> +
> +#include <Library/PciHostBridgeLib.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +
> +/**
> +  Get RootBridge disable status.
> +
> +  @param  HBIndex[In]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[In]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval BOOLEAN               Return RootBridge disable status.
> +**/
> +BOOLEAN
> +Ac01PcieCheckRootBridgeDisabled (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  );
> +
> +/**
> +  Prepare to start PCIE core BSP driver
> +
> +  @param ImageHandle[in]        Handle for the image.
> +  @param SystemTable[in]        Address of the system table.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieSetup (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  );
> +
> +/**
> +  Prepare to end PCIE core BSP driver.
> +**/
> +VOID
> +Ac01PcieEnd (
> +  VOID
> +  );
> +
> +/**
> +  Get Total HostBridge.
> +
> +  @retval UINTN                 Return Total HostBridge.
> +**/
> +UINT8
> +Ac01PcieGetTotalHBs (
> +  VOID
> +  );
> +
> +/**
> +  Get Total RootBridge per HostBridge.
> +
> +  @param  RCIndex[in]           Index to identify of Root Complex.
> +
> +  @retval UINTN                 Return Total RootBridge per HostBridge.
> +**/
> +UINT8
> +Ac01PcieGetTotalRBsPerHB (
> +  IN UINTN RCIndex
> +  );
> +
> +/**
> +  Get RootBridge Attribute.
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval UINTN                 Return RootBridge Attribute.
> +**/
> +UINTN
> +Ac01PcieGetRootBridgeAttribute (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  );
> +
> +/**
> +  Get RootBridge Segment number
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval UINTN                 Return RootBridge Segment number.
> +**/
> +UINTN
> +Ac01PcieGetRootBridgeSegmentNumber (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  );
> +
> +/**
> +  Initialize Host bridge
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieSetupHostBridge (
> +  IN UINTN HBIndex
> +  );
> +
> +/**
> +  Initialize Root bridge
> +
> +  @param  HBIndex[in]            Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]            Index to identify of underneath PCIE Root bridge.
> +  @param  RootBridgeInstance[in] The pointer of instance of the Root bridge IO.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +  @retval EFI_DEVICE_ERROR      Error when initializing.
> +**/
> +EFI_STATUS
> +Ac01PcieSetupRootBridge (
> +  IN UINTN           HBIndex,
> +  IN UINTN           RBIndex,
> +  IN PCI_ROOT_BRIDGE *RootBridge
> +  );
> +
> +/**
> +  Reads/Writes an PCI configuration register.
> +
> +  @param  RootInstance[in]      Pointer to RootInstance structure.
> +  @param  Address[in]           Address which want to read or write to.
> +  @param  Write[in]             Indicate that this is a read or write command.
> +  @param  Width[in]             Specify the width of the data.
> +  @param  Data[in, out]         The buffer to hold the data.
> +
> +  @retval EFI_SUCCESS           Read/Write successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieConfigRW (
> +  IN     VOID    *RootInstance,
> +  IN     UINT64  Address,
> +  IN     BOOLEAN Write,
> +  IN     UINTN   Width,
> +  IN OUT VOID    *Data
> +  );
> +
> +/**
> +  Callback funciton for EndEnumeration notification from PCI stack.
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
> +  @param  Phase[in]             The phase of enumeration as informed from PCI stack.
> +**/
> +VOID
> +Ac01PcieHostBridgeNotifyPhase (
> +  IN UINTN                                         HBIndex,
> +  IN UINTN                                         RBIndex,
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
> +  );
> +
> +#endif /* PCI_CORE_LIB_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h b/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h
> new file mode 100644
> index 000000000000..fb4c8bbbe994
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Pcie.h

Again, namespaces.

> @@ -0,0 +1,203 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_H_
> +#define PCIE_H_

And here.

> +
> +#define PCIE_CORE_DEBUG
> +#define PCIE_CORE_CFG_DEBUG
> +#undef PCIE_CORE_MMIO_DEBUG

And here.
Etc.
Please add some vendor prefix to all of these.

> +
> +#ifdef PCIE_CORE_CFG_DEBUG
> +#define PCIE_DEBUG_CFG(arg...)               \
> +  if (DebugCodeEnabled()) {                  \
> +    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
> +    DEBUG ((DEBUG_INFO,## arg));             \
> +  }
> +#else
> +#define PCIE_DEBUG_CFG(arg...)
> +#endif
> +
> +#ifdef PCIE_CORE_CSR_DEBUG
> +#define PCIE_CSR_DEBUG(arg...)               \
> +  if (DebugCodeEnabled()) {                  \
> +    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
> +    DEBUG((DEBUG_INFO,## arg))               \
> +  }
> +#else
> +#define PCIE_CSR_DEBUG(arg...)
> +#endif
> +
> +#ifdef PCIE_CORE_PHY_DEBUG
> +#define PCIE_PHY_DEBUG(arg...)               \
> +  if (DebugCodeEnabled()) {                  \
> +    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
> +    DEBUG ((DEBUG_INFO,## arg))              \
> +  }
> +#else
> +#define PCIE_PHY_DEBUG(arg...)
> +#endif
> +
> +#ifdef PCIE_CORE_DEBUG
> +#define PCIE_DEBUG(arg...)                   \
> +  if (DebugCodeEnabled()) {                  \
> +    DEBUG ((DEBUG_INFO,"PCICore (DBG): "));  \
> +    DEBUG ((DEBUG_INFO,## arg));             \
> +  }
> +#else
> +#define PCIE_DEBUG(arg...)
> +#endif
> +
> +#define PCIE_WARN(arg...)                   \
> +  DEBUG ((DEBUG_WARN,"PCICore (WARN): "));  \
> +  DEBUG ((DEBUG_WARN,## arg))
> +
> +#define PCIE_ERR(arg...)                      \
> +  DEBUG ((DEBUG_ERROR,"PCICore (ERROR): "));  \
> +  DEBUG ((DEBUG_ERROR,## arg))
> +
> +#define RCS_PER_SOCKET          8
> +
> +#define PCIE_ERRATA_SPEED1      0x0001 // Limited speed errata
> +
> +#define PRESET_INVALID          0xFF
> +
> +/* Max number for AC01 PCIE Root Complexes */
> +#define MAX_AC01_PCIE_ROOT_COMPLEX   16
> +
> +/* Max number for AC01 PCIE Root Bridge under each Root Complex */
> +#define MAX_AC01_PCIE_ROOT_BRIDGE    1
> +
> +/* The base address of {TCU, CSR, MMCONFIG} Registers */
> +#define AC01_PCIE_REGISTER_BASE    0x33FFE0000000, 0x37FFE0000000, 0x3BFFE0000000, 0x3FFFE0000000, 0x23FFE0000000, 0x27FFE0000000, 0x2BFFE0000000, 0x2FFFE0000000, 0x73FFE0000000, 0x77FFE0000000, 0x7BFFE0000000, 0x7FFFE0000000, 0x63FFE0000000, 0x67FFE0000000, 0x6BFFE0000000, 0x6FFFE0000000
> +
> +/* The base address of MMIO Registers */
> +#define AC01_PCIE_MMIO_BASE        0x300000000000, 0x340000000000, 0x380000000000, 0x3C0000000000, 0x200000000000, 0x240000000000, 0x280000000000, 0x2C0000000000, 0x700000000000, 0x740000000000, 0x780000000000, 0x7C0000000000, 0x600000000000, 0x640000000000, 0x680000000000, 0x6C0000000000
> +
> +/* The base address of MMIO32 Registers*/
> +#define AC01_PCIE_MMIO32_BASE      0x000020000000, 0x000028000000, 0x000030000000, 0x000038000000, 0x000001000000, 0x000008000000, 0x000010000000, 0x000018000000, 0x000060000000, 0x000068000000, 0x000070000000, 0x000078000000, 0x000040000000, 0x000048000000, 0x000050000000, 0x000058000000
> +
> +/* The base address of MMIO32 Registers */
> +#define AC01_PCIE_MMIO32_BASE_1P   0x000040000000, 0x000050000000, 0x000060000000, 0x000070000000, 0x000001000000, 0x000010000000, 0x000020000000, 0x000030000000, 0, 0, 0, 0, 0, 0, 0, 0
> +
> +/* DSDT RCA2 PCIe Meme32 Attribute */
> +#define AC01_PCIE_RCA2_QMEM    0x0000000000000000, 0x0000000060000000, 0x000000006FFFFFFF, 0x0000000000000000, 0x0000000010000000
> +
> +/* DSDT RCA3 PCIe Meme32 Attribute */
> +#define AC01_PCIE_RCA3_QMEM    0x0000000000000000, 0x0000000070000000, 0x000000007FFFFFFF, 0x0000000000000000, 0x0000000010000000
> +
> +/* DSDT RCB0 PCIe Meme32 Attribute */
> +#define AC01_PCIE_RCB0_QMEM    0x0000000000000000, 0x0000000001000000, 0x000000000FFFFFFF, 0x0000000000000000, 0x000000000F000000
> +
> +/* DSDT RCB1 PCIe Meme32 Attribute */
> +#define AC01_PCIE_RCB1_QMEM    0x0000000000000000, 0x0000000010000000, 0x000000001FFFFFFF, 0x0000000000000000, 0x0000000010000000
> +
> +/* DSDT RCB2 PCIe Meme32 Attribute*/
> +#define AC01_PCIE_RCB2_QMEM    0x0000000000000000, 0x0000000020000000, 0x000000002FFFFFFF, 0x0000000000000000, 0x0000000010000000
> +
> +/* DSDT RCB3 PCIe Meme32 Attribute */
> +#define AC01_PCIE_RCB3_QMEM    0x0000000000000000, 0x0000000030000000, 0x000000003FFFFFFF, 0x0000000000000000, 0x0000000010000000
> +
> +/* The start of TBU PMU IRQ array. */
> +#define SMMU_TBU_PMU_IRQ_START_ARRAY  224, 230, 236, 242, 160, 170, 180, 190, 544, 550, 556, 562, 480, 490, 500, 510
> +
> +/* The start of TCU PMU IRQ array */
> +#define SMMU_TCU_PMU_IRQ_START_ARRAY  256, 257, 258, 259, 260, 261, 262, 263, 576, 577, 578, 579, 580, 581, 582, 583
> +
> +enum PCIE_LINK_WIDTH {
> +  LNKW_NONE = 0,
> +  LNKW_X1 = 0x1,
> +  LNKW_X2 = 0x2,
> +  LNKW_X4 = 0x4,
> +  LNKW_X8 = 0x8,
> +  LNKW_X16 = 0x10,
> +};
> +
> +enum PCIE_LINK_SPEED {
> +  SPEED_NONE = 0,
> +  SPEED_GEN1 = 0x1,
> +  SPEED_GEN2 = 0x2,
> +  SPEED_GEN3 = 0x4,
> +  SPEED_GEN4 = 0x8,
> +};
> +
> +enum PCIE_CONTROLLER {
> +  PCIE_0 = 0,
> +  PCIE_1,
> +  PCIE_2,
> +  PCIE_3,
> +  PCIE_4,
> +  MAX_PCIE_A = PCIE_4,
> +  PCIE_5,
> +  PCIE_6,
> +  PCIE_7,
> +  MAX_PCIE,
> +  MAX_PCIE_B = MAX_PCIE
> +};
> +
> +enum RC_TYPE {
> +  RCA,
> +  RCB
> +};
> +
> +enum RC_BLOCK {
> +  RCA0 = 0,
> +  RCA1,
> +  RCA2,
> +  RCA3,
> +  MAX_RCA,
> +  RCB0 = MAX_RCA,
> +  RCB1,
> +  RCB2,
> +  RCB3,
> +  MAX_RCB,
> +  MAX_RC = MAX_RCB
> +};
> +
> +typedef struct {
> +  UINT64  CsrAddr;               // Pointer to CSR Address
> +  UINT64  SnpsRamAddr;           // Pointer to Synopsys SRAM address
> +  UINT8   MaxGen;                // Max speed Gen-1/-2/-3/-4
> +  UINT8   CurGen;                // Current speed Gen-1/-2/-3/-4
> +  UINT8   MaxWidth;              // Max lanes x2/x4/x8/x16
> +  UINT8   CurWidth;              // Current lanes x2/x4/x8/x16
> +  UINT8   ID;                    // ID of the controller within Root Complex
> +  UINT8   DevNum;                // Device number as part of Bus:Dev:Func
> +  BOOLEAN Active;                // Active? Used in bi-furcation mode
> +  BOOLEAN LinkUp;                // PHY and PCIE linkup
> +  BOOLEAN HotPlug;               // Hotplug support
> +} AC01_PCIE;
> +
> +typedef struct {
> +  UINT64    BaseAddr;
> +  UINT64    TcuAddr;
> +  UINT64    HBAddr;
> +  UINT64    MsgAddr;
> +  UINT64    SerdesAddr;
> +  UINT64    MmcfgAddr;
> +  UINT64    MmioAddr;
> +  UINT64    Mmio32Addr;
> +  UINT64    IoAddr;
> +  AC01_PCIE Pcie[MAX_PCIE_B];
> +  UINT8     MaxPcieController;
> +  UINT8     Type;
> +  UINT8     ID;
> +  UINT8     DevMapHi;               // Copy of High Devmap programmed to Host bridge
> +  UINT8     DevMapLo;               // Copy of Low Devmap programmed to Host bridge
> +  UINT8     DefaultDevMapHi;        // Default of High devmap based on board settings
> +  UINT8     DefaultDevMapLo;        // Default of Low devmap based on board settings
> +  UINT8     Socket;
> +  BOOLEAN   Active;
> +  UINT8     Logical;
> +  VOID      *RootBridge;            // Pointer to Stack PCI_ROOT_BRIDGE
> +  UINT32    Flags;                  // Flags
> +  UINT8     PresetGen3[MAX_PCIE_B]; // Preset for Gen3
> +  UINT8     PresetGen4[MAX_PCIE_B]; // Preset for Gen4
> +} AC01_RC;
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
> new file mode 100644
> index 000000000000..9dd1627a85d0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.h
> @@ -0,0 +1,582 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIECORE_H_
> +#define PCIECORE_H_
> +
> +#include <IndustryStandard/Pci.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include "Pcie.h"
> +#include "PcieCoreCapCfg.h"
> +
> +#ifndef BIT
> +#define BIT(nr)                         (1 << (nr))
> +#endif
> +
> +#define MAX_REINIT                       3
> +#define MAX_RETRAIN                      10
> +
> +#define LINK_RETRAIN_SUCCESS             0
> +#define LINK_RETRAIN_FAILED              -1
> +#define LINK_RETRAIN_WRONG_PARAMETER     1
> +
> +#define AMPERE_PCIE_VENDORID             0x1DEF
> +#define AC01_HOST_BRIDGE_DEVICEID_RCA    0xE100
> +#define AC01_HOST_BRIDGE_DEVICEID_RCB    0xE110
> +#define AC01_PCIE_BRIDGE_DEVICEID_RCA    0xE101
> +#define AC01_PCIE_BRIDGE_DEVICEID_RCB    0xE111
> +
> +#define PCIE_MEMRDY_TIMEOUT     10            // 10 us
> +#define PCIE_PIPE_CLOCK_TIMEOUT 20000         // 20,000 us
> +#define PCIE_RETRAIN_TRANSITION_TIMEOUT 20000 // 20,000 us
> +
> +#define LINK_POLL_US_TIMER      1
> +#define IO_SPACE                0x2000
> +#define MMIO32_SPACE            0x8000000ULL
> +#define MMIO_SPACE              0x3FFE0000000ULL
> +
> +#define TCU_OFFSET              0
> +#define HB_CSR_OFFSET           0x01000000
> +#define PCIE0_CSR_OFFSET        0x01010000
> +#define PCIE1_CSR_OFFSET        0x01020000
> +#define PCIE2_CSR_OFFSET        0x01030000
> +#define PCIE3_CSR_OFFSET        0x01040000
> +#define PCIE4_CSR_OFFSET        0x01010000
> +#define PCIE5_CSR_OFFSET        0x01020000
> +#define PCIE6_CSR_OFFSET        0x01030000
> +#define PCIE7_CSR_OFFSET        0x01040000
> +#define SNPSRAM_OFFSET          0x9000
> +#define SERDES_CSR_OFFSET       0x01200000
> +#define MMCONFIG_OFFSET         0x10000000
> +
> +
> +/* DATA LINK registers */
> +#define DLINK_VENDOR_CAP_ID       0x25
> +#define DLINK_VSEC                0x80000001
> +#define DATA_LINK_FEATURE_CAP_OFF 0X4
> +
> +/* PL16 CAP registers */
> +#define PL16_CAP_ID                     0x26
> +#define PL16G_CAP_OFF_20H_REG_OFF       0x20
> +#define PL16G_STATUS_REG_OFF            0x0C
> +#define PL16G_STATUS_EQ_CPL_GET(val)    (val & 0x1)
> +#define PL16G_STATUS_EQ_CPL_P1_GET(val) ((val & 0x2) >> 1)
> +#define PL16G_STATUS_EQ_CPL_P2_GET(val) ((val & 0x4) >> 2)
> +#define PL16G_STATUS_EQ_CPL_P3_GET(val) ((val & 0x8) >> 3)
> +#define DSP_16G_TX_PRESET0_SET(dst,src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
> +#define DSP_16G_TX_PRESET1_SET(dst,src) (((dst) & ~0xF00) | (((UINT32) (src) << 8) & 0xF00))
> +#define DSP_16G_TX_PRESET2_SET(dst,src) (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
> +#define DSP_16G_TX_PRESET3_SET(dst,src) (((dst) & ~0xF000000) | (((UINT32) (src) << 24) & 0xF000000))
> +#define DSP_16G_RXTX_PRESET0_SET(dst,src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +#define DSP_16G_RXTX_PRESET1_SET(dst,src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
> +#define DSP_16G_RXTX_PRESET2_SET(dst,src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
> +#define DSP_16G_RXTX_PRESET3_SET(dst,src) (((dst) & ~0xFF000000) | (((UINT32) (src) << 24) & 0xFF000000))
> +
> +/* PCIe PF0_PORT_LOGIC registers */
> +#define PORT_LOCIG_VC0_P_RX_Q_CTRL_OFF      0x748
> +#define PORT_LOCIG_VC0_NP_RX_Q_CTRL_OFF     0x74C
> +
> +/* TCU registers */
> +#define SMMU_GBPA    0x044
> +
> +/* SNPSRAM Synopsys Memory Read/Write Margin registers */
> +#define SPRF_RMR                0x0
> +#define SPSRAM_RMR              0x4
> +#define TPRF_RMR                0x8
> +#define TPSRAM_RMR              0xC
> +
> +//
> +// Host bridge registers
> +//
> +#define HBRCAPDMR               0x0
> +#define HBRCBPDMR               0x4
> +#define HBPDVIDR                0x10
> +#define HBPRBNR                 0x14
> +#define HBPREVIDR               0x18
> +#define HBPSIDR                 0x1C
> +#define HBPCLSSR                0x20
> +
> +// HBRCAPDMR
> +#define RCAPCIDEVMAP_SET(dst, src) (((dst) & ~0x7) | (((UINT32) (src)) & 0x7))
> +#define RCAPCIDEVMAP_GET(val) ((val) & 0x7)
> +
> +// HBRCBPDMR
> +#define RCBPCIDEVMAPLO_SET(dst, src) (((dst) & ~0x7) | (((UINT32) (src)) & 0x7))
> +#define RCBPCIDEVMAPLO_GET(val) ((val) & 0x7)
> +
> +#define RCBPCIDEVMAPHI_SET(dst, src) (((dst) & ~0x70) | (((UINT32) (src) << 4) & 0x70))
> +#define RCBPCIDEVMAPHI_GET(val) (((val) & 0x7) >> 4)
> +
> +// HBPDVIDR
> +#define PCIVENDID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src))  & 0xFFFF))
> +#define PCIVENDID_GET(val) ((val) & 0xFFFF)
> +
> +#define PCIDEVID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
> +#define PCIDEVID_GET(val) (((val) & 0xFFFF0000) >> 16)
> +
> +// HBPRBNR
> +#define PCIRBNUM_SET(dst, src) (((dst) & ~0x1F) | (((UINT32) (src)) & 0x1F))
> +
> +// HBPREVIDR
> +#define PCIREVID_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +
> +// HBPSIDR
> +#define PCISUBSYSVENDID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
> +
> +#define PCISUBSYSID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
> +
> +// HBPCLSSR
> +#define CACHELINESIZE_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +
> +//
> +// PCIE core register
> +//
> +#define LINKCTRL                0x0
> +#define LINKSTAT                0x4
> +#define IRQSEL                  0xC
> +#define HOTPLUGSTAT             0x28
> +#define IRQENABLE               0x30
> +#define IRQEVENTSTAT            0x38
> +#define BLOCKEVENTSTAT          0x3c
> +#define RESET                   0xC000
> +#define CLOCK                   0xC004
> +#define MEMRDYR                 0xC104
> +#define RAMSDR                  0xC10C
> +
> +// LINKCTRL
> +#define LTSSMENB_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +#define DEVICETYPE_SET(dst, src) (((dst) & ~0xF0) | (((UINT32) (src) << 4) & 0xF0))
> +#define DEVICETYPE_GET(val) (((val) & 0xF0) >> 4)
> +
> +// LINKSTAT
> +#define PHY_STATUS_MASK         (1 << 2)
> +#define SMLH_LTSSM_STATE_MASK   0x3f00
> +#define SMLH_LTSSM_STATE_GET(val) ((val & 0x3F00) >> 8)
> +#define RDLH_SMLH_LINKUP_STATUS_GET(val)    (val & 0x3)
> +#define PHY_STATUS_MASK_BIT     0x04
> +#define SMLH_LINK_UP_MASK_BIT   0x02
> +#define RDLH_LINK_UP_MASK_BIT   0x01
> +
> +// IRQSEL
> +#define AER_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +#define PME_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
> +#define LINKAUTOBW_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
> +#define BWMGMT_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << 3) & 0x8))
> +#define EQRQST_SET(dst, src) (((dst) & ~0x10) | (((UINT32) (src) << 4) & 0x10))
> +#define INTPIN_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
> +
> +// SLOTCAP
> +#define SLOT_HPC_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
> +
> +// HOTPLUGSTAT
> +#define PWR_IND_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +#define ATTEN_IND_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
> +#define PWR_CTRL_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
> +#define EML_CTRL_SET(dst, src) (((dst) & ~0x8) | (((UINT32) (src) << 3) & 0x8))
> +
> +// IRQENABLE
> +#define LINKUP_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
> +
> +// IRQEVENTSTAT
> +#define BLOCK_INT_MASK          (1 << 4)
> +#define PCIE_INT_MASK           (1 << 3)
> +
> +// BLOCKEVENTSTAT
> +#define LINKUP_MASK             (1 << 0)
> +
> +// RESET
> +#define DWCPCIE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +#define RESET_MASK              0x1
> +
> +// CLOCK
> +#define AXIPIPE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +// RAMSDR
> +#define SD_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +//
> +// PHY registers
> +//
> +#define RSTCTRL                 0x0
> +#define PHYCTRL                 0x4
> +#define RAMCTRL                 0x8
> +#define RAMSTAT                 0xC
> +#define PLLCTRL                 0x10
> +#define PHYLPKCTRL              0x14
> +#define PHYTERMOFFSET0          0x18
> +#define PHYTERMOFFSET1          0x1C
> +#define PHYTERMOFFSET2          0x20
> +#define PHYTERMOFFSET3          0x24
> +#define RXTERM                  0x28
> +#define PHYDIAGCTRL             0x2C
> +
> +// RSTCTRL
> +#define PHY_RESET_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +// PHYCTRL
> +#define PWR_STABLE_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +//
> +// PCIe config space registers
> +//
> +#define TYPE1_DEV_ID_VEND_ID_REG                0
> +#define TYPE1_CLASS_CODE_REV_ID_REG             0x8
> +#define TYPE1_CAP_PTR_REG                       0x34
> +#define SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG       0x18
> +#define BRIDGE_CTRL_INT_PIN_INT_LINE_REG        0x3c
> +#define CON_STATUS_REG                          (PM_CAP + 0x4)
> +#define LINK_CAPABILITIES_REG                   (PCIE_CAP + 0xc)
> +#define LINK_CONTROL_LINK_STATUS_REG            (PCIE_CAP + 0x10)
> +#define SLOT_CAPABILITIES_REG                   (PCIE_CAP + 0x14)
> +#define DEVICE_CONTROL2_DEVICE_STATUS2_REG      (PCIE_CAP + 0x28)
> +#define LINK_CAPABILITIES2_REG                  (PCIE_CAP + 0x2c)
> +#define LINK_CONTROL2_LINK_STATUS2_REG          (PCIE_CAP + 0x30)
> +#define UNCORR_ERR_STATUS_OFF                   (AER_CAP + 0x4)
> +#define UNCORR_ERR_MASK_OFF                     (AER_CAP + 0x8)
> +#define RESOURCE_CON_REG_VC0                    (VC_CAP + 0x14)
> +#define RESOURCE_CON_REG_VC1                    (VC_CAP + 0x20)
> +#define RESOURCE_STATUS_REG_VC1                 (VC_CAP + 0x24)
> +#define SD_CONTROL1_REG                         (RAS_DES_CAP+0xA0)
> +#define CCIX_TP_CAP_TP_HDR2_OFF                 (CCIX_TP_CAP + 0x8)
> +#define ESM_MNDTRY_RATE_CAP_OFF                 (CCIX_TP_CAP + 0xc)
> +#define ESM_STAT_OFF                            (CCIX_TP_CAP + 0x14)
> +#define ESM_CNTL_OFF                            (CCIX_TP_CAP + 0x18)
> +#define ESM_LN_EQ_CNTL_25G_0_OFF                (CCIX_TP_CAP + 0x2c)
> +#define PORT_LINK_CTRL_OFF                      0x710
> +#define FILTER_MASK_2_OFF                       0x720
> +#define GEN2_CTRL_OFF                           0x80c
> +#define GEN3_RELATED_OFF                        0x890
> +#define GEN3_EQ_CONTROL_OFF                     0x8A8
> +#define MISC_CONTROL_1_OFF                      0x8bc
> +#define AMBA_ERROR_RESPONSE_DEFAULT_OFF         0x8d0
> +#define AMBA_LINK_TIMEOUT_OFF                   0x8d4
> +#define AMBA_ORDERING_CTRL_OFF                  0x8d8
> +#define DTIM_CTRL0_OFF                          0xab0
> +#define AUX_CLK_FREQ_OFF                        0xb40
> +#define CCIX_CTRL_OFF                           0xc20
> +
> +#define DEV_MASK 0x00F8000
> +#define BUS_MASK 0xFF00000
> +#define BUS_NUM(Addr) ((((UINT64)(Addr)) & BUS_MASK) >> 20)
> +#define DEV_NUM(Addr) ((((UINT64)(Addr)) & DEV_MASK) >> 15)
> +#define CFG_REG(Addr) (((UINT64)Addr) & 0x7FFF)
> +
> +// TYPE1_DEV_ID_VEND_ID_REG
> +#define VENDOR_ID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
> +#define DEVICE_ID_SET(dst, src) (((dst) & ~0xFFFF0000) | (((UINT32) (src) << 16) & 0xFFFF0000))
> +
> +// TYPE1_CLASS_CODE_REV_ID_REG
> +#define BASE_CLASS_CODE_SET(dst, src) (((dst) & ~0xFF000000) | (((UINT32) (src) << 24) & 0xFF000000))
> +#define SUBCLASS_CODE_SET(dst, src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
> +#define PROGRAM_INTERFACE_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
> +#define REVISION_ID_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +
> +// SEC_LAT_TIMER_SUB_BUS_SEC_BUS_PRI_BUS_REG
> +#define SUB_BUS_SET(dst, src) (((dst) & ~0xFF0000) | (((UINT32) (src) << 16) & 0xFF0000))
> +#define SEC_BUS_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
> +#define PRIM_BUS_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +
> +// BRIDGE_CTRL_INT_PIN_INT_LINE_REG
> +#define INT_PIN_SET(dst, src) (((dst) & ~0xFF00) | (((UINT32) (src) << 8) & 0xFF00))
> +
> +// CON_STATUS_REG
> +#define POWER_STATE_SET(dst, src) (((dst) & ~0x3) | (((UINT32) (src)) & 0x3))
> +
> +// DEVICE_CONTROL2_DEVICE_STATUS2_REG
> +#define PCIE_CAP_CPL_TIMEOUT_VALUE_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
> +
> +// LINK_CAPABILITIES_REG
> +#define PCIE_CAP_ID                             0x10
> +#define LINK_CAPABILITIES_REG_OFF               0xC
> +#define LINK_CONTROL_LINK_STATUS_OFF            0x10
> +#define PCIE_CAP_MAX_LINK_WIDTH_X1              0x1
> +#define PCIE_CAP_MAX_LINK_WIDTH_X2              0x2
> +#define PCIE_CAP_MAX_LINK_WIDTH_X4              0x4
> +#define PCIE_CAP_MAX_LINK_WIDTH_X8              0x8
> +#define PCIE_CAP_MAX_LINK_WIDTH_X16             0x10
> +#define PCIE_CAP_MAX_LINK_WIDTH_GET(val) ((val & 0x3F0) >> 4)
> +#define PCIE_CAP_MAX_LINK_WIDTH_SET(dst, src) (((dst) & ~0x3F0) | (((UINT32) (src) << 4) & 0x3F0))
> +#define MAX_LINK_SPEED_25                       0x1
> +#define MAX_LINK_SPEED_50                       0x2
> +#define MAX_LINK_SPEED_80                       0x3
> +#define MAX_LINK_SPEED_160                      0x4
> +#define MAX_LINK_SPEED_320                      0x5
> +#define PCIE_CAP_MAX_LINK_SPEED_GET(val) ((val & 0xF))
> +#define PCIE_CAP_MAX_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
> +#define PCIE_CAP_SLOT_CLK_CONFIG_SET(dst, src) (((dst) & ~0x10000000) | (((UINT32) (src) << 28) & 0x10000000))
> +#define NO_ASPM_SUPPORTED                       0x0
> +#define L0S_SUPPORTED                           0x1
> +#define L1_SUPPORTED                            0x2
> +#define L0S_L1_SUPPORTED                        0x3
> +#define PCIE_CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET(dst, src) (((dst) & ~0xC00) | (((UINT32)(src) << 10) & 0xC00))
> +
> +// LINK_CONTROL_LINK_STATUS_REG
> +#define PCIE_CAP_DLL_ACTIVE_GET(val) ((val & 0x20000000) >> 29)
> +#define PCIE_CAP_NEGO_LINK_WIDTH_GET(val) ((val & 0x3F00000) >> 20)
> +#define PCIE_CAP_LINK_SPEED_GET(val) ((val & 0xF0000) >> 16)
> +#define PCIE_CAP_LINK_SPEED_SET(dst, src) (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
> +#define CAP_LINK_SPEED_TO_VECTOR(val)          BIT((val)-1)
> +#define PCIE_CAP_EN_CLK_POWER_MAN_GET(val) ((val & 0x100) >> 8)
> +#define PCIE_CAP_EN_CLK_POWER_MAN_SET(dst, src) (((dst) & ~0x100) | (((UINT32) (src) << 8) & 0x100))
> +#define PCIE_CAP_RETRAIN_LINK_SET(dst, src) (((dst) & ~0x20) | (((UINT32) (src) << 5) & 0x20))
> +#define PCIE_CAP_COMMON_CLK_SET(dst, src) (((dst) & ~0x40) | (((UINT32) (src) << 6) & 0x40))
> +#define PCIE_CAP_LINK_TRAINING_GET(val)     ((val & 0x8000000) >> 27)

Vendor prefix.

/
    Leif

> +
> +// LINK_CAPABILITIES2_REG
> +#define LINK_SPEED_VECTOR_25                    BIT(0)
> +#define LINK_SPEED_VECTOR_50                    BIT(1)
> +#define LINK_SPEED_VECTOR_80                    BIT(2)
> +#define LINK_SPEED_VECTOR_160                   BIT(3)
> +#define LINK_SPEED_VECTOR_320                   BIT(4)
> +#define PCIE_CAP_SUPPORT_LINK_SPEED_VECTOR_GET(val) ((val & 0xFE) >> 1)
> +#define PCIE_CAP_SUPPORT_LINK_SPEED_VECTOR_SET(dst, src) (((dst) & ~0xFE) | (((UINT32) (src) << 1) & 0xFE))
> +#define PCIE_CAP_EQ_CPL_GET(val)        ((val & 0x20000) >> 17)
> +#define PCIE_CAP_EQ_CPL_P1_GET(val)     ((val & 0x40000) >> 18)
> +#define PCIE_CAP_EQ_CPL_P2_GET(val)     ((val & 0x80000) >> 19)
> +#define PCIE_CAP_EQ_CPL_P3_GET(val)     ((val & 0x100000) >> 20)
> +
> +// LINK_CONTROL2_LINK_STATUS2_REG
> +#define PCIE_CAP_TARGET_LINK_SPEED_SET(dst, src) (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
> +
> +// Secondary Capability
> +#define SPCIE_CAP_ID                0x19
> +#define CAP_OFF_0C                  0x0C
> +#define LINK_CONTROL3_REG_OFF       0x4
> +#define DSP_TX_PRESET0_SET(dst,src)  (((dst) & ~0xF) | (((UINT32) (src)) & 0xF))
> +#define DSP_TX_PRESET1_SET(dst,src)  (((dst) & ~0xF0000) | (((UINT32) (src) << 16) & 0xF0000))
> +
> +// UNCORR_ERR_STATUS_OFF
> +#define CMPLT_TIMEOUT_ERR_STATUS_GET(val) ((val & 0x4000) >> 14)
> +#define CMPLT_TIMEOUT_ERR_STATUS_SET(dst, src) (((dst) & ~0x4000) | (((UINT32) (src) << 14) & 0x4000))
> +
> +// UNCORR_ERR_MASK_OFF
> +#define CMPLT_TIMEOUT_ERR_MASK_SET(dst, src) (((dst) & ~0x4000) | (((UINT32) (src) << 14) & 0x4000))
> +#define SDES_ERR_MASK_SET(dst, src) (((dst) & ~0x20) | (((UINT32)(src) << 5) & 0x20))
> +
> +// RESOURCE_STATUS_REG_VC1
> +#define VC_NEGO_PENDING_VC1_GET(val) ((val & 0x20000) >> 17)
> +
> +// SD_CONTROL1_REG
> +#define FORCE_DETECT_LANE_EN_SET(dst, src) (((dst) & ~0x10000) | (((UINT32) (src) << 16) & 0x10000))
> +
> +// CCIX_TP_CAP_TP_HDR2_OFF
> +#define ESM_REACH_LENGTH_GET(val) ((val & 0x60000) >> 17)
> +#define ESM_CALIBRATION_TIME_GET(val) ((val & 0x700000) >> 20)
> +#define ESM_CALIBRATION_TIME_SET(dst, src) (((dst) & ~0x700000) | (((UINT32) (src) << 20) & 0x700000))
> +
> +// ESM_STAT_OFF
> +#define ESM_CALIB_CMPLT_GET(val) ((val & 0x80) >> 7)
> +#define ESM_CURNT_DATA_RATE_GET(val) ((val & 0x7F) >> 0)
> +
> +// ESM_CNTL_OFF
> +#define QUICK_EQ_TIMEOUT_SET(dst, src) (((dst) & ~0x1C000000) | (((UINT32) (src) << 26) & 0x1C000000))
> +#define LINK_REACH_TARGET_GET(val) ((val & 0x1000000) >> 24)
> +#define LINK_REACH_TARGET_SET(dst, src) (((dst) & ~0x1000000) | (((UINT32) (src) << 24) & 0x1000000))
> +#define ESM_EXT_EQ3_DSP_TIMEOUT_GET(val) ((val & 0x700000) >> 20)
> +#define ESM_EXT_EQ3_DSP_TIMEOUT_SET(dst, src) (((dst) & ~0x700000) | (((UINT32) (src) << 20) & 0x700000))
> +#define ESM_EXT_EQ2_USP_TIMEOUT_GET(val) ((val & 0x70000) >> 16)
> +#define ESM_EXT_EQ2_USP_TIMEOUT_SET(dst, src) (((dst) & ~0x70000) | (((UINT32) (src) << 16) & 0x70000))
> +#define ESM_ENABLE_SET(dst, src) (((dst) & ~0x8000) | (((UINT32) (src) << 15) & 0x8000))
> +#define ESM_DATA_RATE1_SET(dst, src) (((dst) & ~0x7F00) | (((UINT32) (src) << 8) & 0x7F00))
> +#define ESM_PERFORM_CAL_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
> +#define ESM_DATA_RATE0_SET(dst, src) (((dst) & ~0x7F) | (((UINT32) (src)) & 0x7F))
> +
> +// PORT_LINK_CTRL_OFF
> +#define LINK_CAPABLE_X1                 0x1
> +#define LINK_CAPABLE_X2                 0x3
> +#define LINK_CAPABLE_X4                 0x7
> +#define LINK_CAPABLE_X8                 0xF
> +#define LINK_CAPABLE_X16                0x1F
> +#define LINK_CAPABLE_X32                0x3F
> +#define LINK_CAPABLE_SET(dst, src) (((dst) & ~0x3F0000) | (((UINT32) (src) << 16) & 0x3F0000))
> +#define FAST_LINK_MODE_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
> +
> +// FILTER_MASK_2_OFF
> +#define CX_FLT_MASK_VENMSG0_DROP_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +#define CX_FLT_MASK_VENMSG1_DROP_SET(dst, src) (((dst) & ~0x2) | (((UINT32) (src) << 1) & 0x2))
> +#define CX_FLT_MASK_DABORT_4UCPL_SET(dst, src) (((dst) & ~0x4) | (((UINT32) (src) << 2) & 0x4))
> +
> +// GEN2_CTRL_OFF
> +#define NUM_OF_LANES_X2                 0x2
> +#define NUM_OF_LANES_X4                 0x4
> +#define NUM_OF_LANES_X8                 0x8
> +#define NUM_OF_LANES_X16                0x10
> +#define NUM_OF_LANES_SET(dst, src) (((dst) & ~0x1F00) | (((UINT32) (src) << 8) & 0x1F00))
> +
> +// GEN3_RELATED_OFF
> +#define RATE_SHADOW_SEL_SET(dst, src) (((dst) & ~0x3000000) | (((UINT32) (src) << 24) & 0x3000000))
> +#define EQ_PHASE_2_3_SET(dst, src) (((dst) & ~0x200) | (((UINT32) (src) << 9) & 0x200))
> +#define RXEQ_REGRDLESS_SET(dst, src) (((dst) & ~0x2000) | (((UINT32) (src) << 13) & 0x2000))
> +
> +// GEN3_EQ_CONTROL_OFF
> +#define GEN3_EQ_FB_MODE(dst, src) (((dst) & ~0xF) | ((UINT32) (src) & 0xF))
> +#define GEN3_EQ_PRESET_VEC(dst, src) (((dst) & 0xFF0000FF) | (((UINT32) (src) << 8) & 0xFFFF00))
> +#define GEN3_EQ_INIT_EVAL(dst,src) (((dst) & ~0x1000000) | (((UINT32) (src) << 24) & 0x1000000))
> +
> +// MISC_CONTROL_1_OFF
> +#define DBI_RO_WR_EN_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +// AMBA_ERROR_RESPONSE_DEFAULT_OFF
> +#define AMBA_ERROR_RESPONSE_CRS_SET(dst, src) (((dst) & ~0x18) | (((UINT32) (src) << 3) & 0x18))
> +#define AMBA_ERROR_RESPONSE_GLOBAL_SET(dst, src) (((dst) & ~0x1) | (((UINT32) (src)) & 0x1))
> +
> +// AMBA_LINK_TIMEOUT_OFF
> +#define LINK_TIMEOUT_PERIOD_DEFAULT_SET(dst, src) (((dst) & ~0xFF) | (((UINT32) (src)) & 0xFF))
> +
> +// AMBA_ORDERING_CTRL_OFF
> +#define AX_MSTR_ZEROLREAD_FW_SET(dst, src) (((dst) & ~0x80) | (((UINT32) (src) << 7) & 0x80))
> +
> +// DTIM_CTRL0_OFF
> +#define DTIM_CTRL0_ROOT_PORT_ID_SET(dst, src) (((dst) & ~0xFFFF) | (((UINT32) (src)) & 0xFFFF))
> +
> +// AUX_CLK_FREQ_OFF
> +#define AUX_CLK_500MHZ 500
> +#define AUX_CLK_FREQ_SET(dst, src) (((dst) & ~0x1FF) | (((UINT32) (src)) & 0x1FF))
> +
> +#define EXT_CAP_OFFSET_START 0x100
> +
> +enum LTSSM_STATE {
> +  S_DETECT_QUIET = 0,
> +  S_DETECT_ACT,
> +  S_POLL_ACTIVE,
> +  S_POLL_COMPLIANCE,
> +  S_POLL_CONFIG,
> +  S_PRE_DETECT_QUIET,
> +  S_DETECT_WAIT,
> +  S_CFG_LINKWD_START,
> +  S_CFG_LINKWD_ACEPT,
> +  S_CFG_LANENUM_WAI,
> +  S_CFG_LANENUM_ACEPT,
> +  S_CFG_COMPLETE,
> +  S_CFG_IDLE,
> +  S_RCVRY_LOCK,
> +  S_RCVRY_SPEED,
> +  S_RCVRY_RCVRCFG,
> +  S_RCVRY_IDLE,
> +  S_L0,
> +  S_L0S,
> +  S_L123_SEND_EIDLE,
> +  S_L1_IDLE,
> +  S_L2_IDLE,
> +  S_L2_WAKE,
> +  S_DISABLED_ENTRY,
> +  S_DISABLED_IDLE,
> +  S_DISABLED,
> +  S_LPBK_ENTRY,
> +  S_LPBK_ACTIVE,
> +  S_LPBK_EXIT,
> +  S_LPBK_EXIT_TIMEOUT,
> +  S_HOT_RESET_ENTRY,
> +  S_HOT_RESET,
> +  S_RCVRY_EQ0,
> +  S_RCVRY_EQ1,
> +  S_RCVRY_EQ2,
> +  S_RCVRY_EQ3,
> +  MAX_LTSSM_STATE
> +};
> +
> +INT32
> +Ac01PcieCfgOut32 (
> +  VOID   *Addr,
> +  UINT32 Val
> +  );
> +
> +INT32
> +Ac01PcieCfgOut16 (
> +  VOID   *Addr,
> +  UINT16 Val
> +  );
> +
> +INT32
> +Ac01PcieCfgOut8 (
> +  VOID  *Addr,
> +  UINT8 Val
> +  );
> +
> +INT32
> +Ac01PcieCfgIn32 (
> +  VOID   *Addr,
> +  UINT32 *Val
> +  );
> +
> +INT32
> +Ac01PcieCfgIn16 (
> +  VOID   *Addr,
> +  UINT16 *Val
> +  );
> +
> +INT32
> +Ac01PcieCfgIn8 (
> +  VOID  *Addr,
> +  UINT8 *Val
> +  );
> +
> +INT32
> +Ac01PcieCoreSetup (
> +  AC01_RC *RC
> +  );
> +
> +VOID
> +Ac01PcieCoreResetPort (
> +  AC01_RC *RC
> +  );
> +
> +VOID
> +Ac01PcieClearConfigPort (
> +  AC01_RC *RC
> +  );
> +
> +AC01_RC *
> +GetRCList (
> +  UINT8 Idx
> +  );
> +
> +VOID
> +Ac01PcieCoreBuildRCStruct (
> +  AC01_RC *RC,
> +  UINT64  RegBase,
> +  UINT64  MmioBase,
> +  UINT64  Mmio32Base
> +  );
> +
> +INT32
> +Ac01PcieCoreSetupRC (
> +  IN AC01_RC *RC,
> +  IN UINT8   ReInit,
> +  IN UINT8   ReInitPcieIndex
> +  );
> +
> +VOID
> +Ac01PcieCoreUpdateLink (
> +  IN  AC01_RC *RC,
> +  OUT BOOLEAN *IsNextRoundNeeded,
> +  OUT INT8    *FailedPciePtr,
> +  OUT INT8    *FailedPcieCount
> +  );
> +
> +VOID
> +Ac01PcieCoreEndEnumeration (
> +  AC01_RC *RC
> +  );
> +
> +INT32
> +Ac01PcieCoreQoSLinkCheckRecovery (
> +  IN AC01_RC *RC,
> +  IN INTN    PcieIndex
> +  );
> +
> +#endif /* PCIECORE_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
> new file mode 100755
> index 000000000000..0da47cb4e9d3
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreCapCfg.h
> @@ -0,0 +1,64 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef X16_CAP_PORT_CFG_H_
> +#define X16_CAP_PORT_CFG_H_
> +
> +
> +/* PCIe config space capabilities offset */
> +#define PM_CAP          0x40
> +#define MSI_CAP         0x50
> +#define PCIE_CAP        0x70
> +#define MSIX_CAP        0xB0
> +#define SLOT_CAP        0xC0
> +#define VPD_CAP         0xD0
> +#define SATA_CAP        0xE0
> +#define CFG_NEXT_CAP    0x40
> +#define PM_NEXT_CAP     0x70
> +#define MSI_NEXT_CAP    0x00
> +#define PCIE_NEXT_CAP   0x00
> +#define MSIX_NEXT_CAP   0x00
> +#define SLOT_NEXT_CAP   0x00
> +#define VPD_NEXT_CAP    0x00
> +#define SATA_NEXT_CAP   0x00
> +#define BASE_CAP        0x100
> +#define AER_CAP         0x100
> +#define VC_CAP          0x148
> +#define SN_CAP          0x178
> +#define PB_CAP          0x178
> +#define ARI_CAP         0x178
> +#define SPCIE_CAP_x8    0x148
> +#define SPCIE_CAP       0x178
> +#define PL16G_CAP       0x1A8
> +#define MARGIN_CAP      0x1D8
> +#define PL32G_CAP       0x220
> +#define SRIOV_CAP       0x220
> +#define TPH_CAP         0x220
> +#define ATS_CAP         0x220
> +#define ACS_CAP         0x230
> +#define PRS_CAP         0x238
> +#define LTR_CAP         0x248
> +#define L1SUB_CAP       0x248
> +#define PASID_CAP       0x248
> +#define DPA_CAP         0x248
> +#define DPC_CAP         0x248
> +#define MPCIE_CAP       0x248
> +#define FRSQ_CAP        0x248
> +#define RTR_CAP         0x248
> +#define LN_CAP          0x248
> +#define RAS_DES_CAP     0x248
> +#define VSECRAS_CAP     0x348
> +#define DLINK_CAP       0x380
> +#define PTM_CAP         0x38C
> +#define PTM_VSEC_CAP    0x38C
> +#define CCIX_TP_CAP     0x38C
> +#define CXS_CAP         0x3D0
> +#define RBAR_CAP        0x3E8
> +#define VF_RBAR_CAP     0x3E8
> +
> +#endif /* X16_CAP_PORT_CFG_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
> new file mode 100755
> index 000000000000..c9356f658778
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.h
> @@ -0,0 +1,30 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIEPATCHACPI_H_
> +#define PCIEPATCHACPI_H_
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiPatchPciMem32 (
> +  INT8 *PciSegEnabled
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiInstallMcfg (
> +  INT8 *PciSegEnabled
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiInstallIort (
> +  INT8 *PciSegEnabled
> +  );
> +
> +#endif /* PCIEPATCHACPI_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
> new file mode 100644
> index 000000000000..a798d995ba9d
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCore.c
> @@ -0,0 +1,1266 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PcieBoardLib.h>
> +#include <Library/PciePhyLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +#include <PlatformInfoHob.h>
> +
> +#include "Pcie.h"
> +#include "PcieCore.h"
> +
> +#define DEV_MASK 0x00F8000
> +#define BUS_MASK 0xFF00000
> +
> +STATIC INT32
> +Ac01PcieCsrOut32 (
> +  VOID   *Addr,
> +  UINT32 Val
> +  )
> +{
> +  MmioWrite32 ((UINT64)Addr, Val);
> +  PCIE_CSR_DEBUG (
> +    "PCIE CSR WR: 0x%p value: 0x%08X (0x%08X)\n",
> +    Addr,
> +    Val,
> +    MmioRead32 ((UINT64)Addr)
> +    );
> +
> +  return 0;
> +}
> +
> +STATIC INT32
> +Ac01PcieCsrOut32Serdes (
> +  VOID   *Addr,
> +  UINT32 Val
> +  )
> +{
> +  MmioWrite32 ((UINT64)Addr, Val);
> +  PCIE_CSR_DEBUG (
> +    "PCIE CSR WR: 0x%p value: 0x%08X (0x%08X)\n",
> +    Addr,
> +    Val,
> +    MmioRead32 ((UINT64)Addr)
> +    );
> +
> +  return 0;
> +}
> +
> +STATIC INT32
> +Ac01PcieCsrIn32 (
> +  VOID   *Addr,
> +  UINT32 *Val
> +  )
> +{
> +  *Val = MmioRead32 ((UINT64)Addr);
> +  PCIE_CSR_DEBUG ("PCIE CSR RD: 0x%p value: 0x%08X\n", Addr, *Val);
> +
> +  return 0;
> +}
> +
> +STATIC INT32
> +Ac01PcieCsrIn32Serdes (
> +  VOID   *Addr,
> +  UINT32 *Val
> +  )
> +{
> +  *Val = MmioRead32 ((UINT64)Addr);
> +  PCIE_CSR_DEBUG ("PCIE CSR RD: 0x%p value: 0x%08X\n", Addr, *Val);
> +
> +  return 0;
> +}
> +
> +VOID
> +Ac01PcieMmioRd (
> +  UINT64 Addr,
> +  UINT32 *Val
> +  )
> +{
> +  Ac01PcieCsrIn32Serdes ((VOID *)Addr, (UINT32 *)Val);
> +}
> +
> +VOID
> +Ac01PcieMmioWr (
> +  UINT64 Addr,
> +  UINT32 Val
> +  )
> +{
> +  Ac01PcieCsrOut32Serdes ((VOID *)Addr, (UINT32)Val);
> +}
> +
> +VOID
> +Ac01PciePuts (
> +  CONST CHAR8 *Msg
> +  )
> +{
> +  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
> +}
> +
> +VOID
> +Ac01PciePutInt (
> +  UINT32 val
> +  )
> +{
> +  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
> +}
> +
> +VOID
> +Ac01PciePutHex (
> +  UINT64 val
> +  )
> +{
> +  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
> +}
> +
> +INT32
> +Ac01PcieDebugPrint (
> +  CONST CHAR8 *fmt,
> +  ...
> +  )
> +{
> +  PCIE_PHY_DEBUG ("%a\n", __FUNCTION__);
> +  return 0;
> +}
> +
> +VOID
> +Ac01PcieDelay (
> +  UINT32 Val
> +  )
> +{
> +  MicroSecondDelay (Val);
> +}
> +
> +/**
> +   Write 32-bit value to config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           32-bit value to write
> +**/
> +INT32
> +Ac01PcieCfgOut32 (
> +  IN VOID   *Addr,
> +  IN UINT32 Val
> +  )
> +{
> +  MmioWrite32 ((UINT64)Addr, Val);
> +  PCIE_DEBUG_CFG (
> +    "PCIE CFG WR: 0x%p value: 0x%08X (0x%08X)\n",
> +    Addr,
> +    Val,
> +    MmioRead32 ((UINT64)Addr)
> +    );
> +
> +  return 0;
> +}
> +
> +/**
> +   Write 16-bit value to config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           16-bit value to write
> +**/
> +INT32
> +Ac01PcieCfgOut16 (
> +  IN VOID   *Addr,
> +  IN UINT16 Val
> +  )
> +{
> +  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
> +  UINT32 Val32  = MmioRead32 (AlignedAddr);
> +
> +  switch ((UINT64)Addr & 0x3) {
> +  case 2:
> +    Val32 &= ~0xFFFF0000;
> +    Val32 |= (UINT32)Val << 16;
> +    break;
> +
> +  case 0:
> +  default:
> +    Val32 &= ~0xFFFF;
> +    Val32 |= Val;
> +    break;
> +  }
> +  MmioWrite32 (AlignedAddr, Val32);
> +  PCIE_DEBUG_CFG (
> +    "PCIE CFG WR16: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
> +    Addr,
> +    Val,
> +    AlignedAddr,
> +    MmioRead32 ((UINT64)AlignedAddr)
> +    );
> +
> +  return 0;
> +}
> +
> +/**
> +   Write 8-bit value to config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           8-bit value to write
> +**/
> +INT32
> +Ac01PcieCfgOut8 (
> +  IN VOID  *Addr,
> +  IN UINT8 Val
> +  )
> +{
> +  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
> +  UINT32 Val32  = MmioRead32 (AlignedAddr);
> +
> +  switch ((UINT64)Addr & 0x3) {
> +  case 0:
> +    Val32 &= ~0xFF;
> +    Val32 |= Val;
> +    break;
> +
> +  case 1:
> +    Val32 &= ~0xFF00;
> +    Val32 |= (UINT32)Val << 8;
> +    break;
> +
> +  case 2:
> +    Val32 &= ~0xFF0000;
> +    Val32 |= (UINT32)Val << 16;
> +    break;
> +
> +  case 3:
> +  default:
> +    Val32 &= ~0xFF000000;
> +    Val32 |= (UINT32)Val << 24;
> +    break;
> +  }
> +  MmioWrite32 (AlignedAddr, Val32);
> +  PCIE_DEBUG_CFG (
> +    "PCIE CFG WR8: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
> +    Addr,
> +    Val,
> +    AlignedAddr,
> +    MmioRead32 ((UINT64)AlignedAddr)
> +    );
> +
> +  return 0;
> +}
> +
> +/**
> +   Read 32-bit value from config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           Point to address for read value
> +**/
> +INT32
> +Ac01PcieCfgIn32 (
> +  IN  VOID   *Addr,
> +  OUT UINT32 *Val
> +  )
> +{
> +  UINT32 RegC, Reg18;
> +  UINT8  MfHt, Primary = 0, Sec = 0, Sub = 0;
> +
> +  if ((BUS_NUM (Addr) > 0) && (DEV_NUM (Addr) > 0) && (CFG_REG (Addr) == 0)) {
> +    *Val = MmioRead32 ((UINT64)Addr);
> +    PCIE_DEBUG_CFG (
> +      "PCIE CFG RD: B%X|D%X 0x%p value: 0x%08X\n",
> +      BUS_NUM (Addr),
> +      DEV_NUM (Addr),
> +      Addr,
> +      *Val
> +      );
> +
> +    if (*Val != 0xffffffff) {
> +      RegC = MmioRead32 ((UINT64)Addr + 0xC);
> +      PCIE_DEBUG_CFG ("Peek PCIE MfHt RD32: 0x%p value: 0x%08X\n", Addr + 0xc, RegC);
> +      MfHt = RegC >> 16;
> +      PCIE_DEBUG_CFG ("  Peek RD8 MfHt=0x%02X\n", MfHt);
> +
> +      if ((MfHt & 0x7F)!= 0) { /* Type 1 header */
> +        Reg18 = MmioRead32 ((UINT64)Addr + 0x18);
> +        Primary = Reg18; Sec = Reg18 >> 8; Sub = Reg18 >> 16;
> +        PCIE_DEBUG_CFG (
> +          "  Bus Peek PCIE Sub:%01X Sec:%01X Primary:%01X  RD: 0x%p value: 0x%08X\n",
> +          Sub,
> +          Sec,
> +          Primary,
> +          Addr + 0x18,
> +          Reg18
> +          );
> +      }
> +      if ((MfHt == 0) || (Primary != 0)) { /* QS RPs Primary Bus is 0b */
> +        *Val = 0xffffffff;
> +        PCIE_DEBUG_CFG (
> +          "  Skip RD32 B%X|D%X PCIE CFG RD: 0x%p return 0xffffffff\n",
> +          BUS_NUM (Addr),
> +          DEV_NUM (Addr),
> +          Addr
> +          );
> +      }
> +    }
> +  } else {
> +    *Val = MmioRead32 ((UINT64)Addr);
> +  }
> +  PCIE_DEBUG_CFG ("PCIE CFG RD: 0x%p value: 0x%08X\n", Addr, *Val);
> +
> +  return 0;
> +}
> +
> +/**
> +   Read 16-bit value from config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           Point to address for read value
> +**/
> +INT32
> +Ac01PcieCfgIn16 (
> +  IN  VOID   *Addr,
> +  OUT UINT16 *Val
> +  )
> +{
> +  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
> +  UINT32 RegC, Reg18;
> +  UINT8  MfHt, Primary = 0, Sec = 0, Sub = 0;
> +  UINT32 Val32;
> +
> +  if ((BUS_NUM (Addr) > 0) && (DEV_NUM (Addr) > 0) && (CFG_REG (Addr) == 0)) {
> +    *Val = MmioRead32 ((UINT64)Addr);
> +    PCIE_DEBUG_CFG (
> +      "PCIE CFG16 RD: B%X|D%X 0x%p value: 0x%08X\n",
> +      BUS_NUM (Addr),
> +      DEV_NUM (Addr),
> +      Addr,
> +      *Val
> +      );
> +
> +    if (*Val != 0xffff) {
> +      RegC = MmioRead32 ((UINT64)Addr + 0xC);
> +      PCIE_DEBUG_CFG ("  Peek PCIE MfHt RD: 0x%p value: 0x%08X\n", Addr + 0xc, RegC);
> +      MfHt = RegC >> 16;
> +      PCIE_DEBUG_CFG ("  Peek RD8 MfHt=0x%02X\n", MfHt);
> +
> +
> +      if ((MfHt & 0x7F)!= 0) { /* Type 1 header */
> +        Reg18 = MmioRead32 ((UINT64)Addr + 0x18);
> +        Primary = Reg18; Sec = Reg18 >> 8; Sub = Reg18 >> 16;
> +        PCIE_DEBUG_CFG (
> +          "  Bus Peek PCIE Sub:%01X Sec:%01X Primary:%01X  RD: 0x%p value: 0x%08X\n",
> +          Sub,
> +          Sec,
> +          Primary,
> +          Addr + 0x18,
> +          Reg18
> +          );
> +      }
> +      if ((MfHt == 0) || (Primary != 0)) { /* QS RPs Primary Bus is 0b */
> +        *Val = 0xffff;
> +        PCIE_DEBUG_CFG (
> +          "  Skip RD16 B%X|D%X PCIE CFG RD: 0x%p return 0xffff\n",
> +          BUS_NUM (Addr),
> +          DEV_NUM (Addr),
> +          Addr
> +          );
> +        return 0;
> +      }
> +    }
> +  }
> +
> +  Val32 = MmioRead32 (AlignedAddr);
> +  switch ((UINT64)Addr & 0x3) {
> +  case 2:
> +    *Val = Val32 >> 16;
> +    break;
> +
> +  case 0:
> +  default:
> +    *Val = Val32;
> +    break;
> +  }
> +  PCIE_DEBUG_CFG (
> +    "PCIE CFG RD16: 0x%p value: 0x%04X (0x%08llX 0x%08X)\n",
> +    Addr,
> +    *Val,
> +    AlignedAddr,
> +    Val32
> +    );
> +
> +  return 0;
> +}
> +
> +/**
> +   Read 8-bit value from config space address
> +
> +   @param Addr          Address within config space
> +   @param Val           Point to address for read value
> +**/
> +INT32
> +Ac01PcieCfgIn8 (
> +  IN  VOID  *Addr,
> +  OUT UINT8 *Val
> +  )
> +{
> +  UINT64 AlignedAddr = (UINT64)Addr & ~0x3;
> +  if ((((UINT64)Addr & DEV_MASK) >> 15 )> 0 && (((UINT64)Addr & BUS_MASK)  >> 20)> 0) {
> +    *Val = 0xff;
> +    return 0;
> +  }
> +
> +  UINT32 Val32 = MmioRead32 (AlignedAddr);
> +  switch ((UINT64)Addr & 0x3) {
> +  case 3:
> +    *Val = Val32 >> 24;
> +    break;
> +
> +  case 2:
> +    *Val = Val32 >> 16;
> +    break;
> +
> +  case 1:
> +    *Val = Val32 >> 8;
> +    break;
> +
> +  case 0:
> +  default:
> +    *Val = Val32;
> +    break;
> +  }
> +  PCIE_DEBUG_CFG (
> +    "PCIE CFG RD8: 0x%p value: 0x%02X (0x%08llX 0x%08X)\n",
> +    Addr,
> +    *Val,
> +    AlignedAddr,
> +    Val32
> +    );
> +
> +  return 0;
> +}
> +
> +/**
> +   Return the next extended capability address
> +
> +   @param RC              Pointer to AC01_RC structure
> +   @param PcieIndex       PCIe index
> +   @param IsRC            0x1: Checking RC configuration space
> +                          0x0: Checking EP configuration space
> +   @param ExtendedCapId
> +**/
> +UINT64
> +PcieCheckCap (
> +  IN AC01_RC *RC,
> +  IN INTN    PcieIndex,
> +  IN BOOLEAN IsRC,
> +  IN UINT16  ExtendedCapId
> +  )
> +{
> +  VOID   *CfgAddr;
> +  UINT32 Val = 0, NextCap = 0, CapId = 0, ExCap = 0;
> +
> +  if (IsRC) {
> +    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +  } else {
> +    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 20));
> +  }
> +
> +  Ac01PcieCsrIn32 (CfgAddr + TYPE1_CAP_PTR_REG, &Val);
> +  NextCap = Val & 0xFF;
> +
> +  // Loop untill desired capability is found else return 0
> +  while (1) {
> +    if ((NextCap & 0x3) != 0) {
> +      /* Not alignment, just return */
> +      return 0;
> +    }
> +    Ac01PcieCsrIn32 (CfgAddr + NextCap, &Val);
> +    if (NextCap < EXT_CAP_OFFSET_START) {
> +      CapId = Val & 0xFF;
> +    } else {
> +      CapId = Val & 0xFFFF;
> +    }
> +
> +    if (CapId == ExtendedCapId) {
> +      return (UINT64)(CfgAddr + NextCap);
> +    }
> +
> +    if (NextCap < EXT_CAP_OFFSET_START) {
> +      NextCap = (Val & 0xFFFF) >> 8;
> +    } else {
> +      NextCap = (Val & 0xFFFF0000) >> 20;
> +    }
> +
> +    if ((NextCap == 0) && (ExCap == 0)) {
> +      ExCap = 1;
> +      NextCap = EXT_CAP_OFFSET_START;
> +    }
> +
> +    if ((NextCap == 0) && (ExCap == 1)) {
> +      return (UINT64)0;
> +    }
> +  }
> +}
> +
> +/**
> +   Read 8-bit value from config space address
> +
> +   @param RC          Pointer to AC01_RC strucutre
> +   @param RegBase     Base address of CSR, TCU, Hostbridge, Msg, Serdes, and MMCFG register
> +   @param MmioBase    Base address of 32-bit MMIO
> +   @param Mmio32Base  Base address of 64-bit MMIO
> +**/
> +VOID
> +Ac01PcieCoreBuildRCStruct (
> +  AC01_RC *RC,
> +  UINT64  RegBase,
> +  UINT64  MmioBase,
> +  UINT64  Mmio32Base
> +  )
> +{
> +  INTN PcieIndex;
> +
> +  RC->BaseAddr = RegBase;
> +  RC->TcuAddr = RegBase + TCU_OFFSET;
> +  RC->HBAddr = RegBase + HB_CSR_OFFSET;
> +  RC->SerdesAddr = RegBase + SERDES_CSR_OFFSET;
> +  RC->MmcfgAddr = RegBase + MMCONFIG_OFFSET;
> +  RC->MmioAddr = MmioBase;
> +  RC->Mmio32Addr = Mmio32Base;
> +  RC->IoAddr = Mmio32Base + MMIO32_SPACE - IO_SPACE;
> +
> +  RC->Type = (RC->ID < MAX_RCA) ? RCA : RCB;
> +  RC->MaxPcieController = (RC->Type == RCB) ? MAX_PCIE_B : MAX_PCIE_A;
> +
> +  PcieBoardParseRCParams (RC);
> +
> +  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
> +    RC->Pcie[PcieIndex].ID = PcieIndex;
> +    RC->Pcie[PcieIndex].CsrAddr = RC->BaseAddr + PCIE0_CSR_OFFSET + PcieIndex*0x10000;
> +    RC->Pcie[PcieIndex].SnpsRamAddr = RC->Pcie[PcieIndex].CsrAddr + SNPSRAM_OFFSET;
> +    RC->Pcie[PcieIndex].DevNum = PcieIndex + 1;
> +  }
> +
> +  PCIE_DEBUG (
> +    " + S%d - RC%a%d, MMCfgAddr:0x%lx, MmioAddr:0x%lx, Mmio32Addr:0x%lx, Enabled:%a\n",
> +    RC->Socket,
> +    (RC->Type == RCA) ? "A" : "B",
> +    RC->ID,
> +    RC->MmcfgAddr,
> +    RC->MmioAddr,
> +    RC->Mmio32Addr,
> +    (RC->Active) ? "Y" : "N"
> +    );
> +  PCIE_DEBUG (" +   DevMapLo/Hi: 0x%x/0x%x\n", RC->DevMapLo, RC->DevMapHi);
> +  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
> +    PCIE_DEBUG (
> +      " +     PCIE%d:0x%lx - Enabled:%a - DevNum:0x%x\n",
> +      PcieIndex,
> +      RC->Pcie[PcieIndex].CsrAddr,
> +      (RC->Pcie[PcieIndex].Active) ? "Y" : "N",
> +      RC->Pcie[PcieIndex].DevNum
> +      );
> +  }
> +}
> +
> +/**
> +   Configure equalization settings
> +
> +   @param RC              Pointer to AC01_RC structure
> +   @param PcieIndex       PCIe index
> +**/
> +STATIC
> +VOID
> +Ac01PcieConfigureEqualization (
> +  IN AC01_RC *RC,
> +  IN INTN    PcieIndex
> +  )
> +{
> +  VOID   *CfgAddr;
> +  UINT32 Val;
> +
> +  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +
> +  // Select the FoM method, need double-write to convey settings
> +  Ac01PcieCfgIn32 (CfgAddr + GEN3_EQ_CONTROL_OFF, &Val);
> +  Val = GEN3_EQ_FB_MODE (Val, 0x1);
> +  Val = GEN3_EQ_PRESET_VEC (Val, 0x3FF);
> +  Val = GEN3_EQ_INIT_EVAL (Val, 0x1);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_EQ_CONTROL_OFF, Val);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_EQ_CONTROL_OFF, Val);
> +  Ac01PcieCfgIn32 (CfgAddr + GEN3_EQ_CONTROL_OFF, &Val);
> +}
> +
> +/**
> +   Configure presets for GEN3 equalization
> +
> +   @param RC              Pointer to AC01_RC structure
> +   @param PcieIndex       PCIe index
> +**/
> +STATIC
> +VOID
> +Ac01PcieConfigurePresetGen3 (
> +  IN AC01_RC *RC,
> +  IN INTN    PcieIndex
> +  )
> +{
> +  VOID   *CfgAddr, *SpcieBaseAddr;
> +  UINT32 Val, Idx;
> +  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +
> +  // Bring to legacy mode
> +  Ac01PcieCfgIn32 (CfgAddr + GEN3_RELATED_OFF, &Val);
> +  Val = RATE_SHADOW_SEL_SET (Val, 0);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
> +  Val = EQ_PHASE_2_3_SET (Val, 0);
> +  Val = RXEQ_REGRDLESS_SET (Val, 1);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
> +
> +  // Generate SPCIE capability address
> +  SpcieBaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, SPCIE_CAP_ID);
> +  if (SpcieBaseAddr == 0) {
> +    PCIE_ERR (
> +      "PCIE%d.%d: Cannot get SPCIE capability address\n",
> +      RC->ID,
> +      PcieIndex
> +      );
> +    return;
> +  }
> +
> +  for (Idx=0; Idx < RC->Pcie[PcieIndex].MaxWidth/2; Idx++) {
> +    // Program Preset to Gen3 EQ Lane Control
> +    Ac01PcieCfgIn32 (SpcieBaseAddr + CAP_OFF_0C + Idx*4, &Val);
> +    Val = DSP_TX_PRESET0_SET (Val, 0x7);
> +    Val = DSP_TX_PRESET1_SET (Val, 0x7);
> +    Ac01PcieCfgOut32 (SpcieBaseAddr + CAP_OFF_0C + Idx*4, Val);
> +  }
> +}
> +
> +/**
> +   Configure presets for GEN4 equalization
> +
> +   @param RC              Pointer to AC01_RC structure
> +   @param PcieIndex       PCIe index
> +**/
> +STATIC
> +VOID
> +Ac01PcieConfigurePresetGen4 (
> +  IN AC01_RC *RC,
> +  IN INTN    PcieIndex
> +  )
> +{
> +  UINT32 Val;
> +  VOID   *CfgAddr, *SpcieBaseAddr, *Pl16BaseAddr;
> +  UINT32 LinkWidth, i;
> +  UINT8  Preset;
> +
> +  CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +
> +  // Bring to legacy mode
> +  Ac01PcieCfgIn32 (CfgAddr + GEN3_RELATED_OFF, &Val);
> +  Val = RATE_SHADOW_SEL_SET (Val, 1);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
> +  Val = EQ_PHASE_2_3_SET (Val, 0);
> +  Val = RXEQ_REGRDLESS_SET (Val, 1);
> +  Ac01PcieCfgOut32 (CfgAddr + GEN3_RELATED_OFF, Val);
> +
> +  // Generate the PL16 capability address
> +  Pl16BaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, PL16_CAP_ID);
> +  if (Pl16BaseAddr == 0) {
> +    PCIE_ERR (
> +      "PCIE%d.%d: Cannot get PL16 capability address\n",
> +      RC->ID,
> +      PcieIndex
> +      );
> +    return;
> +  }
> +
> +  // Generate the SPCIE capability address
> +  SpcieBaseAddr = (VOID *)PcieCheckCap (RC, PcieIndex, 0x1, SPCIE_CAP_ID);
> +  if (SpcieBaseAddr == 0) {
> +    PCIE_ERR (
> +      "PCIE%d.%d: Cannot get SPICE capability address\n",
> +      RC->ID,
> +      PcieIndex
> +      );
> +    return;
> +  }
> +
> +  // Configure downstream Gen4 Tx preset
> +  if (RC->PresetGen4[PcieIndex] == PRESET_INVALID) {
> +    Preset = 0x57; // Default Gen4 preset
> +  } else {
> +    Preset = RC->PresetGen4[PcieIndex];
> +  }
> +
> +  LinkWidth = RC->Pcie[PcieIndex].MaxWidth;
> +  if (LinkWidth == 0x2) {
> +    Ac01PcieCfgIn32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF, &Val);
> +    Val = DSP_16G_RXTX_PRESET0_SET (Val, Preset);
> +    Val = DSP_16G_RXTX_PRESET1_SET (Val, Preset);
> +    Ac01PcieCfgOut32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF, Val);
> +  } else {
> +    for (i = 0; i < LinkWidth/4; i++) {
> +      Ac01PcieCfgIn32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF + i*4, &Val);
> +      Val = DSP_16G_RXTX_PRESET0_SET (Val, Preset);
> +      Val = DSP_16G_RXTX_PRESET1_SET (Val, Preset);
> +      Val = DSP_16G_RXTX_PRESET2_SET (Val, Preset);
> +      Val = DSP_16G_RXTX_PRESET3_SET (Val, Preset);
> +      Ac01PcieCfgOut32 (Pl16BaseAddr + PL16G_CAP_OFF_20H_REG_OFF + i*4, Val);
> +    }
> +  }
> +
> +  // Configure Gen3 preset
> +  for (i = 0; i < LinkWidth/2; i++) {
> +    Ac01PcieCfgIn32 (SpcieBaseAddr + CAP_OFF_0C + i*4, &Val);
> +    Val = DSP_TX_PRESET0_SET (Val, 0x7);
> +    Val = DSP_TX_PRESET1_SET (Val, 0x7);
> +    Ac01PcieCfgOut32 (SpcieBaseAddr + CAP_OFF_0C + i*4, Val);
> +  }
> +}
> +
> +STATIC BOOLEAN
> +RasdpMitigationCheck (
> +  AC01_RC *RC,
> +  INTN    PcieIndex
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  VOID               *Hob;
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +  if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) {
> +    if (AsciiStrCmp ((CONST CHAR8 *)PlatformHob->CpuVer, "A0") == 0) {
> +      return ((RC->Type == RCB)||(PcieIndex > 0)) ? TRUE : FALSE;
> +    }
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +   Setup and initialize the AC01 PCIe Root Complex and underneath PCIe controllers
> +
> +   @param RC                    Pointer to Root Complex structure
> +   @param ReInit                Re-init status
> +   @param ReInitPcieIndex       PCIe index
> +**/
> +INT32
> +Ac01PcieCoreSetupRC (
> +  IN AC01_RC *RC,
> +  IN UINT8   ReInit,
> +  IN UINT8   ReInitPcieIndex
> +  )
> +{
> +  VOID              *CsrAddr, *CfgAddr, *SnpsRamAddr, *DlinkBaseAddr;
> +  INTN              PcieIndex;
> +  INTN              TimeOut;
> +  UINT32            Val;
> +  PHY_CONTEXT       PhyCtx = { 0 };
> +  PHY_PLAT_RESOURCE PhyPlatResource = { 0 };
> +  INTN              Ret;
> +  UINT16            NextExtendedCapabilityOff;
> +  UINT32            VsecVal;
> +
> +  PCIE_DEBUG ("Initializing Socket%d RC%d\n", RC->Socket, RC->ID);
> +
> +  if (ReInit == 0) {
> +    // Initialize SERDES
> +    ZeroMem (&PhyCtx, sizeof (PhyCtx));
> +    PhyCtx.SdsAddr = RC->SerdesAddr;
> +    PhyCtx.PcieCtrlInfo |= ((RC->Socket & 0x1) << 2);
> +    PhyCtx.PcieCtrlInfo |= ((RC->ID & 0x7) << 4);
> +    PhyCtx.PcieCtrlInfo |= 0xF << 8;
> +    PhyPlatResource.MmioRd = Ac01PcieMmioRd;
> +    PhyPlatResource.MmioWr = Ac01PcieMmioWr;
> +    PhyPlatResource.UsDelay = Ac01PcieDelay;
> +    PhyPlatResource.Puts = Ac01PciePuts;
> +    PhyPlatResource.PutInt = Ac01PciePutInt;
> +    PhyPlatResource.PutHex = Ac01PciePutInt;
> +    PhyPlatResource.PutHex64 = Ac01PciePutHex;
> +    PhyPlatResource.DebugPrint = Ac01PcieDebugPrint;
> +    PhyCtx.PhyPlatResource = &PhyPlatResource;
> +
> +    Ret = SerdesInitClkrst (&PhyCtx);
> +    if (Ret != PHY_INIT_PASS) {
> +      return -1;
> +    }
> +  }
> +
> +  // Setup each controller
> +  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
> +
> +    if (ReInit == 1) {
> +      PcieIndex = ReInitPcieIndex;
> +    }
> +
> +    if (!RC->Pcie[PcieIndex].Active) {
> +      continue;
> +    }
> +
> +    PCIE_DEBUG ("Initializing Controller %d\n", PcieIndex);
> +
> +    CsrAddr = (VOID *)RC->Pcie[PcieIndex].CsrAddr;
> +    SnpsRamAddr = (VOID *)RC->Pcie[PcieIndex].SnpsRamAddr;
> +    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +
> +    // Put Controller into reset if not in reset already
> +    Ac01PcieCsrIn32 (CsrAddr +  RESET, &Val);
> +    if (!(Val & RESET_MASK)) {
> +      Val = DWCPCIE_SET (Val, 1);
> +      Ac01PcieCsrOut32 (CsrAddr + RESET, Val);
> +
> +      // Delay 50ms to ensure controller finish its reset
> +      // FIXME: Is this necessary?
> +      MicroSecondDelay (50000);
> +    }
> +
> +    // Clear memory shutdown
> +    Ac01PcieCsrIn32 (CsrAddr + RAMSDR, &Val);
> +    Val = SD_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CsrAddr + RAMSDR, Val);
> +
> +    // Poll till mem is ready
> +    TimeOut = PCIE_MEMRDY_TIMEOUT;
> +    do {
> +      Ac01PcieCsrIn32 (CsrAddr + MEMRDYR, &Val);
> +      if (Val & 1) {
> +        break;
> +      }
> +
> +      TimeOut--;
> +      MicroSecondDelay (1);
> +    } while (TimeOut > 0);
> +
> +    if (TimeOut <= 0) {
> +      PCIE_ERR ("- Pcie[%d] - Mem not ready\n", PcieIndex);
> +      return -1;
> +    }
> +
> +    // Hold link training
> +    Ac01PcieCsrIn32 (CsrAddr + LINKCTRL, &Val);
> +    Val = LTSSMENB_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CsrAddr + LINKCTRL, Val);
> +
> +    // Enable subsystem clock and release reset
> +    Ac01PcieCsrIn32 (CsrAddr + CLOCK, &Val);
> +    Val = AXIPIPE_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CsrAddr + CLOCK, Val);
> +    Ac01PcieCsrIn32 (CsrAddr +  RESET, &Val);
> +    Val = DWCPCIE_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CsrAddr + RESET, Val);
> +
> +    //
> +    // Controller does not provide any indicator for reset released.
> +    // Must wait at least 1us as per EAS.
> +    //
> +    MicroSecondDelay (1);
> +
> +    // Poll till PIPE clock is stable
> +    TimeOut = PCIE_PIPE_CLOCK_TIMEOUT;
> +    do {
> +      Ac01PcieCsrIn32 (CsrAddr + LINKSTAT, &Val);
> +      if (!(Val & PHY_STATUS_MASK)) {
> +        break;
> +      }
> +
> +      TimeOut--;
> +      MicroSecondDelay (1);
> +    } while (TimeOut > 0);
> +
> +    if (TimeOut <= 0) {
> +      PCIE_ERR ("- Pcie[%d] - PIPE clock is not stable\n", PcieIndex);
> +      return -1;
> +    }
> +
> +    // Start PERST pulse
> +    PcieBoardAssertPerst (RC, PcieIndex, 0, TRUE);
> +
> +    // Allow programming to config space
> +    Ac01PcieCsrIn32 (CfgAddr + MISC_CONTROL_1_OFF, &Val);
> +    Val = DBI_RO_WR_EN_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + MISC_CONTROL_1_OFF, Val);
> +
> +    // In order to detect the NVMe disk for booting without disk,
> +    // need to set Hot-Plug Slot Capable during port initialization.
> +    // It will help PCI Linux driver to initialize its slot iomem resource,
> +    // the one is used for detecting the disk when it is inserted.
> +    Ac01PcieCsrIn32 (CfgAddr + SLOT_CAPABILITIES_REG, &Val);
> +    Val = SLOT_HPC_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + SLOT_CAPABILITIES_REG, Val);
> +
> +
> +    // Apply RASDP error mitigation for all x8, x4, and x2 controllers
> +    // This includes all RCB root ports, and every RCA root port controller
> +    // except for index 0 (i.e. x16 controllers are exempted from this WA)
> +    if (RasdpMitigationCheck (RC, PcieIndex)) {
> +      // Change the Read Margin dual ported RAMs
> +      Val = 0x10; // Margin to 0x0 (most conservative setting)
> +      Ac01PcieCsrOut32 (SnpsRamAddr + TPSRAM_RMR, Val);
> +
> +      // Generate the DLINK capability address
> +      DlinkBaseAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +      NextExtendedCapabilityOff = 0x100; // This is the 1st extended capability offset
> +      do {
> +        Ac01PcieCsrIn32 (DlinkBaseAddr + NextExtendedCapabilityOff, &Val);
> +        if (Val == 0xFFFFFFFF) {
> +          DlinkBaseAddr = 0x0;
> +          break;
> +        }
> +        if ((Val & 0xFFFF) == DLINK_VENDOR_CAP_ID) {
> +          Ac01PcieCsrIn32 (DlinkBaseAddr + NextExtendedCapabilityOff + 0x4, &VsecVal);
> +          if (VsecVal == DLINK_VSEC) {
> +            DlinkBaseAddr = DlinkBaseAddr + NextExtendedCapabilityOff;
> +            break;
> +          }
> +        }
> +        NextExtendedCapabilityOff = (Val >> 20);
> +      } while (NextExtendedCapabilityOff != 0);
> +
> +      // Disable the scaled credit mode
> +      if (DlinkBaseAddr != 0x0) {
> +        Val = 1;
> +        Ac01PcieCsrOut32 (DlinkBaseAddr + DATA_LINK_FEATURE_CAP_OFF, Val);
> +        Ac01PcieCsrIn32 (DlinkBaseAddr + DATA_LINK_FEATURE_CAP_OFF, &Val);
> +        if (Val != 1) {
> +          PCIE_ERR ("- Pcie[%d] - Unable to disable scaled credit\n", PcieIndex);
> +          return -1;
> +        }
> +      } else {
> +        PCIE_ERR ("- Pcie[%d] - Unable to locate data link feature cap offset\n", PcieIndex);
> +        return -1;
> +      }
> +
> +      // Reduce Posted Credits to 1 packet header and data credit for all
> +      // impacted controllers.  Also zero credit scale values for both
> +      // data and packet headers.
> +      Val=0x40201020;
> +      Ac01PcieCsrOut32 (CfgAddr + PORT_LOCIG_VC0_P_RX_Q_CTRL_OFF, Val);
> +    }
> +
> +    // Program DTI for ATS support
> +    Ac01PcieCsrIn32 (CfgAddr + DTIM_CTRL0_OFF, &Val);
> +    Val = DTIM_CTRL0_ROOT_PORT_ID_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CfgAddr + DTIM_CTRL0_OFF, Val);
> +
> +    //
> +    // Program number of lanes used
> +    // - Reprogram LINK_CAPABLE of PORT_LINK_CTRL_OFF
> +    // - Reprogram NUM_OF_LANES of GEN2_CTRL_OFF
> +    // - Reprogram PCIE_CAP_MAX_LINK_WIDTH of LINK_CAPABILITIES_REG
> +    //
> +    Ac01PcieCsrIn32 (CfgAddr + PORT_LINK_CTRL_OFF, &Val);
> +    switch (RC->Pcie[PcieIndex].MaxWidth) {
> +    case LNKW_X2:
> +      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X2);
> +      break;
> +
> +    case LNKW_X4:
> +      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X4);
> +      break;
> +
> +    case LNKW_X8:
> +      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X8);
> +      break;
> +
> +    case LNKW_X16:
> +    default:
> +      Val = LINK_CAPABLE_SET (Val, LINK_CAPABLE_X16);
> +      break;
> +    }
> +    Ac01PcieCsrOut32 (CfgAddr + PORT_LINK_CTRL_OFF, Val);
> +    Ac01PcieCsrIn32 (CfgAddr + GEN2_CTRL_OFF, &Val);
> +    switch (RC->Pcie[PcieIndex].MaxWidth) {
> +    case LNKW_X2:
> +      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X2);
> +      break;
> +
> +    case LNKW_X4:
> +      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X4);
> +      break;
> +
> +    case LNKW_X8:
> +      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X8);
> +      break;
> +
> +    case LNKW_X16:
> +    default:
> +      Val = NUM_OF_LANES_SET (Val, NUM_OF_LANES_X16);
> +      break;
> +    }
> +    Ac01PcieCsrOut32 (CfgAddr + GEN2_CTRL_OFF, Val);
> +    Ac01PcieCsrIn32 (CfgAddr + LINK_CAPABILITIES_REG, &Val);
> +    switch (RC->Pcie[PcieIndex].MaxWidth) {
> +    case LNKW_X2:
> +      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X2);
> +      break;
> +
> +    case LNKW_X4:
> +      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X4);
> +      break;
> +
> +    case LNKW_X8:
> +      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X8);
> +      break;
> +
> +    case LNKW_X16:
> +    default:
> +      Val = PCIE_CAP_MAX_LINK_WIDTH_SET (Val, PCIE_CAP_MAX_LINK_WIDTH_X16);
> +      break;
> +    }
> +
> +    switch (RC->Pcie[PcieIndex].MaxGen) {
> +    case SPEED_GEN1:
> +      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25);
> +      break;
> +
> +    case SPEED_GEN2:
> +      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50);
> +      break;
> +
> +    case SPEED_GEN3:
> +      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80);
> +      break;
> +
> +    default:
> +      Val = PCIE_CAP_MAX_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160);
> +      break;
> +    }
> +    /* Enable ASPM Capability */
> +    Val = PCIE_CAP_ACTIVE_STATE_LINK_PM_SUPPORT_SET (Val, L0S_L1_SUPPORTED);
> +    Ac01PcieCsrOut32 (CfgAddr + LINK_CAPABILITIES_REG, Val);
> +
> +    Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL2_LINK_STATUS2_REG, &Val);
> +    switch (RC->Pcie[PcieIndex].MaxGen) {
> +    case SPEED_GEN1:
> +      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_25);
> +      break;
> +
> +    case SPEED_GEN2:
> +      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_50);
> +      break;
> +
> +    case SPEED_GEN3:
> +      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_80);
> +      break;
> +
> +    default:
> +      Val = PCIE_CAP_TARGET_LINK_SPEED_SET (Val, MAX_LINK_SPEED_160);
> +      break;
> +    }
> +    Ac01PcieCsrOut32 (CfgAddr + LINK_CONTROL2_LINK_STATUS2_REG, Val);
> +
> +    // Set Zero byte request handling
> +    Ac01PcieCsrIn32 (CfgAddr + FILTER_MASK_2_OFF, &Val);
> +    Val = CX_FLT_MASK_VENMSG0_DROP_SET (Val, 0);
> +    Val = CX_FLT_MASK_VENMSG1_DROP_SET (Val, 0);
> +    Val = CX_FLT_MASK_DABORT_4UCPL_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CfgAddr + FILTER_MASK_2_OFF, Val);
> +    Ac01PcieCsrIn32 (CfgAddr + AMBA_ORDERING_CTRL_OFF, &Val);
> +    Val = AX_MSTR_ZEROLREAD_FW_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CfgAddr + AMBA_ORDERING_CTRL_OFF, Val);
> +
> +    //
> +    // Set Completion with CRS handling for CFG Request
> +    // Set Completion with CA/UR handling non-CFG Request
> +    //
> +    Ac01PcieCsrIn32 (CfgAddr + AMBA_ERROR_RESPONSE_DEFAULT_OFF, &Val);
> +    Val = AMBA_ERROR_RESPONSE_CRS_SET (Val, 0x2);
> +    Ac01PcieCsrOut32 (CfgAddr + AMBA_ERROR_RESPONSE_DEFAULT_OFF, Val);
> +
> +    // Set Legacy PCIE interrupt map to INTA
> +    Ac01PcieCsrIn32 (CfgAddr + BRIDGE_CTRL_INT_PIN_INT_LINE_REG, &Val);
> +    Val = INT_PIN_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + BRIDGE_CTRL_INT_PIN_INT_LINE_REG, Val);
> +    Ac01PcieCsrIn32 (CsrAddr + IRQSEL, &Val);
> +    Val = INTPIN_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CsrAddr + IRQSEL, Val);
> +
> +    if (RC->Pcie[PcieIndex].MaxGen != SPEED_GEN1) {
> +      Ac01PcieConfigureEqualization (RC, PcieIndex);
> +      if (RC->Pcie[PcieIndex].MaxGen == SPEED_GEN3) {
> +        Ac01PcieConfigurePresetGen3 (RC, PcieIndex);
> +      } else if (RC->Pcie[PcieIndex].MaxGen == SPEED_GEN4) {
> +        Ac01PcieConfigurePresetGen4 (RC, PcieIndex);
> +      }
> +    }
> +
> +    // Mask Completion Timeout
> +    Ac01PcieCsrIn32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, &Val);
> +    Val = LINK_TIMEOUT_PERIOD_DEFAULT_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, Val);
> +    Ac01PcieCsrIn32 (CfgAddr + UNCORR_ERR_MASK_OFF, &Val);
> +    Val = CMPLT_TIMEOUT_ERR_MASK_SET (Val, 1);
> +    // AER surprise link down error should be masked due to hotplug is enabled
> +    // This event must be handled by Hotplug handler, instead of error handler
> +    Val = SDES_ERR_MASK_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + UNCORR_ERR_MASK_OFF, Val);
> +
> +    // Program Class Code
> +    Ac01PcieCsrIn32 (CfgAddr + TYPE1_CLASS_CODE_REV_ID_REG, &Val);
> +    Val = REVISION_ID_SET (Val, 4);
> +    Val = SUBCLASS_CODE_SET (Val, 4);
> +    Val = BASE_CLASS_CODE_SET (Val, 6);
> +    Ac01PcieCsrOut32 (CfgAddr + TYPE1_CLASS_CODE_REV_ID_REG, Val);
> +
> +    // Program VendorID and DeviceID
> +    Ac01PcieCsrIn32 (CfgAddr + TYPE1_DEV_ID_VEND_ID_REG, &Val);
> +    Val = VENDOR_ID_SET (Val, AMPERE_PCIE_VENDORID);
> +    if (RCA == RC->Type) {
> +      Val = DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICEID_RCA + PcieIndex);
> +    } else {
> +      Val = DEVICE_ID_SET (Val, AC01_PCIE_BRIDGE_DEVICEID_RCB + PcieIndex);
> +    }
> +    Ac01PcieCsrOut32 (CfgAddr + TYPE1_DEV_ID_VEND_ID_REG, Val);
> +
> +    // Enable common clock for downstream
> +    Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, &Val);
> +    Val = PCIE_CAP_SLOT_CLK_CONFIG_SET (Val, 1);
> +    Val = PCIE_CAP_COMMON_CLK_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, Val);
> +
> +    // Assert PERST low to reset endpoint
> +    PcieBoardAssertPerst (RC, PcieIndex, 0, FALSE);
> +
> +    // Start link training
> +    Ac01PcieCsrIn32 (CsrAddr + LINKCTRL, &Val);
> +    Val = LTSSMENB_SET (Val, 1);
> +    Ac01PcieCsrOut32 (CsrAddr + LINKCTRL, Val);
> +
> +    // Complete the PERST pulse
> +    PcieBoardAssertPerst (RC, PcieIndex, 0, TRUE);
> +
> +    // Match aux_clk to system
> +    Ac01PcieCsrIn32 (CfgAddr + AUX_CLK_FREQ_OFF, &Val);
> +    Val = AUX_CLK_FREQ_SET (Val, AUX_CLK_500MHZ);
> +    Ac01PcieCsrOut32 (CfgAddr + AUX_CLK_FREQ_OFF, Val);
> +
> +    // Lock programming of config space
> +    Ac01PcieCsrIn32 (CfgAddr + MISC_CONTROL_1_OFF, &Val);
> +    Val = DBI_RO_WR_EN_SET (Val, 0);
> +    Ac01PcieCsrOut32 (CfgAddr + MISC_CONTROL_1_OFF, Val);
> +
> +    if (ReInit == 1) {
> +      break;
> +    }
> +  }
> +
> +  // Program VendorID and DeviceId
> +  if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr  + HBPDVIDR, &Val))) {
> +    Val = PCIVENDID_SET (Val, AMPERE_PCIE_VENDORID);
> +    if (RCA == RC->Type) {
> +      Val = PCIDEVID_SET (Val, AC01_HOST_BRIDGE_DEVICEID_RCA);
> +    } else {
> +      Val = PCIDEVID_SET (Val, AC01_HOST_BRIDGE_DEVICEID_RCB);
> +    }
> +    MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr  + HBPDVIDR, Val);
> +  }
> +
> +  return 0;
> +}
> +
> +STATIC BOOLEAN
> +PcieLinkUpCheck (
> +  IN  AC01_PCIE *Pcie,
> +  OUT UINT32    *LtssmState
> +  )
> +{
> +  VOID   *CsrAddr;
> +  UINT32 BlockEvent, LinkStat;
> +
> +  CsrAddr = (VOID *)Pcie->CsrAddr;
> +
> +  // Check if card present
> +  // smlh_ltssm_state[13:8] = 0
> +  // phy_status[2] = 0
> +  // smlh_link_up[1] = 0
> +  // rdlh_link_up[0] = 0
> +  Ac01PcieCsrIn32 (CsrAddr + LINKSTAT, &LinkStat);
> +  LinkStat = LinkStat & (SMLH_LTSSM_STATE_MASK | PHY_STATUS_MASK_BIT |
> +                         SMLH_LINK_UP_MASK_BIT | RDLH_LINK_UP_MASK_BIT);
> +  if (LinkStat == 0x0000) {
> +    return 0;
> +  }
> +
> +  Ac01PcieCsrIn32 (CsrAddr +  BLOCKEVENTSTAT, &BlockEvent);
> +  Ac01PcieCsrIn32 (CsrAddr +  LINKSTAT, &LinkStat);
> +
> +  if ((BlockEvent & LINKUP_MASK) != 0) {
> +    *LtssmState = SMLH_LTSSM_STATE_GET (LinkStat);
> +    PCIE_DEBUG ("%a *LtssmState=%lx Linkup\n", __func__, *LtssmState);
> +    return 1;
> +  }
> +
> +  return 0;
> +}
> +
> +VOID
> +Ac01PcieCoreUpdateLink (
> +  IN  AC01_RC *RC,
> +  OUT BOOLEAN *IsNextRoundNeeded,
> +  OUT INT8    *FailedPciePtr,
> +  OUT INT8    *FailedPcieCount
> +  )
> +{
> +  INTN      PcieIndex;
> +  AC01_PCIE *Pcie;
> +  UINT32    Ltssm, i;
> +  UINT32    Val;
> +  VOID      *CfgAddr;
> +
> +  *IsNextRoundNeeded = FALSE;
> +  *FailedPcieCount   = 0;
> +  for (i = 0; i < MAX_PCIE_B; i++) {
> +    FailedPciePtr[i] = -1;
> +  }
> +
> +  if (!RC->Active) {
> +    return;
> +  }
> +
> +  // Loop for all controllers
> +  for (PcieIndex = 0; PcieIndex < RC->MaxPcieController; PcieIndex++) {
> +    Pcie = &RC->Pcie[PcieIndex];
> +    CfgAddr = (VOID *)(RC->MmcfgAddr + (RC->Pcie[PcieIndex].DevNum << 15));
> +
> +    if (Pcie->Active && !Pcie->LinkUp) {
> +      if (PcieLinkUpCheck (Pcie, &Ltssm)) {
> +        Pcie->LinkUp = 1;
> +        Ac01PcieCsrIn32 (CfgAddr + LINK_CONTROL_LINK_STATUS_REG, &Val);
> +        PCIE_DEBUG (
> +          "%a S%d RC%d RP%d NEGO_LINK_WIDTH: 0x%x LINK_SPEED: 0x%x\n",
> +          __FUNCTION__,
> +          RC->Socket,
> +          RC->ID,
> +          PcieIndex,
> +          PCIE_CAP_NEGO_LINK_WIDTH_GET (Val),
> +          PCIE_CAP_LINK_SPEED_GET (Val)
> +          );
> +
> +        // Un-mask Completion Timeout
> +        Ac01PcieCsrIn32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, &Val);
> +        Val = LINK_TIMEOUT_PERIOD_DEFAULT_SET (Val, 32);
> +        Ac01PcieCsrOut32 (CfgAddr + AMBA_LINK_TIMEOUT_OFF, Val);
> +        Ac01PcieCsrIn32 (CfgAddr + UNCORR_ERR_MASK_OFF, &Val);
> +        Val = CMPLT_TIMEOUT_ERR_MASK_SET (Val, 0);
> +        Ac01PcieCsrOut32 (CfgAddr + UNCORR_ERR_MASK_OFF, Val);
> +      } else {
> +        *IsNextRoundNeeded = TRUE;
> +        FailedPciePtr[*FailedPcieCount] = PcieIndex;
> +        *FailedPcieCount += 1;
> +      }
> +    }
> +  }
> +}
> +
> +VOID
> +Ac01PcieCoreEndEnumeration (
> +  AC01_RC *RC
> +  )
> +{
> +  //
> +  // Reserved for hook from stack ending of enumeration phase processing.
> +  // Emptry for now.
> +  //
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
> new file mode 100644
> index 000000000000..5beb59689254
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.c
> @@ -0,0 +1,536 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmGenericTimerCounterLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcieBoardLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +
> +#include "PcieCore.h"
> +#include "PciePatchAcpi.h"
> +
> +STATIC UINT64  RCRegBase[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_REGISTER_BASE };
> +STATIC UINT64  RCMmioBase[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO_BASE };
> +STATIC UINT64  RCMmio32Base[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE };
> +STATIC UINT64  RCMmio32Base1P[MAX_AC01_PCIE_ROOT_COMPLEX] = { AC01_PCIE_MMIO32_BASE_1P };
> +STATIC AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX];
> +STATIC INT8    PciList[MAX_AC01_PCIE_ROOT_COMPLEX];
> +
> +STATIC
> +VOID
> +SerialPrint (
> +  IN CONST CHAR8 *FormatString,
> +  ...
> +  )
> +{
> +  UINT8   Buf[64];
> +  VA_LIST Marker;
> +  UINTN   NumberOfPrinted;
> +
> +  VA_START (Marker, FormatString);
> +  NumberOfPrinted = AsciiVSPrint ((CHAR8 *)Buf, sizeof (Buf), FormatString, Marker);
> +  SerialPortWrite (Buf, NumberOfPrinted);
> +  VA_END (Marker);
> +}
> +
> +AC01_RC *
> +GetRCList (
> +  UINT8 Idx
> +  )
> +{
> +  return &RCList[Idx];
> +}
> +
> +/**
> +   Map BusDxe Host bridge and Root bridge Indexes to PCIE core BSP driver Root Complex Index.
> +
> +   @param  HBIndex               Index to identify of PCIE Host bridge.
> +   @param  RBIndex               Index to identify of PCIE Root bridge.
> +   @retval UINT8                 Index to identify Root Complex instance from global RCList.
> +**/
> +STATIC
> +UINT8
> +GetRCIndex (
> +  IN UINT8 HBIndex,
> +  IN UINT8 RBIndex
> +  )
> +{
> +  //
> +  // BusDxe addresses resources based on Host bridge and Root bridge.
> +  // Map those to Root Complex index/instance known for Pcie Core BSP driver
> +  //
> +  return HBIndex * MAX_AC01_PCIE_ROOT_BRIDGE + RBIndex;
> +}
> +
> +/**
> +  Prepare to start PCIE core BSP driver.
> +
> +  @param ImageHandle[in]        Handle for the image.
> +  @param SystemTable[in]        Address of the system table.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieSetup (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  AC01_RC *RC;
> +  INTN    RCIndex;
> +
> +  ZeroMem (&RCList, sizeof (AC01_RC) * MAX_AC01_PCIE_ROOT_COMPLEX);
> +
> +  // Adjust MMIO32 base address 1P vs 2P
> +  if (!IsSlaveSocketPresent ()) {
> +    CopyMem ((VOID *)&RCMmio32Base, (VOID *)&RCMmio32Base1P, sizeof (UINT64) * MAX_AC01_PCIE_ROOT_COMPLEX);
> +  }
> +
> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +    RC = &RCList[RCIndex];
> +    RC->Socket = RCIndex / RCS_PER_SOCKET;
> +    RC->ID = RCIndex % RCS_PER_SOCKET;
> +
> +    Ac01PcieCoreBuildRCStruct (RC, RCRegBase[RCIndex], RCMmioBase[RCIndex], RCMmio32Base[RCIndex]);
> +  }
> +
> +  // Build the UEFI menu
> +  PcieBoardScreenInitialize (ImageHandle, SystemTable, RCList);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Get Total HostBridge
> +
> +  @retval UINTN                 Return Total HostBridge.
> +**/
> +UINT8
> +Ac01PcieGetTotalHBs (
> +  VOID
> +  )
> +{
> +  return MAX_AC01_PCIE_ROOT_COMPLEX;
> +}
> +
> +/**
> +  Get Total RootBridge per HostBridge.
> +
> +  @param  RCIndex[in]           Index to identify of Root Complex.
> +
> +  @retval UINTN                 Return Total RootBridge per HostBridge.
> +**/
> +UINT8
> +Ac01PcieGetTotalRBsPerHB (
> +  IN UINTN RCIndex
> +  )
> +{
> +  return MAX_AC01_PCIE_ROOT_BRIDGE;
> +}
> +
> +/**
> +  Get RootBridge Attribute.
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval UINTN                 Return RootBridge Attribute.
> +**/
> +UINTN
> +Ac01PcieGetRootBridgeAttribute (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  )
> +{
> +  return EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
> +}
> +
> +/**
> +  Get RootBridge Segment number.
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval UINTN                 Return RootBridge Segment number.
> +**/
> +UINTN
> +Ac01PcieGetRootBridgeSegmentNumber (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  )
> +{
> +  UINTN   RCIndex;
> +  AC01_RC *RC;
> +  UINTN   SegmentNumber;
> +
> +  RCIndex = GetRCIndex (HBIndex, RBIndex);
> +  RC = &RCList[RCIndex];
> +  SegmentNumber = RCIndex;
> +
> +  // Get board specific overrides
> +  PcieBoardGetRCSegmentNumber (RC, &SegmentNumber);
> +  RC->Logical = SegmentNumber;
> +
> +  return SegmentNumber;
> +}
> +
> +STATIC
> +VOID
> +SortPciList (
> +  INT8 *PciList
> +  )
> +{
> +  INT8 Idx1, Idx2;
> +
> +  for (Idx2 = 0, Idx1 = 0; Idx2 < MAX_AC01_PCIE_ROOT_COMPLEX; Idx2++) {
> +    if (PciList[Idx2] < 0) {
> +      continue;
> +    }
> +    PciList[Idx1] = PciList[Idx2];
> +    if (Idx1 != Idx2) {
> +      PciList[Idx2] = -1;
> +    }
> +    Idx1++;
> +  }
> +
> +  for (Idx2 = 0; Idx2 < Idx1; Idx2++) {
> +    PCIE_DEBUG (
> +      " %a: PciList[%d]=%d TcuAddr=0x%llx\n",
> +      __FUNCTION__,
> +      Idx2,
> +      PciList[Idx2],
> +      RCList[PciList[Idx2]].TcuAddr
> +      );
> +  }
> +}
> +
> +/**
> +  Get RootBridge disable status
> +
> +  @param  HBIndex[In]           Index to identify of PCIE Host bridge.
> +  @param  RBIndex[In]           Index to identify of underneath PCIE Root bridge.
> +
> +  @retval BOOLEAN               Return RootBridge disable status.
> +**/
> +BOOLEAN
> +Ac01PcieCheckRootBridgeDisabled (
> +  IN UINTN HBIndex,
> +  IN UINTN RBIndex
> +  )
> +{
> +  UINTN RCIndex;
> +  INT8  Ret;
> +
> +  RCIndex = HBIndex;
> +  Ret = !RCList[RCIndex].Active;
> +  if (Ret) {
> +    PciList[HBIndex] = -1;
> +  } else {
> +    PciList[HBIndex] = HBIndex;
> +  }
> +  if (HBIndex == (MAX_AC01_PCIE_ROOT_COMPLEX -1)) {
> +    SortPciList (PciList);
> +    if (!IsSlaveSocketPresent ()) {
> +      AcpiPatchPciMem32 (PciList);
> +    }
> +    AcpiInstallMcfg (PciList);
> +    AcpiInstallIort (PciList);
> +  }
> +  return Ret;
> +}
> +
> +/**
> +  Initialize Host bridge.
> +
> +  @param  HBIndex[in]           Index to identify of PCIE Host bridge.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieSetupHostBridge (
> +  IN UINTN HBIndex
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Initialize Root bridge.
> +
> +  @param  HBIndex[in]            Index to identify of PCIE Host bridge.
> +  @param  RBIndex[in]            Index to identify of underneath PCIE Root bridge.
> +  @param  RootBridgeInstance[in] The pointer of instance of the Root bridge IO.
> +
> +  @retval EFI_SUCCESS           Initialize successfully.
> +  @retval EFI_DEVICE_ERROR      Error when initializing.
> +**/
> +EFI_STATUS
> +Ac01PcieSetupRootBridge (
> +  IN UINTN           HBIndex,
> +  IN UINTN           RBIndex,
> +  IN PCI_ROOT_BRIDGE *RootBridge
> +  )
> +{
> +  UINTN   RCIndex;
> +  AC01_RC *RC;
> +  UINT32  Result;
> +
> +  RCIndex = GetRCIndex (HBIndex, RBIndex);
> +  RC = &RCList[RCIndex];
> +  if (!RC->Active) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  RC->RootBridge = (VOID *)RootBridge;
> +
> +  // Initialize Root Complex and underneath controllers
> +  Result = Ac01PcieCoreSetupRC (RC, 0, 0);
> +  if (Result) {
> +    PCIE_ERR ("RootComplex[%d]: Init Failed\n", RCIndex);
> +
> +    goto Error;
> +  }
> +
> +  // Populate resource aperture
> +  RootBridge->Bus.Base = 0x0;
> +  RootBridge->Bus.Limit = 0xFF;
> +  RootBridge->Io.Base = RC->IoAddr;
> +  RootBridge->Io.Limit = RC->IoAddr + IO_SPACE - 1;
> +  RootBridge->Mem.Base = RC->Mmio32Addr;
> +  RootBridge->Mem.Limit = RootBridge->Mem.Base + MMIO32_SPACE - 1;
> +  RootBridge->PMem.Base = RootBridge->Mem.Base;
> +  RootBridge->PMem.Limit = RootBridge->Mem.Limit;
> +  RootBridge->MemAbove4G.Base = 0x0;
> +  RootBridge->MemAbove4G.Limit = 0x0;
> +  RootBridge->PMemAbove4G.Base = RC->MmioAddr;
> +  RootBridge->PMemAbove4G.Limit = RootBridge->PMemAbove4G.Base + MMIO_SPACE - 1;
> +
> +  PCIE_DEBUG (" +    Bus: 0x%x - 0x%lx\n", RootBridge->Bus.Base, RootBridge->Bus.Limit);
> +  PCIE_DEBUG (" +     Io: 0x%x - 0x%lx\n", RootBridge->Io.Base, RootBridge->Io.Limit);
> +  PCIE_DEBUG (" +    Mem: 0x%x - 0x%lx\n", RootBridge->Mem.Base, RootBridge->Mem.Limit);
> +  PCIE_DEBUG (" +   PMem: 0x%x - 0x%lx\n", RootBridge->PMem.Base, RootBridge->PMem.Limit);
> +  PCIE_DEBUG (" +  4GMem: 0x%x - 0x%lx\n", RootBridge->MemAbove4G.Base, RootBridge->MemAbove4G.Limit);
> +  PCIE_DEBUG (" + 4GPMem: 0x%x - 0x%lx\n", RootBridge->PMemAbove4G.Base, RootBridge->PMemAbove4G.Limit);
> +
> +  return EFI_SUCCESS;
> +
> +Error:
> +  RC->Active = FALSE;
> +  return EFI_DEVICE_ERROR;
> +}
> +
> +/**
> +  Reads/Writes an PCI configuration register.
> +
> +  @param  RootInstance[in]      Pointer to RootInstance structure.
> +  @param  Address[in]           Address which want to read or write to.
> +  @param  Write[in]             Indicate that this is a read or write command.
> +  @param  Width[in]             Specify the width of the data.
> +  @param  Data[in, out]         The buffer to hold the data.
> +
> +  @retval EFI_SUCCESS           Read/Write successfully.
> +**/
> +EFI_STATUS
> +Ac01PcieConfigRW (
> +  IN     VOID    *RootInstance,
> +  IN     UINT64  Address,
> +  IN     BOOLEAN Write,
> +  IN     UINTN   Width,
> +  IN OUT VOID    *Data
> +  )
> +{
> +  AC01_RC *RC = NULL;
> +  VOID    *CfgBase = NULL;
> +  UINTN   RCIndex;
> +  UINT32  Reg;
> +
> +  ASSERT (Address <= 0x0FFFFFFF);
> +
> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +    RC = &RCList[RCIndex];
> +    if (RC->RootBridge == RootInstance) {
> +      break;
> +    }
> +  }
> +
> +  if ((RCIndex == MAX_AC01_PCIE_ROOT_COMPLEX) || (RC == NULL)) {
> +    PCIE_ERR ("Can't find Root Bridge instance:%p\n", RootInstance);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Reg = Address & 0xFFF;
> +
> +  CfgBase = (VOID *)((UINT64)RC->MmcfgAddr + (Address & 0x0FFFF000));
> +  if (Write) {
> +    switch (Width) {
> +    case 1:
> +      Ac01PcieCfgOut8 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT8 *)Data));
> +      break;
> +
> +    case 2:
> +      Ac01PcieCfgOut16 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT16 *)Data));
> +      break;
> +
> +    case 4:
> +      Ac01PcieCfgOut32 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), *((UINT32 *)Data));
> +      break;
> +
> +    default:
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else {
> +    switch (Width) {
> +    case 1:
> +      Ac01PcieCfgIn8 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT8 *)Data);
> +      break;
> +
> +    case 2:
> +      Ac01PcieCfgIn16 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT16 *)Data);
> +      if (Reg == 0xAE && (*((UINT16 *)Data)) == 0xFFFF) {
> +        SerialPrint ("PANIC due to PCIE RC:%d link issue\n", RC->ID);
> +        // Loop forever waiting for failsafe/watch dog time out
> +        do {
> +        } while (1);
> +      }
> +      break;
> +
> +    case 4:
> +      Ac01PcieCfgIn32 ((VOID *)(CfgBase + (Reg & (~(Width - 1)))), (UINT32 *)Data);
> +      break;
> +
> +    default:
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +Ac01PcieCorePollLinkUp (
> +  VOID
> +  )
> +{
> +  INTN    RCIndex, PcieIndex, i;
> +  BOOLEAN IsNextRoundNeeded = FALSE, NextRoundNeeded;
> +  UINT64  PrevTick, CurrTick, ElapsedCycle;
> +  UINT64  TimerTicks64;
> +  UINT8   ReInit;
> +  INT8    FailedPciePtr[MAX_PCIE_B];
> +  INT8    FailedPcieCount;
> +
> +  ReInit = 0;
> +
> +_link_polling:
> +  NextRoundNeeded = 0;
> +  //
> +  // It is not guaranteed the timer service is ready prior to PCI Dxe.
> +  // Calculate system ticks for link training.
> +  //
> +  TimerTicks64 = ArmGenericTimerGetTimerFreq (); /* 1 Second */
> +  PrevTick = ArmGenericTimerGetSystemCount ();
> +  ElapsedCycle = 0;
> +
> +  do {
> +    // Update timer
> +    CurrTick = ArmGenericTimerGetSystemCount ();
> +    if (CurrTick < PrevTick) {
> +      ElapsedCycle += (UINT64)(~0x0ULL) - PrevTick;
> +      PrevTick = 0;
> +    }
> +    ElapsedCycle += (CurrTick - PrevTick);
> +    PrevTick = CurrTick;
> +  } while (ElapsedCycle < TimerTicks64);
> +
> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +    Ac01PcieCoreUpdateLink (&RCList[RCIndex], &IsNextRoundNeeded, FailedPciePtr, &FailedPcieCount);
> +    if (IsNextRoundNeeded) {
> +      NextRoundNeeded = 1;
> +    }
> +  }
> +
> +  if (NextRoundNeeded && ReInit < MAX_REINIT) {
> +    // Timer is up. Give another chance to re-program controller
> +    ReInit++;
> +    for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +      Ac01PcieCoreUpdateLink (&RCList[RCIndex], &IsNextRoundNeeded, FailedPciePtr, &FailedPcieCount);
> +      if (IsNextRoundNeeded) {
> +        for (i = 0; i < FailedPcieCount; i++) {
> +          PcieIndex = FailedPciePtr[i];
> +          if (PcieIndex == -1) {
> +            continue;
> +          }
> +
> +          // Some controller still observes link-down. Re-init controller
> +          Ac01PcieCoreSetupRC (&RCList[RCIndex], 1, PcieIndex);
> +        }
> +      }
> +    }
> +
> +    goto _link_polling;
> +  }
> +}
> +
> +/**
> +  Prepare to end PCIE core BSP driver
> +**/
> +VOID
> +Ac01PcieEnd (
> +  VOID
> +  )
> +{
> +  Ac01PcieCorePollLinkUp ();
> +}
> +
> +/**
> +  Callback funciton for EndEnumeration notification from PCI stack.
> +
> +  @param  HBIndex               Index to identify of PCIE Host bridge.
> +  @param  RBIndex               Index to identify of underneath PCIE Root bridge.
> +  @param  Phase                 The phase of enumeration as informed from PCI stack.
> +**/
> +VOID
> +Ac01PcieHostBridgeNotifyPhase (
> +  IN UINTN                                         HBIndex,
> +  IN UINTN                                         RBIndex,
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
> +  )
> +{
> +  AC01_RC *RC;
> +  UINTN   RCIndex;
> +
> +  RCIndex = GetRCIndex (HBIndex, RBIndex);
> +  RC = &RCList[RCIndex];
> +
> +  switch (Phase) {
> +  case EfiPciHostBridgeEndEnumeration:
> +    Ac01PcieCoreEndEnumeration (RC);
> +    break;
> +
> +  case EfiPciHostBridgeBeginEnumeration:
> +  case EfiPciHostBridgeBeginBusAllocation:
> +  case EfiPciHostBridgeEndBusAllocation:
> +  case EfiPciHostBridgeBeginResourceAllocation:
> +  case EfiPciHostBridgeAllocateResources:
> +  case EfiPciHostBridgeSetResources:
> +  case EfiPciHostBridgeFreeResources:
> +  case EfiPciHostBridgeEndResourceAllocation:
> +  case EfiMaxPciHostBridgeEnumerationPhase:
> +    break;
> +  }
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
> new file mode 100644
> index 000000000000..dae7ee4fced1
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PciePatchAcpi.c
> @@ -0,0 +1,610 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <AcpiHeader.h>
> +#include <IndustryStandard/Acpi30.h>
> +#include <IndustryStandard/IoRemappingTable.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PcieBoardLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Platform/Ac01.h>
> +#include <Protocol/AcpiTable.h>
> +
> +#include "Pcie.h"
> +#include "PcieCore.h"
> +
> +#define ACPI_RESOURCE_NAME_ADDRESS16            0x88
> +#define ACPI_RESOURCE_NAME_ADDRESS64            0x8A
> +
> +#define RCA_NUM_TBU_PMU         6
> +#define RCB_NUM_TBU_PMU         10
> +
> +STATIC UINT32 gTbuPmuIrqArray[] = { SMMU_TBU_PMU_IRQ_START_ARRAY };
> +STATIC UINT32 gTcuPmuIrqArray[] = { SMMU_TCU_PMU_IRQ_START_ARRAY };
> +
> +#pragma pack(1)
> +typedef struct
> +{
> +  UINT64 ullBaseAddress;
> +  UINT16 usSegGroupNum;
> +  UINT8  ucStartBusNum;
> +  UINT8  ucEndBusNum;
> +  UINT32 Reserved2;
> +} EFI_MCFG_CONFIG_STRUCTURE;
> +
> +typedef struct
> +{
> +  EFI_ACPI_DESCRIPTION_HEADER Header;
> +  UINT64                      Reserved1;
> +} EFI_MCFG_TABLE_CONFIG;
> +
> +typedef struct {
> +  UINT64 AddressGranularity;
> +  UINT64 AddressMin;
> +  UINT64 AddressMax;
> +  UINT64 AddressTranslation;
> +  UINT64 RangeLength;
> +} QWordMemory;
> +
> +typedef struct ResourceEntry {
> +  UINT8  ResourceType;
> +  UINT16 ResourceSize;
> +  UINT8  Attribute;
> +  UINT8  Byte0;
> +  UINT8  Byte1;
> +  VOID   *ResourcePtr;
> +} RESOURCE;
> +
> +STATIC QWordMemory Qmem[] = {
> +  { AC01_PCIE_RCA2_QMEM },
> +  { AC01_PCIE_RCA3_QMEM },
> +  { AC01_PCIE_RCB0_QMEM },
> +  { AC01_PCIE_RCB1_QMEM },
> +  { AC01_PCIE_RCB2_QMEM },
> +  { AC01_PCIE_RCB3_QMEM }
> +};
> +
> +typedef struct {
> +  EFI_ACPI_6_0_IO_REMAPPING_NODE Node;
> +  UINT64                         Base;
> +  UINT32                         Flags;
> +  UINT32                         Reserved;
> +  UINT64                         VatosAddress;
> +  UINT32                         Model;
> +  UINT32                         Event;
> +  UINT32                         Pri;
> +  UINT32                         Gerr;
> +  UINT32                         Sync;
> +  UINT32                         ProximityDomain;
> +  UINT32                         DeviceIdMapping;
> +} EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE;
> +
> +typedef struct {
> +  EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE Node;
> +  UINT32                             ItsIdentifier;
> +} AC01_ITS_NODE;
> +
> +
> +typedef struct {
> +  EFI_ACPI_6_0_IO_REMAPPING_RC_NODE  Node;
> +  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE RcIdMapping;
> +} AC01_RC_NODE;
> +
> +typedef struct {
> +  EFI_ACPI_6_2_IO_REMAPPING_SMMU3_NODE Node;
> +  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE   InterruptMsiMapping;
> +  EFI_ACPI_6_0_IO_REMAPPING_ID_TABLE   InterruptMsiMappingSingle;
> +} AC01_SMMU_NODE;
> +
> +typedef struct {
> +  EFI_ACPI_6_0_IO_REMAPPING_TABLE Iort;
> +  AC01_ITS_NODE                   ItsNode[2];
> +  AC01_RC_NODE                    RcNode[2];
> +  AC01_SMMU_NODE                  SmmuNode[2];
> +} AC01_IO_REMAPPING_STRUCTURE;
> +
> +#define FIELD_OFFSET(type, name)            __builtin_offsetof (type, name)
> +#define __AC01_ID_MAPPING(In, Num, Out, Ref, Flags)    \
> +  {                                                    \
> +    In,                                                \
> +    Num,                                               \
> +    Out,                                               \
> +    FIELD_OFFSET (AC01_IO_REMAPPING_STRUCTURE, Ref),   \
> +    Flags                                              \
> +  }
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiPatchPciMem32 (
> +  INT8 *PciSegEnabled
> +  )
> +{
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
> +  EFI_STATUS            Status;
> +  UINTN                 Idx, Ix;
> +  EFI_ACPI_HANDLE       TableHandle, SegHandle;
> +  CHAR8                 Buffer[MAX_ACPI_NODE_PATH];
> +  CHAR8                 *KB, *B;
> +  EFI_ACPI_DATA_TYPE    DataType;
> +  UINTN                 DataSize, Mem32;
> +  RESOURCE              *Rs;
> +  QWordMemory           *Qm;
> +  UINT8                 Segment;
> +
> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("Unable to locate ACPI table protocol Guid\n");
> +    return Status;
> +  }
> +
> +  /* Open DSDT Table */
> +  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("Unable to open DSDT table\n");
> +    return Status;
> +  }
> +
> +  for (Idx = 0; PciSegEnabled[Idx] != -1; Idx++) {
> +    if (PciSegEnabled[Idx] > SOCKET0_LAST_RC) { /* Physical segment */
> +      break;
> +    }
> +    if (PciSegEnabled[Idx] < SOCKET0_FIRST_RC) {
> +      continue;
> +    }
> +
> +    /* DSDT PCI devices to use Physical segment */
> +    AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.PCI%x.RBUF", PciSegEnabled[Idx]);
> +    Status = AcpiTableProtocol->FindPath (TableHandle, (VOID *)Buffer, &SegHandle);
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +
> +    for (Ix = 0; Ix < 3; Ix++) {
> +      Status = AcpiTableProtocol->GetOption (
> +                                    SegHandle,
> +                                    Ix,
> +                                    &DataType,
> +                                    (VOID *)&B,
> +                                    &DataSize
> +                                    );
> +      KB = B;
> +      if (EFI_ERROR (Status)) {
> +        continue;
> +      }
> +
> +      if (Ix == 0) { /* B[0] == AML_NAME_OP */
> +        if (!((DataSize == 1) && (DataType == EFI_ACPI_DATA_TYPE_OPCODE))) {
> +          break;
> +        }
> +      } else if (Ix == 1) { /* *B == "RBUF"  */
> +        if (!((DataSize == 4) && (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING))) {
> +          break;
> +        }
> +      } else { /* Ix:2 11 42 07 0A 6E 88 ... */
> +        if (DataType != EFI_ACPI_DATA_TYPE_CHILD) {
> +          break;
> +        }
> +
> +        KB += 5; /* Point to Resource type */
> +        Rs = (RESOURCE *)KB;
> +        Mem32 = 0;
> +        while ((Mem32 == 0) && ((KB - B) < DataSize)) {
> +          if (Rs->ResourceType == ACPI_RESOURCE_NAME_ADDRESS16) {
> +            KB += (Rs->ResourceSize + 3); /* Type + Size */
> +            Rs = (RESOURCE *)KB;
> +          } else if (Rs->ResourceType == ACPI_RESOURCE_NAME_ADDRESS64) {
> +
> +            if (Rs->Attribute == 0x00) { /* The first QWordMemory */
> +              Mem32 = 1;
> +              Segment = PciSegEnabled[Idx] - 2;
> +              Qm = (QWordMemory *)&(Rs->ResourcePtr);
> +              *Qm = Qmem[Segment]; /* Physical segment */
> +            }
> +            KB += (Rs->ResourceSize + 3); /* Type + Size */
> +            Rs = (RESOURCE *)KB;
> +          }
> +        }
> +        if (Mem32 != 0) {
> +          Status = AcpiTableProtocol->SetOption (
> +                                        SegHandle,
> +                                        Ix,
> +                                        (VOID *)B,
> +                                        DataSize
> +                                        );
> +        }
> +      }
> +    }
> +  }
> +  AcpiTableProtocol->Close (TableHandle);
> +  /* Update DSDT Checksum */
> +  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
> +
> +  return Status;
> +}
> +
> +VOID
> +ConstructMcfg (
> +  VOID   *McfgPtr,
> +  INT8   *PciSegEnabled,
> +  UINT32 McfgCount
> +  )
> +{
> +  EFI_MCFG_TABLE_CONFIG     McfgHeader = {
> +    {
> +      EFI_ACPI_6_1_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
> +      McfgCount,
> +      1,
> +      0x00,                        // Checksum will be updated at runtime
> +      EFI_ACPI_OEM_ID,
> +      EFI_ACPI_OEM_TABLE_ID,
> +      EFI_ACPI_OEM_REVISION,
> +      EFI_ACPI_CREATOR_ID,
> +      EFI_ACPI_CREATOR_REVISION
> +    },
> +    0x0000000000000000,            // Reserved
> +  };
> +  EFI_MCFG_CONFIG_STRUCTURE TMcfg = {
> +    .ullBaseAddress = 0,
> +    .usSegGroupNum = 0,
> +    .ucStartBusNum = 0,
> +    .ucEndBusNum = 255,
> +    .Reserved2 = 0,
> +  };
> +  UINT32                    Idx;
> +  VOID                      *TMcfgPtr = McfgPtr;
> +  AC01_RC                   *Rc;
> +
> +  CopyMem (TMcfgPtr, &McfgHeader, sizeof (EFI_MCFG_TABLE_CONFIG));
> +  TMcfgPtr += sizeof (EFI_MCFG_TABLE_CONFIG);
> +  for (Idx = 0; PciSegEnabled[Idx] != -1; Idx++) {
> +    Rc = GetRCList (PciSegEnabled[Idx]); /* Logical */
> +    TMcfg.ullBaseAddress = Rc->MmcfgAddr;
> +    TMcfg.usSegGroupNum = Rc->Logical;
> +    CopyMem (TMcfgPtr, &TMcfg, sizeof (EFI_MCFG_CONFIG_STRUCTURE));
> +    TMcfgPtr += sizeof (EFI_MCFG_CONFIG_STRUCTURE);
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiInstallMcfg (
> +  INT8 *PciSegEnabled
> +  )
> +{
> +  UINT32                  RcCount, McfgCount;
> +  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
> +  UINTN                   TableKey;
> +  EFI_STATUS              Status;
> +  VOID                    *McfgPtr;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("MCFG: Unable to locate ACPI table entry\n");
> +    return Status;
> +  }
> +  for (RcCount = 0; PciSegEnabled[RcCount] != -1; RcCount++) {
> +  }
> +  McfgCount = sizeof (EFI_MCFG_TABLE_CONFIG) + sizeof (EFI_MCFG_CONFIG_STRUCTURE) * RcCount;
> +  McfgPtr = AllocateZeroPool (McfgCount);
> +  if (McfgPtr == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  ConstructMcfg (McfgPtr, PciSegEnabled, McfgCount);
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                McfgPtr,
> +                                McfgCount,
> +                                &TableKey
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("MCFG: Unable to install MCFG table entry\n");
> +  }
> +  FreePool (McfgPtr);
> +  return Status;
> +}
> +
> +STATIC
> +VOID
> +ConstructIort (
> +  VOID   *IortPtr,
> +  UINT32 RcCount,
> +  UINT32 SmmuPmuAgentCount,
> +  UINT32 HeaderCount,
> +  INT8   *PciSegEnabled
> +  )
> +{
> +  EFI_ACPI_6_0_IO_REMAPPING_TABLE TIort = {
> +    .Header = __ACPI_HEADER (
> +                EFI_ACPI_6_0_IO_REMAPPING_TABLE_SIGNATURE,
> +                AC01_IO_REMAPPING_STRUCTURE,
> +                EFI_ACPI_IO_REMAPPING_TABLE_REVISION
> +                ),
> +    .NumNodes = (3 * RcCount) + SmmuPmuAgentCount,
> +    .NodeOffset = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE),
> +    0
> +  };
> +
> +  AC01_ITS_NODE TItsNode = {
> +    .Node = {
> +      EFI_ACPI_IORT_TYPE_ITS_GROUP,
> +      sizeof (EFI_ACPI_6_0_IO_REMAPPING_ITS_NODE) + 4,
> +      0x0,
> +      0x0,
> +      0x0,
> +      0x0,
> +      .NumItsIdentifiers = 1,
> +    },
> +    .ItsIdentifier = 1,
> +  };
> +
> +  AC01_RC_NODE TRcNode = {
> +    {
> +      {
> +        EFI_ACPI_IORT_TYPE_ROOT_COMPLEX,
> +        sizeof (AC01_RC_NODE),
> +        0x1,
> +        0x0,
> +        0x1,
> +        FIELD_OFFSET (AC01_RC_NODE, RcIdMapping),
> +      },
> +      EFI_ACPI_IORT_MEM_ACCESS_PROP_CCA,
> +      0x0,
> +      0x0,
> +      EFI_ACPI_IORT_MEM_ACCESS_FLAGS_CPM |
> +      EFI_ACPI_IORT_MEM_ACCESS_FLAGS_DACS,
> +      EFI_ACPI_IORT_ROOT_COMPLEX_ATS_UNSUPPORTED,
> +      .PciSegmentNumber = 0,
> +      .MemoryAddressSize = 64,
> +    },
> +    __AC01_ID_MAPPING (0x0, 0xffff, 0x0, SmmuNode, 0),
> +  };
> +
> +  AC01_SMMU_NODE TSmmuNode = {
> +    {
> +      {
> +        EFI_ACPI_IORT_TYPE_SMMUv3,
> +        sizeof (AC01_SMMU_NODE),
> +        0x2,  /* Revision */
> +        0x0,
> +        0x2,  /* Mapping Count */
> +        FIELD_OFFSET (AC01_SMMU_NODE, InterruptMsiMapping),
> +      },
> +      .Base = 0,
> +      EFI_ACPI_IORT_SMMUv3_FLAG_COHAC_OVERRIDE,
> +      0,
> +      0,
> +      0,
> +      0,
> +      0,
> +      0x0,
> +      0x0,
> +      0,
> +      .DeviceIdMapping = 1,
> +    },
> +    __AC01_ID_MAPPING (0x0, 0xffff, 0, SmmuNode, 0),
> +    __AC01_ID_MAPPING (0x0, 0x1, 0, SmmuNode, 1),
> +  };
> +
> +  EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE TPmcgNode = {
> +    {
> +      EFI_ACPI_IORT_TYPE_PMCG,
> +      sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE),
> +      0x1,
> +      0x0,
> +      0x0,
> +      0x0,
> +    },
> +    0, /* Page 0 Base. Need to be filled */
> +    0, /* GSIV. Need to be filled */
> +    0, /* Node reference. Need to be filled */
> +    0, /* Page 1 Base. Need to be filled. */
> +  };
> +
> +  UINT32  Idx, Idx1, SmmuNodeOffset[MAX_AC01_PCIE_ROOT_COMPLEX];
> +  VOID    *TIortPtr = IortPtr, *SmmuPtr, *PmcgPtr;
> +  UINT32  ItsOffset[MAX_AC01_PCIE_ROOT_COMPLEX];
> +  AC01_RC *Rc;
> +  UINTN   NumTbuPmu;
> +
> +  TIort.Header.Length = HeaderCount;
> +  CopyMem (TIortPtr, &TIort, sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE));
> +  TIortPtr += sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE);
> +  for (Idx = 0; Idx < RcCount; Idx++) {
> +    ItsOffset[Idx] = TIortPtr - IortPtr;
> +    TItsNode.ItsIdentifier = PciSegEnabled[Idx]; /* Physical */
> +    CopyMem (TIortPtr, &TItsNode, sizeof (AC01_ITS_NODE));
> +    TIortPtr += sizeof (AC01_ITS_NODE);
> +  }
> +
> +  SmmuPtr = TIortPtr + RcCount * sizeof (AC01_RC_NODE);
> +  PmcgPtr = SmmuPtr + RcCount * sizeof (AC01_SMMU_NODE);
> +  for (Idx = 0; Idx < RcCount; Idx++) {
> +    SmmuNodeOffset[Idx] = SmmuPtr - IortPtr;
> +    Rc = GetRCList (PciSegEnabled[Idx]); /* Physical RC */
> +    TSmmuNode.Node.Base = Rc->TcuAddr;
> +    TSmmuNode.InterruptMsiMapping.OutputBase = PciSegEnabled[Idx] << 16;
> +    TSmmuNode.InterruptMsiMapping.OutputReference = ItsOffset[Idx];
> +    TSmmuNode.InterruptMsiMappingSingle.OutputBase = PciSegEnabled[Idx] << 16;
> +    TSmmuNode.InterruptMsiMappingSingle.OutputReference = ItsOffset[Idx];
> +    CopyMem (SmmuPtr, &TSmmuNode, sizeof (AC01_SMMU_NODE));
> +    SmmuPtr += sizeof (AC01_SMMU_NODE);
> +
> +    if (!SmmuPmuAgentCount) {
> +      continue;
> +    }
> +
> +    /* Add PMCG nodes */
> +    if (Rc->Type == RCA) {
> +      NumTbuPmu = RCA_NUM_TBU_PMU;
> +    } else {
> +      NumTbuPmu = RCB_NUM_TBU_PMU;
> +    }
> +    for (Idx1 = 0; Idx1 < NumTbuPmu; Idx1++) {
> +      TPmcgNode.Base = Rc->TcuAddr;
> +      if (NumTbuPmu == RCA_NUM_TBU_PMU) {
> +        switch (Idx1) {
> +        case 0:
> +          TPmcgNode.Base += 0x40000;
> +          break;
> +
> +        case 1:
> +          TPmcgNode.Base += 0x60000;
> +          break;
> +
> +        case 2:
> +          TPmcgNode.Base += 0xA0000;
> +          break;
> +
> +        case 3:
> +          TPmcgNode.Base += 0xE0000;
> +          break;
> +
> +        case 4:
> +          TPmcgNode.Base += 0x100000;
> +          break;
> +
> +        case 5:
> +          TPmcgNode.Base += 0x140000;
> +          break;
> +        }
> +      } else {
> +       switch (Idx1) {
> +        case 0:
> +          TPmcgNode.Base += 0x40000;
> +          break;
> +
> +        case 1:
> +          TPmcgNode.Base += 0x60000;
> +          break;
> +
> +        case 2:
> +          TPmcgNode.Base += 0xA0000;
> +          break;
> +
> +        case 3:
> +          TPmcgNode.Base += 0xE0000;
> +          break;
> +
> +        case 4:
> +          TPmcgNode.Base += 0x120000;
> +          break;
> +
> +        case 5:
> +          TPmcgNode.Base += 0x160000;
> +          break;
> +
> +        case 6:
> +          TPmcgNode.Base += 0x180000;
> +          break;
> +
> +        case 7:
> +          TPmcgNode.Base += 0x1C0000;
> +          break;
> +
> +        case 8:
> +          TPmcgNode.Base += 0x200000;
> +          break;
> +
> +        case 9:
> +          TPmcgNode.Base += 0x240000;
> +          break;
> +        }
> +      }
> +      TPmcgNode.Page1Base = TPmcgNode.Base + 0x12000;
> +      TPmcgNode.Base += 0x2000;
> +      TPmcgNode.NodeReference = SmmuNodeOffset[Idx];
> +      TPmcgNode.OverflowInterruptGsiv = gTbuPmuIrqArray[PciSegEnabled[Idx]] + Idx1;
> +      CopyMem (PmcgPtr, &TPmcgNode, sizeof (TPmcgNode));
> +      PmcgPtr += sizeof (TPmcgNode);
> +    }
> +
> +    /* TCU PMCG */
> +    TPmcgNode.Base = Rc->TcuAddr;
> +    TPmcgNode.Base += 0x2000;
> +    TPmcgNode.Page1Base = Rc->TcuAddr + 0x12000;
> +    TPmcgNode.NodeReference = SmmuNodeOffset[Idx];
> +    TPmcgNode.OverflowInterruptGsiv = gTcuPmuIrqArray[PciSegEnabled[Idx]];
> +    CopyMem (PmcgPtr, &TPmcgNode, sizeof (TPmcgNode));
> +    PmcgPtr += sizeof (TPmcgNode);
> +  }
> +
> +  for (Idx = 0; Idx < RcCount; Idx++) {
> +    TRcNode.Node.PciSegmentNumber = GetRCList (PciSegEnabled[Idx])->Logical; /* Logical */
> +    TRcNode.RcIdMapping.OutputReference = SmmuNodeOffset[Idx];
> +    CopyMem (TIortPtr, &TRcNode, sizeof (AC01_RC_NODE));
> +    TIortPtr += sizeof (AC01_RC_NODE);
> +  }
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiInstallIort (
> +  INT8 *PciSegEnabled
> +  )
> +{
> +  UINT32                  RcCount, SmmuPmuAgentCount, TotalCount;
> +  VOID                    *IortPtr;
> +  UINTN                   TableKey;
> +  EFI_STATUS              Status;
> +  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
> +
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiTableProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("IORT: Unable to locate ACPI table entry\n");
> +    return Status;
> +  }
> +
> +  for (RcCount = 0, SmmuPmuAgentCount = 0; PciSegEnabled[RcCount] != -1; RcCount++) {
> +    if ((GetRCList (PciSegEnabled[RcCount]))->Type == RCA) {
> +      SmmuPmuAgentCount += RCA_NUM_TBU_PMU;
> +    } else {
> +      SmmuPmuAgentCount += RCB_NUM_TBU_PMU;
> +    }
> +    SmmuPmuAgentCount += 1; /* Only 1 TCU */
> +  }
> +
> +  if (!PcieBoardCheckSmmuPmuEnabled ()) {
> +    SmmuPmuAgentCount = 0;
> +  }
> +
> +  TotalCount = sizeof (EFI_ACPI_6_0_IO_REMAPPING_TABLE) +
> +               RcCount * (sizeof (AC01_ITS_NODE) + sizeof (AC01_RC_NODE) + sizeof (AC01_SMMU_NODE)) +
> +               SmmuPmuAgentCount * sizeof (EFI_ACPI_6_0_IO_REMAPPING_PMCG_NODE);
> +
> +  IortPtr = AllocateZeroPool (TotalCount);
> +  if (IortPtr == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  ConstructIort (IortPtr, RcCount, SmmuPmuAgentCount, TotalCount, PciSegEnabled);
> +
> +  Status = AcpiTableProtocol->InstallAcpiTable (
> +                                AcpiTableProtocol,
> +                                IortPtr,
> +                                TotalCount,
> +                                &TableKey
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("IORT: Unable to install IORT table entry\n");
> +  }
> +  FreePool (IortPtr);
> +  return Status;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib library instance
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
@ 2021-06-07 22:45   ` Leif Lindholm
  2021-06-15 16:50     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 22:45 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:07 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Provides basic features like:
> * Screen menu to change bifurcation setting of each Root Complex. Note
>   that we can only change the option for Root Complex which doesn't have
>   default value in the BoardSetting.
> * Parsing the BoardSetting and coordinate with saved setting to enable
>   corresponding PCIe controller of each Root Complex.
> * Config speed and lane of enabled controller.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                 |    3 +
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf    |   60 ++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h       |   89 ++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h   |  138 +++
>  Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h     |  102 ++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr             |  212 ++++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c         |  438 ++++++++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c   |  327 ++++++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c   | 1120 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni |   99 ++
>  10 files changed, 2588 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 0d79673ce50a..a372a4e0078b 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -40,6 +40,9 @@ [LibraryClasses]
>    ##  @libraryclass  Defines a set of methods to initialize Pcie
>    PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h
>  
> +  ##  @libraryclass  Defines a set of miscellaneous PCIe functions
> +  PcieBoardLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
> +
>    ##  @libraryclass  Defines a set of methods to access flash memory.
>    FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>  
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
> new file mode 100644
> index 000000000000..6be78f8936d7
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
> @@ -0,0 +1,60 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PcieBoardLib
> +  FILE_GUID                      = 062191A6-E113-4FD6-84C7-E400B4B34759
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PcieBoardLib
> +
> +[Sources]
> +  PcieBoard.c
> +  PcieBoardCommon.c
> +  PcieBoardScreen.c
> +  PcieBoardScreen.h
> +  PcieBoardScreen.uni
> +  NVDataStruc.h
> +  Vfr.vfr
> +
> +[Packages]
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  BaseLib
> +  DevicePathLib
> +  GpioLib
> +  HiiLib
> +  HobLib
> +  MemoryAllocationLib
> +  SystemFirmwareInterfaceLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid
> +  gEfiHiiStringProtocolGuid                     ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +  gEfiHiiDatabaseProtocolGuid                   ## CONSUMES
> +  gEfiConfigKeywordHandlerProtocolGuid          ## CONSUMES
> +
> +[Guids]
> +  gEfiIfrTianoGuid                              ## CONSUMES
> +  gPlatformManagerFormsetGuid                   ## CONSUMES
> +  gPlatformHobGuid                              ## CONSUMES
> +
> +[Depex]
> +  TRUE
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
> new file mode 100644
> index 000000000000..f94f12d968fd
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h

(Should this not be NVDataStruct.h?

> @@ -0,0 +1,89 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef NVDATASTRUC_H_
> +#define NVDATASTRUC_H_
> +
> +#define MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX 16
> +
> +#define PCIE_VARSTORE_NAME        L"PcieIfrNVData"
> +#define PCIE_VARSTORE_ID          0x1234
> +#define PCIE_FORM_ID              0x1235
> +#define PCIE_RC0_FORM_ID          0x1236
> +#define PCIE_RC1_FORM_ID          0x1237
> +#define PCIE_RC2_FORM_ID          0x1238
> +#define PCIE_RC3_FORM_ID          0x1239
> +#define PCIE_RC4_FORM_ID          0x123A
> +#define PCIE_RC5_FORM_ID          0x123B
> +#define PCIE_RC6_FORM_ID          0x123C
> +#define PCIE_RC7_FORM_ID          0x123D
> +#define PCIE_RC8_FORM_ID          0x123E
> +#define PCIE_RC9_FORM_ID          0x123F
> +#define PCIE_RC10_FORM_ID         0x1240
> +#define PCIE_RC11_FORM_ID         0x1241
> +#define PCIE_RC12_FORM_ID         0x1242
> +#define PCIE_RC13_FORM_ID         0x1243
> +#define PCIE_RC14_FORM_ID         0x1244
> +#define PCIE_RC15_FORM_ID         0x1245
> +#define PCIE_FORM_SET_GUID        { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98,  0x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } }
> +
> +#define PCIE_GOTO_ID_BASE         0x8040

Would recommend prefix before PCIE.
Or, given this is a fully local include - dropping the PCIE prefix.

> +
> +#pragma pack(1)
> +
> +//
> +// NV data structure definition
> +//
> +typedef struct {
> +  BOOLEAN RCStatus[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
> +  UINT8   RCBifurLo[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
> +  UINT8   RCBifurHi[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
> +  UINT32  SmmuPmu;
> +} PCIE_VARSTORE_DATA;

Same.

> +
> +//
> +// Labels definition
> +//
> +#define LABEL_UPDATE             0x2223
> +#define LABEL_END                0x2224
> +#define LABEL_RC0_UPDATE         0x2225
> +#define LABEL_RC0_END            0x2226
> +#define LABEL_RC1_UPDATE         0x2227
> +#define LABEL_RC1_END            0x2228
> +#define LABEL_RC2_UPDATE         0x2229
> +#define LABEL_RC2_END            0x222A
> +#define LABEL_RC3_UPDATE         0x222B
> +#define LABEL_RC3_END            0x222C
> +#define LABEL_RC4_UPDATE         0x222D
> +#define LABEL_RC4_END            0x222E
> +#define LABEL_RC5_UPDATE         0x222F
> +#define LABEL_RC5_END            0x2230
> +#define LABEL_RC6_UPDATE         0x2231
> +#define LABEL_RC6_END            0x2232
> +#define LABEL_RC7_UPDATE         0x2233
> +#define LABEL_RC7_END            0x2234
> +#define LABEL_RC8_UPDATE         0x2235
> +#define LABEL_RC8_END            0x2236
> +#define LABEL_RC9_UPDATE         0x2237
> +#define LABEL_RC9_END            0x2238
> +#define LABEL_RC10_UPDATE        0x2239
> +#define LABEL_RC10_END           0x223A
> +#define LABEL_RC11_UPDATE        0x223B
> +#define LABEL_RC11_END           0x223C
> +#define LABEL_RC12_UPDATE        0x223D
> +#define LABEL_RC12_END           0x223E
> +#define LABEL_RC13_UPDATE        0x223F
> +#define LABEL_RC13_END           0x2240
> +#define LABEL_RC14_UPDATE        0x2241
> +#define LABEL_RC14_END           0x2242
> +#define LABEL_RC15_UPDATE        0x2243
> +#define LABEL_RC15_END           0x2244
> +
> +#pragma pack()

Move this to just after the struct? Nothing to pack beyond that.

> +
> +#endif
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
> new file mode 100644
> index 000000000000..c5c50060870c
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
> @@ -0,0 +1,138 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_SCREEN_H_
> +#define PCIE_SCREEN_H_

Needs to not start with PCIE - additional prefix is fine.

> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/FormBrowser2.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigKeyword.h>
> +#include <Protocol/HiiConfigRouting.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>

Move all include statements not needed by this header file to the .c
file that actually uses them.

> +
> +#include "NVDataStruc.h"
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 VfrBin[];

Add some descriptive prefix.
PcieBoardVfrBin?

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 PcieDxeStrings[];

Not part of PCIE or PI spec - add "Platform" or something prefix.

> +
> +#define MAX_EDITABLE_ELEMENTS 3
> +#define PCIE_RC0_STATUS_OFFSET  \
> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCStatus[0])
> +#define PCIE_RC0_BIFUR_LO_OFFSET  \
> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurLo[0])
> +#define PCIE_RC0_BIFUR_HI_OFFSET  \
> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurHi[0])
> +#define PCIE_SMMU_PMU_OFFSET  \
> +  OFFSET_OF (PCIE_VARSTORE_DATA, SmmuPmu)
> +
> +#define PCIE_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'E')

This signature is supposed to be at least potentially unique.

> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE         DriverHandle;
> +  EFI_HII_HANDLE     HiiHandle;
> +  PCIE_VARSTORE_DATA VarStoreConfig;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
> +  EFI_HII_STRING_PROTOCOL             *HiiString;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} PCIE_SCREEN_PRIVATE_DATA;

Structs need more unique prefixes.

> +
> +typedef union {
> +  UINT16 VAR_ID;
> +  struct _PCIE_VAR_ID {
> +    UINT16 PciDevIndex     : 12;
> +    UINT16 DataType        : 3;
> +    UINT16 Always1         : 1;
> +  } IdField;
> +} PCIE_VAR_ID;
> +
> +typedef struct {
> +  UINTN         PciDevIdx;
> +  EFI_STRING_ID GotoStringId;
> +  EFI_STRING_ID GotoHelpStringId;
> +  UINT16        GotoKey;
> +  BOOLEAN       ShowItem;
> +} PCIE_SETUP_GOTO_DATA;
> +
> +typedef struct {
> +  VOID               *StartOpCodeHandle;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +
> +} PCIE_IFR_INFO;
> +
> +#define PCIE_SCREEN_PRIVATE_FROM_THIS(a)  \
> +  CR (a, PCIE_SCREEN_PRIVATE_DATA, ConfigAccess, PCIE_SCREEN_PRIVATE_DATA_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +UINT8
> +PcieRCDevMapLoDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  );
> +
> +UINT8
> +PcieRCDevMapHiDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  );
> +
> +BOOLEAN
> +PcieRCActiveDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  );
> +
> +#endif /* PCIE_SCREEN_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
> new file mode 100644
> index 000000000000..bff5b62ba13b
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
> @@ -0,0 +1,102 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_BOARD_LIB_H_
> +#define PCIE_BOARD_LIB_H_
> +
> +#include "Pcie.h"

OK, I'm going to stop pointing this out from this point on, but
anything that is not referencing a direct aspect of the PCIe
specification should not be named PCIE*/Pcie*, ...
These names are reserved.

Since most of these symbols are internal anyway, and reference only
settings inside the PCIE configuration screen, I think the cleanest
thing would be to drop the PCIE/Pcie prefixes altogether.

> +
> +/**
> +
> +  Check if a PCIE port enabled in the board configuration.
> +
> +  @param  Index                     The port index.
> +
> +  @retval                           TRUE if the port enabled, otherwise FALSE.
> +
> +**/
> +BOOLEAN
> +PcieBoardCheckSysSlotEnabled (
> +  IN UINTN Index
> +  );
> +
> +VOID
> +PcieBoardGetRCSegmentNumber (
> +  IN  AC01_RC *RC,
> +  OUT UINTN   *SegmentNumber
> +  );
> +
> +/**
> +
> +  Check if SMM PMU enabled in board screen
> +
> +  @retval                           TRUE if the SMMU PMU enabled, otherwise FALSE.
> +
> +**/
> +BOOLEAN
> +PcieBoardCheckSmmuPmuEnabled (
> +  VOID
> +  );
> +
> +/**
> +
> +  Build UEFI menu.
> +
> +  @param  ImageHandle               Handle.
> +  @param  SystemTable               Pointer to System Table.
> +  @param  RCList                    List of Root Complex with properties.
> +
> +  @retval                           EFI_SUCCESS if successful, otherwise EFI_ERROR.
> +
> +**/
> +EFI_STATUS
> +PcieBoardScreenInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable,
> +  IN AC01_RC          *RCList
> +  );
> +
> +BOOLEAN
> +IsEmptyRC (
> +  IN AC01_RC *RC
> +  );
> +
> +VOID
> +PcieBoardSetupDevmap (
> +  IN AC01_RC *RC
> +  );
> +
> +VOID
> +PcieBoardGetLaneAllocation (
> +  IN AC01_RC *RC
> +  );
> +
> +VOID
> +PcieBoardGetSpeed (
> +  IN AC01_RC *RC
> +  );
> +
> +VOID
> +PcieBoardParseRCParams (
> +  IN AC01_RC *RC
> +  );
> +
> +VOID
> +PcieBoardAssertPerst (
> +  AC01_RC *RC,
> +  UINT32  PcieIndex,
> +  UINT8   Bifurcation,
> +  BOOLEAN isPullToHigh
> +  );
> +
> +BOOLEAN
> +PcieBoardCheckSmmuPmuEnabled (
> +  VOID
> +  );
> +
> +#endif /* PCIE_BOARD_LIB_H_ */
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
> new file mode 100644
> index 000000000000..a596d5ac9a92
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
> @@ -0,0 +1,212 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "NVDataStruc.h"
> +
> +formset
> +  guid    = PCIE_FORM_SET_GUID,
> +  title   = STRING_TOKEN(STR_PCIE_FORM),
> +  help    = STRING_TOKEN(STR_PCIE_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  //
> +  // Define a variable Storage
> +  //
> +  varstore PCIE_VARSTORE_DATA,
> +    varid = PCIE_VARSTORE_ID,
> +    name  = PcieIfrNVData,
> +    guid  = PCIE_FORM_SET_GUID;
> +
> +  form
> +    formid = PCIE_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_FORM);
> +
> +    label LABEL_UPDATE;
> +    // dynamic content here
> +    label LABEL_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC0_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC0_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC0_FORM);
> +
> +    label LABEL_RC0_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC0_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC1_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC1_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC1_FORM);
> +
> +    label LABEL_RC1_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC1_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC2_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC2_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC2_FORM);
> +
> +    label LABEL_RC2_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC2_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC3_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC3_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC3_FORM);
> +
> +    label LABEL_RC3_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC3_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC4_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC4_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC4_FORM);
> +
> +    label LABEL_RC4_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC4_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC5_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC5_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC5_FORM);
> +
> +    label LABEL_RC5_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC5_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC6_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC6_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC6_FORM);
> +
> +    label LABEL_RC6_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC6_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC7_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC7_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC7_FORM);
> +
> +    label LABEL_RC7_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC7_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC8_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC8_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC8_FORM);
> +
> +    label LABEL_RC8_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC8_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC9_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC9_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC9_FORM);
> +
> +    label LABEL_RC9_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC9_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC10_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC10_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC10_FORM);
> +
> +    label LABEL_RC10_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC10_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC11_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC11_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC11_FORM);
> +
> +    label LABEL_RC11_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC11_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC12_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC12_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC12_FORM);
> +
> +    label LABEL_RC12_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC12_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC13_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC13_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC13_FORM);
> +
> +    label LABEL_RC13_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC13_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC14_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC14_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC14_FORM);
> +
> +    label LABEL_RC14_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC14_END;
> +  endform;
> +
> +  form
> +    formid = PCIE_RC15_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_RC15_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_RC15_FORM);
> +
> +    label LABEL_RC15_UPDATE;
> +    // dynamic content here
> +    label LABEL_RC15_END;
> +  endform;
> +
> +endformset;
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
> new file mode 100644
> index 000000000000..c0c94d349b5b
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
> @@ -0,0 +1,438 @@
> +/** @file
> +
> +  Pcie board specific driver to handle asserting PERST signal to Endpoint
> +  card and parsing NVPARAM board settings for bifurcation programming.
> +
> +  PERST asserting is via group of GPIO pins to CPLD as Platform Specification.
> +
> +  NVPARAM board settings is spec-ed within Firmware Interface Requirement.
> +  Bifuration devmap is programmed before at SCP following the rule
> +
> +  Root Complex Type-A devmap settings (RP == Root Port)
> +  -----------------------------------------
> +  | RP0   | RP1  | RP2  | RP3  | Devmap   |
> +  | (x16) | (x4) | (x8) | (x4) | (output) |
> +  -------------------------------------------
> +  |  Y    |  N   |  N   |  N   | 0        |
> +  |  Y    |  N   |  Y   |  N   | 1        |
> +  |  Y    |  N   |  Y   |  Y   | 2        |
> +  |  Y    |  Y   |  Y   |  Y   | 3        |
> +  -----------------------------------------
> +
> +  Root Complex Type-B LO (aka RCBxA) devmap settings (RP == Root Port)
> +  ----------------------------------------
> +  | RP0  | RP1  | RP2  | RP3  | Devmap   |
> +  | (x8) | (x2) | (x4) | (x3) | (output) |
> +  ----------------------------------------
> +  |  Y   |  N   |  N   |  N   | 0        |
> +  |  Y   |  N   |  Y   |  N   | 1        |
> +  |  Y   |  N   |  Y   |  Y   | 2        |
> +  |  Y   |  Y   |  Y   |  Y   | 3        |
> +  ----------------------------------------
> +
> +  Root Complex Type-B LO (aka RCBxB) devmap settings (RP == Root Port)
> +  ----------------------------------------
> +  | RP4  | RP5  | RP6  | RP7  | Devmap   |
> +  | (x8) | (x2) | (x4) | (x3) | (output) |
> +  ----------------------------------------
> +  |  Y   |  N   |  N   |  N   | 0        |
> +  |  Y   |  N   |  Y   |  N   | 1        |
> +  |  Y   |  N   |  Y   |  Y   | 2        |
> +  |  Y   |  Y   |  Y   |  Y   | 3        |
> +  ----------------------------------------
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/GpioLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PcieBoardLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <NVDataStruc.h>
> +#include <NVParamDef.h>
> +#include <Pcie.h>
> +#include <PlatformInfoHob.h>
> +
> +#ifndef BIT
> +#define BIT(nr)                         (1 << (nr))
> +#endif
> +
> +extern CHAR16   VariableName[];
> +extern EFI_GUID gPcieFormSetGuid;
> +
> +VOID
> +EFIAPI
> +PcieBoardLoadPreset (
> +  IN AC01_RC *RC
> +  )
> +{
> +  UINT32 Nv;
> +  INTN   NvParam;
> +  INTN   Ret;
> +  INTN   i;
> +
> +  // Load default value
> +  for (i = 0; i < MAX_PCIE_B; i++) {
> +    RC->PresetGen3[i] = PRESET_INVALID;
> +    RC->PresetGen4[i] = PRESET_INVALID;
> +  }
> +
> +  // Load override value
> +  if (RC->Socket == 0) {
> +    if (RC->Type == RCA) {
> +      if (RC->ID < 4) {

There are various live-coded values of 4 and 2 in this function.
Please replace them with #defines with descriptive names to improve readability.

> +        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NVPARAM_SIZE;
> +      } else {
> +        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
> +      }
> +    } else {
> +      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
> +    }
> +  } else if (RC->Type == RCA) {
> +    if (RC->ID < 4) {
> +      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NVPARAM_SIZE;
> +    } else {
> +      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
> +    }
> +  } else {
> +    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
> +  }
> +
> +  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
> +  if (Ret == EFI_SUCCESS) {
> +    for (i = 0; i < 4; i++) {
> +      RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
> +    }
> +  }
> +
> +  if (RC->Type == RCB) {
> +    NvParam += NVPARAM_SIZE;
> +    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
> +    if (Ret == EFI_SUCCESS) {
> +      for (i = 0; i < 4; i++) {
> +        RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
> +      }
> +    }
> +  }
> +
> +  if (RC->Socket == 0) {
> +    if (RC->Type == RCA) {
> +      if (RC->ID < 4) {
> +        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NVPARAM_SIZE;
> +      } else {
> +        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
> +      }
> +    } else {
> +      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
> +    }
> +  } else if (RC->Type == RCA) {
> +    if (RC->ID < 4) {
> +      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NVPARAM_SIZE;
> +    } else {
> +      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
> +    }
> +  } else {
> +    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
> +  }
> +
> +  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
> +  if (Ret == EFI_SUCCESS) {
> +    for (i = 0; i < 4; i++) {
> +      RC->PresetGen4[i] = (Nv >> (8 * i)) & 0xFF;
> +    }
> +  }
> +
> +  if (RC->Type == RCB) {
> +    NvParam += NVPARAM_SIZE;
> +    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
> +    if (Ret == EFI_SUCCESS) {
> +      for (i = 0; i < 4; i++) {
> +        RC->PresetGen4[i + 4] = (Nv >> (8 * i)) & 0xFF;
> +      }
> +    }
> +  }
> +}
> +
> +VOID
> +EFIAPI
> +PcieBoardParseRCParams (
> +  IN AC01_RC *RC
> +  )
> +{
> +  UINT32             Efuse;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  UINT8              PlatRCId;
> +  EFI_STATUS         Status;
> +  VOID               *Hob;
> +  UINTN              BufferSize;
> +  PCIE_VARSTORE_DATA VarStoreConfig = {
> +    .RCStatus = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE,
> +                 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE},
> +    .RCBifurLo = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> +    .RCBifurHi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> +    .SmmuPmu = 0
> +  };
> +
> +  PCIE_DEBUG ("%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID);
> +
> +  PlatRCId = RC->Socket * RCS_PER_SOCKET + RC->ID;
> +  // Get RC activation status
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  VariableName,
> +                  &gPcieFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &VarStoreConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    PCIE_DEBUG ("%a - Failed to read PCIE variable data from config store.\n", __FUNCTION__);
> +  }
> +
> +  RC->Active = VarStoreConfig.RCStatus[PlatRCId];
> +  RC->DevMapLo = VarStoreConfig.RCBifurLo[PlatRCId];
> +  RC->DevMapHi = VarStoreConfig.RCBifurHi[PlatRCId];
> +
> +  PCIE_DEBUG (
> +    "%a - Socket%d RC%d is %s\n",
> +    __FUNCTION__,
> +    RC->Socket,
> +    RC->ID,
> +    (RC->Active) ? "ACTIVE" : "INACTIVE"
> +    );
> +
> +  if (!IsSlaveSocketActive () && RC->Socket == 1) {
> +    RC->Active = FALSE;
> +  }
> +
> +  if (RC->Active) {
> +    //
> +    // Consolidate with E-fuse
> +    //
> +    Efuse = 0;
> +    Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +    if (Hob != NULL) {
> +      PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +      Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
> +      PCIE_DEBUG (
> +        "RcDisableMask[0]: 0x%x [1]: 0x%x\n",
> +        PlatformHob->RcDisableMask[0],
> +        PlatformHob->RcDisableMask[1]
> +        );
> +
> +      // Update errata flags for Ampere Altra
> +      if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) {
> +        if (PlatformHob->AHBCId[0] == 0x20100
> +            || PlatformHob->AHBCId[0] == 0x21100
> +            || (IsSlaveSocketActive ()
> +                && (PlatformHob->AHBCId[1] == 0x20100
> +                    || PlatformHob->AHBCId[1] == 0x21100)))
> +        {
> +          RC->Flags |= PCIE_ERRATA_SPEED1;
> +          PCIE_DEBUG ("RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags);
> +        }
> +      }
> +    }
> +
> +    RC->Active = (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALSE;
> +  }
> +
> +  /* Load Gen3/Gen4 preset */
> +  PcieBoardLoadPreset (RC);
> +  PcieBoardGetLaneAllocation (RC);
> +  PcieBoardSetupDevmap (RC);
> +  PcieBoardGetSpeed (RC);
> +}
> +
> +VOID
> +EFIAPI
> +PcieBoardReleaseAllPerst (
> +  IN UINT8 SocketId
> +  )
> +{
> +  UINT32 GpioIndex, GpioPin;
> +
> +  // Write 1 to all GPIO[16..21] to release all PERST
> +  GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * SocketId + 16;
> +  for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
> +    GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
> +  }
> +}
> +
> +VOID
> +EFIAPI
> +PcieBoardAssertPerst (
> +  AC01_RC *RC,
> +  UINT32  PcieIndex,
> +  UINT8   Bifurcation,
> +  BOOLEAN isPullToHigh

CamelCase uses leading capital letter.

> +  )
> +{
> +  UINT32 GpioGroupVal, Val, GpioIndex, GpioPin;
> +
> +  /*
> +   * For Post-silicon, Fansipan board is using GPIO combination (GPIO[16..21])
> +   * to control CPLD.
> +   * It should be follow PCIE RESET TABLE in Fansipan schematic.
> +   *
> +   * Depend on Bifurcation settings, will active corresponding PERST pin or not
> +   */
> +
> +  if (RC->Type == RCA) {
> +    switch (Bifurcation) {
> +    case 0:                 // RCA_BIFURCATION_ONE_X16:
> +      if (PcieIndex != 0) { // 1,2,3
> +      }
> +      break;
> +
> +    case 1:                                       // RCA_BIFURCATION_TWO_X8:

Wouldn't this look an awful lot better as
  case RCA_BIFURCATION_TWO_X8:
than with a live-coded integer, followed by a comment explaining what
that integer means?
This appplies throughout this function.

> +      if ((PcieIndex == 1) || (PcieIndex == 3)) { // 1,3
> +      }
> +      break;
> +
> +    case 2:                 // RCA_BIFURCATION_ONE_X8_TWO_X4:
> +      if (PcieIndex == 1) { // 1
> +      }
> +      break;
> +
> +    case 3: // RCA_BIFURCATION_FOUR_X4:
> +      break;
> +
> +    default:
> +      PCIE_DEBUG ("Invalid Bifurcation setting\n");
> +      break;
> +    }
> +  } else { // RCB
> +    switch (Bifurcation) {
> +    case 0:                                       // RCB_BIFURCATION_ONE_X8:
> +      if ((PcieIndex != 0) && (PcieIndex != 4)) { // 1,2,3,5,6,7
> +      }
> +      break;
> +
> +    case 1:                       // RCB_BIFURCATION_TWO_X4:
> +      if ((PcieIndex % 2) != 0) { // 1,3,5,7
> +      }
> +      break;
> +
> +    case 2: // RCB_BIFURCATION_ONE_X4_TWO_X2:
> +      if ((PcieIndex == 1) || (PcieIndex == 5)) {
> +      }
> +      break;
> +
> +    case 3: // RCB_BIFURCATION_FOUR_X2:
> +      break;
> +
> +    default:
> +      PCIE_DEBUG ("Invalid Bifurcation setting\n");
> +      break;
> +    }
> +  }
> +
> +  if (!isPullToHigh) { // Pull PERST to Low
> +    if (RC->Type == RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3
> +      GpioGroupVal = 62 - RC->ID*4 - PcieIndex;

That 62 needs to be a #define.

> +    }
> +    else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7

else on same line as } 

> +      GpioGroupVal = 46 - (RC->ID - 4)*8 - PcieIndex;
> +    }
> +
> +    GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16;
> +    for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
> +      // 6: Number of GPIO pins to control via CPLD
> +      Val = (GpioGroupVal & 0x3F) & (1 << GpioIndex);
> +      if (Val == 0) {
> +        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_LOW);
> +      } else {
> +        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
> +      }
> +    }
> +
> +    // Keep reset as low as 100 ms as specification
> +    MicroSecondDelay (100 * 1000);
> +  } else { // Pull PERST to High
> +    PcieBoardReleaseAllPerst (RC->Socket);
> +  }
> +}
> +
> +/**
> + * Overrride the segment number for a root complex with
> + * a board specific number.
> + **/
> +VOID
> +EFIAPI
> +PcieBoardGetRCSegmentNumber (
> +  IN  AC01_RC *RC,
> +  OUT UINTN   *SegmentNumber
> +  )
> +{
> +  if (RC->Socket == 0) {
> +    if (RC->Type == RCA) {
> +      switch (RC->ID) {
> +      case 0:
> +        *SegmentNumber = 12;
> +        break;
> +
> +      case 1:
> +        *SegmentNumber = 13;
> +        break;
> +
> +      case 2:
> +        *SegmentNumber = 1;
> +        break;
> +
> +      case 3:
> +        *SegmentNumber = 0;
> +        break;
> +
> +        default:
> +          *SegmentNumber = 16;
> +      }
> +    } else { /* Socket0, CCIX: RCA0 and RCA1 */
> +      *SegmentNumber = RC->ID - 2;
> +    }
> +  } else { /* Socket1, CCIX: RCA0 and RCA1 */
> +    if (RC->ID == 0 || RC->ID == 1) {
> +      *SegmentNumber = 16;
> +    } else {
> +      *SegmentNumber = 4 + RC->ID;
> +    }
> +  }
> +}
> +
> +BOOLEAN
> +EFIAPI
> +PcieBoardCheckSmmuPmuEnabled (
> +  VOID
> +  )
> +{
> +  EFI_GUID           PcieFormSetGuid = PCIE_FORM_SET_GUID;
> +  PCIE_VARSTORE_DATA VarStoreConfig;
> +  UINTN              BufferSize;
> +  EFI_STATUS         Status;
> +
> +  // Get Buffer Storage data from EFI variable
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  PCIE_VARSTORE_NAME,
> +                  &PcieFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &VarStoreConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return FALSE;
> +  }
> +
> +  return VarStoreConfig.SmmuPmu;
> +}
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
> new file mode 100644
> index 000000000000..a8accbf53047
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
> @@ -0,0 +1,327 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Library/DebugLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +#include <NVParamDef.h>
> +
> +#include "Pcie.h"
> +
> +/* Host bridge registers */
> +#define HBRCAPDMR    0x0
> +#define HBRCBPDMR    0x4

Inappropriate names for this codebase.
Are these the actual register names as described in hardware manuals
for this device? If so, they can be permitted. But every file where
these names are used need to contain a glossary section at the start
of it, explaining what these actually are.
Applies also below.

> +
> +/* HBRCAPDMR */
> +#define RCAPCIDEVMAP_SET(dst, src) \
> +  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
> +
> +/* HBRCBPDMR */
> +#define RCBPCIDEVMAPLO_SET(dst, src) \
> +  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
> +#define RCBPCIDEVMAPHI_SET(dst, src) \
> +  (((dst) & ~0x70) | (((UINT32)(src) << 4) & 0x70))
> +
> +#define PCIE_GET_MAX_WIDTH(Pcie, Max) \
> +  !((Pcie).MaxWidth) ? (Max) : MIN((Pcie).MaxWidth, (Max))
> +
> +BOOLEAN
> +IsEmptyRC (
> +  IN AC01_RC *RC
> +  )
> +{
> +  INTN Idx;
> +
> +  for (Idx = PCIE_0; Idx < MAX_PCIE; Idx++) {
> +    if (RC->Pcie[Idx].Active) {
> +      return FALSE;
> +    }
> +  }
> +
> +  return TRUE;
> +}
> +
> +VOID
> +PcieBoardSetRCBifur (
> +  IN AC01_RC *RC,
> +  IN UINT8   RPStart,
> +  IN UINT8   DevMap
> +  )
> +{
> +  UINT8 MaxWidth;
> +
> +  if (RPStart != PCIE_0 && RPStart != PCIE_4) {
> +    return;
> +  }
> +
> +  if (RC->Type != RCB && RPStart == PCIE_4) {
> +    return;
> +  }
> +
> +  if (RC->Type == RCA && RC->Pcie[RPStart].MaxWidth == LNKW_X16) {
> +    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X4;
> +    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X8;
> +    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X4;
> +  }
> +
> +  if (RC->Type == RCB && RC->Pcie[RPStart].MaxWidth == LNKW_X8) {
> +    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X2;
> +    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X4;
> +    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X2;
> +  }
> +
> +  switch (DevMap) {
> +  case 1:

Would benefit from #defines with descriptive names rather than just
live-coded integers. (All cases in switch.)

> +    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
> +    RC->Pcie[RPStart + 1].Active = 0;
> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
> +    RC->Pcie[RPStart + 2].Active = 1;
> +    RC->Pcie[RPStart + 3].Active = 0;
> +    break;
> +
> +  case 2:
> +    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
> +    RC->Pcie[RPStart + 1].Active = 0;
> +    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
> +    RC->Pcie[RPStart + 2].Active = 1;
> +    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
> +    RC->Pcie[RPStart + 3].Active = 1;
> +    break;
> +
> +  case 3:
> +    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
> +    RC->Pcie[RPStart + 1].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 1], MaxWidth);
> +    RC->Pcie[RPStart + 1].Active = 1;
> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
> +    RC->Pcie[RPStart + 2].Active = 1;
> +    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
> +    RC->Pcie[RPStart + 3].Active = 1;
> +    break;
> +
> +  case 0:
> +  default:
> +    MaxWidth = (RC->Type == RCA) ? LNKW_X16 : LNKW_X8;
> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
> +    RC->Pcie[RPStart + 1].Active = 0;
> +    RC->Pcie[RPStart + 2].Active = 0;
> +    RC->Pcie[RPStart + 3].Active = 0;
> +    break;
> +  }
> +}
> +
> +VOID
> +PcieBoardGetLaneAllocation (
> +  IN AC01_RC *RC
> +  )
> +{
> +  INTN    RPIndex, Ret;
> +  UINT32  Nv, Width;
> +  NVPARAM NvParam;
> +
> +  // Retrieve lane allocation and capabilities for each controller
> +  if (RC->Type == RCA) {
> +    NvParam = NV_SI_RO_BOARD_S0_RCA0_CFG + RC->Socket * 96 +
> +                RC->ID * 8;
> +  } else {
> +    NvParam = NV_SI_RO_BOARD_S0_RCB0_LO_CFG + RC->Socket * 96 +
> +              (RC->ID - MAX_RCA) * 16;
> +  }

Please create descriptively named #defines for that 96, 16, and 8.

> +
> +  Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
> +  Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
> +
> +  for (RPIndex = 0; RPIndex < MAX_PCIE_A; RPIndex++) {
> +    Width = (Nv >> (RPIndex * 8)) & 0xF;
> +    switch (Width) {
> +    case 1:
> +    case 2:
> +    case 3:
> +    case 4:
> +      RC->Pcie[RPIndex].MaxWidth = 1 << Width;
> +      RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
> +      RC->Pcie[RPIndex].Active = TRUE;
> +      break;
> +
> +    case 0:
> +    default:
> +      RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
> +      RC->Pcie[RPIndex].MaxGen = 0;
> +      RC->Pcie[RPIndex].Active = FALSE;
> +      break;
> +    }
> +  }
> +
> +  if (RC->Type == RCB) {
> +    // Processing Hi
> +    NvParam += 8;
> +    Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
> +    Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
> +
> +    for (RPIndex = MAX_PCIE_A; RPIndex < MAX_PCIE; RPIndex++) {
> +      Width = (Nv >> ((RPIndex - MAX_PCIE_A) * 8)) & 0xF;

Same 8?

> +      switch (Width) {
> +      case 1:
> +      case 2:
> +      case 3:
> +      case 4:
> +        RC->Pcie[RPIndex].MaxWidth = 1 << Width;
> +        RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
> +        RC->Pcie[RPIndex].Active = TRUE;
> +        break;
> +
> +      case 0:
> +      default:
> +        RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
> +        RC->Pcie[RPIndex].MaxGen = 0;
> +        RC->Pcie[RPIndex].Active = FALSE;
> +        break;
> +      }
> +    }
> +  }
> +
> +  // Do not proceed if no Root Port enabled
> +  if (IsEmptyRC (RC)) {
> +    RC->Active = FALSE;
> +  }
> +}
> +
> +VOID
> +PcieBoardSetupDevmap (
> +  IN AC01_RC *RC
> +  )
> +{
> +  UINT32 Val;
> +
> +  if (RC->Pcie[PCIE_0].Active
> +      && RC->Pcie[PCIE_1].Active
> +      && RC->Pcie[PCIE_2].Active
> +      && RC->Pcie[PCIE_3].Active)
> +  {
> +    RC->DefaultDevMapLo = 3;

What's a DefaultDevMapLo?
The *only* benefit of SuperLongCamelCaseNames is that they actually
completely spell out what things are. This makes abbreviating them
extremely unfortunate, except where the abbreviation is completely
obvious regardless of context.

I also have a feeling these 0, 1, 2, 3 could benefit from being
replaced by descriptively named #defines.

> +  } else if (RC->Pcie[PCIE_0].Active
> +             && RC->Pcie[PCIE_2].Active
> +             && RC->Pcie[PCIE_3].Active)
> +  {
> +    RC->DefaultDevMapLo = 2;
> +  } else if (RC->Pcie[PCIE_0].Active
> +             && RC->Pcie[PCIE_2].Active)
> +  {
> +    RC->DefaultDevMapLo = 1;
> +  } else {
> +    RC->DefaultDevMapLo = 0;
> +  }
> +
> +  if (RC->Pcie[PCIE_4].Active
> +      && RC->Pcie[PCIE_5].Active
> +      && RC->Pcie[PCIE_6].Active
> +      && RC->Pcie[PCIE_7].Active)
> +  {
> +    RC->DefaultDevMapHi = 3;
> +  } else if (RC->Pcie[PCIE_4].Active
> +             && RC->Pcie[PCIE_6].Active
> +             && RC->Pcie[PCIE_7].Active)
> +  {
> +    RC->DefaultDevMapHi = 2;
> +  } else if (RC->Pcie[PCIE_4].Active
> +             && RC->Pcie[PCIE_6].Active)
> +  {
> +    RC->DefaultDevMapHi = 1;
> +  } else {
> +    RC->DefaultDevMapHi = 0;
> +  }
> +
> +  if (RC->DevMapLo == 0) {
> +    RC->DevMapLo = RC->DefaultDevMapLo;
> +  }
> +
> +  if (RC->Type == RCB && RC->DevMapHi == 0) {
> +    RC->DevMapHi = RC->DefaultDevMapHi;
> +  }
> +
> +  PcieBoardSetRCBifur (RC, PCIE_0, RC->DevMapLo);
> +  if (RC->Type == RCB) {
> +    PcieBoardSetRCBifur (RC, PCIE_4, RC->DevMapHi);
> +  }
> +
> +  if (RC->Active) {
> +    if (RC->Type == RCA) {
> +      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCAPDMR, &Val))) {
> +        Val = RCAPCIDEVMAP_SET (Val, RC->DevMapLo & 0x7);

Is this actively trying to obscure away runtime errors, or
are there valid situations where RC->DevMapLo may be higher than 7
and only the bottom 3 bits should be respected?
If so, a comment should explain.

> +        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCAPDMR, Val);
> +      }
> +    } else {
> +      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCBPDMR, &Val))) {
> +        Val = RCBPCIDEVMAPLO_SET (Val, RC->DevMapLo & 0x7);
> +        Val = RCBPCIDEVMAPHI_SET (Val, RC->DevMapHi & 0x7);

Is this actively trying to obscure away runtime errors, or
are there valid situations where RC->DevMapLo or RC->DevMapHi may be
higher than 7 and only the bottom 3 bits should be respected?
If so, a comment should explain.

> +        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCBPDMR, Val);
> +      }
> +    }
> +  }
> +}
> +
> +VOID
> +PcieBoardGetSpeed (
> +  IN AC01_RC *RC
> +  )
> +{
> +  UINT8 MaxGenTbl[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN4, SPEED_GEN4 };         // Bifurcation 0: RCA x16 / RCB x8
> +  UINT8 MaxGenTblX8X4X4[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN1, SPEED_GEN1 };   // Bifurcation 2: x8 x4 x4 (PCIE_ERRATA_SPEED1)
> +  UINT8 MaxGenTblX4X4X4X4[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 }; // Bifurcation 3: x4 x4 x4 x4 (PCIE_ERRATA_SPEED1)
> +  UINT8 MaxGenTblRCB[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 };      // RCB PCIE_ERRATA_SPEED1
> +  INTN  RPIdx;
> +  UINT8 *MaxGen;
> +
> +  ASSERT (MAX_PCIE_A == 4);
> +  ASSERT (MAX_PCIE == 8);
> +
> +  //
> +  // Due to hardware errata, for A0/A1*
> +  //  RCB is limited to Gen1 speed.
> +  //  RCA x16, x8 port supports up to Gen4,
> +  //  RCA x4 port only supports Gen1.
> +  //
> +  MaxGen = MaxGenTbl;
> +  if (RC->Type == RCB) {
> +    if (RC->Flags & PCIE_ERRATA_SPEED1) {
> +      MaxGen = MaxGenTblRCB;
> +    }
> +  } else {
> +    switch (RC->DevMapLo) {
> +    case 2: /* x8 x4 x4 */

#define for these 2, 3, and 1.

> +      if (RC->Flags & PCIE_ERRATA_SPEED1) {
> +        MaxGen = MaxGenTblX8X4X4;
> +      }
> +      break;
> +
> +    case 3: /* X4 x4 x4 x4 */
> +      if (RC->Flags & PCIE_ERRATA_SPEED1) {
> +        MaxGen = MaxGenTblX4X4X4X4;
> +      }
> +      break;
> +
> +    case 1: /* x8 x8 */
> +    default:
> +      break;
> +    }
> +  }
> +
> +  for (RPIdx = 0; RPIdx < MAX_PCIE_A; RPIdx++) {
> +    RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : 0;
> +  }
> +
> +  if (RC->Type == RCB) {
> +    for (RPIdx = MAX_PCIE_A; RPIdx < MAX_PCIE; RPIdx++) {
> +      RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ?
> +                               MaxGen[RPIdx - MAX_PCIE_A] : 0;
> +    }
> +  }
> +}
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
> new file mode 100644
> index 000000000000..309cc8857b8c
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
> @@ -0,0 +1,1120 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PcieBoardLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <NVParamDef.h>
> +#include <Pcie.h>
> +#include <PlatformInfoHob.h>
> +
> +#include "PcieBoardScreen.h"
> +
> +#ifndef BIT
> +#define BIT(nr) (1 << (nr))
> +#endif
> +
> +#define MAX_STRING_SIZE     32
> +
> +CHAR16   VariableName[]     = PCIE_VARSTORE_NAME;
> +EFI_GUID gPcieFormSetGuid   = PCIE_FORM_SET_GUID;
> +
> +EFI_HANDLE               DriverHandle = NULL;
> +PCIE_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
> +
> +AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX];
> +
> +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    PCIE_FORM_SET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Request,
> +  OUT      EFI_STRING                     *Progress,
> +  OUT      EFI_STRING                     *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  CHAR16                          *StrPointer;
> +  BOOLEAN                         AllocatedRequest;
> +  PCIE_VARSTORE_DATA              *VarStoreConfig;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  //
> +  // Get Buffer Storage data from EFI variable.
> +  // Try to get the current setting from variable.
> +  //
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  VariableName,
> +                  &gPcieFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  VarStoreConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (Request == NULL) {
> +    //
> +    // Request is set to NULL, construct full request string.
> +    //
> +
> +    //
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
> +    // Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (
> +                         &gPcieFormSetGuid,
> +                         VariableName,
> +                         PrivateData->DriverHandle
> +                         );
> +    if (ConfigRequestHdr == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (
> +      ConfigRequest,
> +      Size,
> +      L"%s&OFFSET=0&WIDTH=%016LX",
> +      ConfigRequestHdr,
> +      (UINT64)BufferSize
> +      );
> +    FreePool (ConfigRequestHdr);
> +    ConfigRequestHdr = NULL;
> +  } else {
> +    //
> +    // Check routing data in <ConfigHdr>.
> +    // Note: if only one Storage is used, then this checking could be skipped.
> +    //
> +    if (!HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, NULL)) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    //
> +    // Set Request to the unified request string.
> +    //
> +    ConfigRequest = Request;
> +
> +    //
> +    // Check whether Request includes Request Element.
> +    //
> +    if (StrStr (Request, L"OFFSET") == NULL) {
> +      //
> +      // Check Request Element does exist in Request String
> +      //
> +      StrPointer = StrStr (Request, L"PATH");
> +      if (StrPointer == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +      if (StrStr (StrPointer, L"&") == NULL) {
> +        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);

What is 32?

> +        ConfigRequest    = AllocateZeroPool (Size);
> +        ASSERT (ConfigRequest != NULL);
> +        AllocatedRequest = TRUE;
> +        UnicodeSPrint (
> +          ConfigRequest,
> +          Size,
> +          L"%s&OFFSET=0&WIDTH=%016LX",
> +          Request,
> +          (UINT64)BufferSize
> +          );
> +      }
> +    }
> +  }
> +
> +  //
> +  // Check if requesting Name/Value storage
> +  //
> +  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    Status = EFI_SUCCESS;
> +  } else {
> +    //
> +    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +    //
> +    Status = HiiConfigRouting->BlockToConfig (
> +                                 HiiConfigRouting,
> +                                 ConfigRequest,
> +                                 (UINT8 *)VarStoreConfig,
> +                                 BufferSize,
> +                                 Results,
> +                                 Progress
> +                                 );
> +  }
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +  }
> +
> +  if (ConfigRequestHdr != NULL) {
> +    FreePool (ConfigRequestHdr);
> +  }
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Configuration,
> +  OUT      EFI_STRING                     *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  PCIE_VARSTORE_DATA              *VarStoreConfig;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, NULL)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get Buffer Storage data from EFI variable
> +  //
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  VariableName,
> +                  &gPcieFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  VarStoreConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Check if configuring Name/Value storage
> +  //
> +  if (StrStr (Configuration, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)VarStoreConfig,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store Buffer Storage back to variable
> +  //
> +  Status = gRT->SetVariable (
> +                  VariableName,
> +                  &gPcieFormSetGuid,
> +                  EFI_VARIABLE_NON_VOLATILE |
> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                  EFI_VARIABLE_RUNTIME_ACCESS,
> +                  sizeof (PCIE_VARSTORE_DATA),
> +                  VarStoreConfig
> +                  );
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +  @retval EFI_SUCCESS            The callback successfully handled the action.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
> +                                 variable and its data.
> +  @retval EFI_DEVICE_ERROR       The variable could not be saved.
> +  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
> +                                 callback.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  PCIE_VARSTORE_DATA       *VarStoreConfig;
> +  PCIE_SCREEN_PRIVATE_DATA *PrivateData;
> +  EFI_STATUS               Status;
> +
> +  if (((Value == NULL) &&
> +       (Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
> +       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
> +      (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  Status = EFI_SUCCESS;
> +
> +  switch (Action) {
> +  case EFI_BROWSER_ACTION_FORM_OPEN:
> +    break;
> +
> +  case EFI_BROWSER_ACTION_FORM_CLOSE:
> +    break;
> +
> +  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
> +  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
> +    if (QuestionId == 0x9000) {
> +      /* SMMU PMU */
> +      Value->u32 = 0; /* default disable */
> +      break;
> +    }
> +
> +    switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) {
> +    case 0:
> +      Value->u8 = PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
> +      break;
> +
> +    case 1:
> +      Value->u8 = PcieRCDevMapLoDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
> +      break;
> +
> +    case 2:
> +      Value->u8 = PcieRCDevMapHiDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
> +      break;
> +    }
> +    break;
> +
> +  case EFI_BROWSER_ACTION_RETRIEVE:
> +  case EFI_BROWSER_ACTION_CHANGING:
> +  case EFI_BROWSER_ACTION_SUBMITTED:
> +    break;
> +
> +  default:
> +    Status = EFI_UNSUPPORTED;
> +    break;
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +PcieScreenUnload (
> +  IN EFI_HANDLE ImageHandle
> +  )
> +{
> +  ASSERT (mPrivateData != NULL);
> +
> +  if (DriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           DriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    DriverHandle = NULL;
> +  }
> +
> +  if (mPrivateData->HiiHandle != NULL) {
> +    HiiRemovePackages (mPrivateData->HiiHandle);
> +  }
> +
> +  FreePool (mPrivateData);
> +  mPrivateData = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function return default settings for Dev Map LO.
> +  @param  RC                     Root Complex ID.
> +  @param  PrivateData            Private data.
> +
> +  @retval Default dev settings.
> +**/
> +UINT8
> +PcieRCDevMapLoDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  AC01_RC *RC = &RCList[RCIndex];
> +
> +  return RC->DefaultDevMapLo;
> +}
> +
> +/**
> +  This function return default settings for Dev Map HI.
> +  @param  RC                     Root Complex ID.
> +  @param  PrivateData            Private data.
> +
> +  @retval Default dev settings.
> +**/
> +UINT8
> +PcieRCDevMapHiDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  AC01_RC *RC = &RCList[RCIndex];
> +
> +  return RC->DefaultDevMapHi;
> +}
> +
> +BOOLEAN
> +PcieRCActiveDefaultSetting (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  VOID               *Hob;
> +  UINT32             Efuse;
> +
> +  // FIXME: Disable Root Complex 6 (USB and VGA) as default

Please get rid of the FIXME

> +  if (RCIndex == 6) {
> +    return FALSE;
> +  }
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob != NULL) {
> +    PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +    Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
> +    return (!(Efuse & BIT (RCIndex))) ? TRUE : FALSE;
> +  }
> +
> +  return FALSE;
> +}
> +
> +/**
> +  This function sets up the first elements of the form.
> +  @param  RC                     Root Complex ID.
> +  @param  PrivateData            Private data.
> +  @retval EFI_SUCCESS            The form is set up successfully.
> +**/
> +EFI_STATUS
> +PcieRCScreenSetup (
> +  IN UINTN                    RCIndex,
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  VOID               *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +  VOID               *OptionsOpCodeHandle;
> +  VOID               *OptionsHiOpCodeHandle;
> +  CHAR16             Str[MAX_STRING_SIZE];
> +  UINT16             DisabledStatusVarOffset;
> +  UINT16             BifurLoVarOffset;
> +  UINT16             BifurHiVarOffset;
> +  UINT8              QuestionFlags, QuestionFlagsSubItem;
> +  AC01_RC            *RC;
> +
> +  RC = &RCList[RCIndex];
> +
> +  // Initialize the container for dynamic opcodes
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  // Create Hii Extend Label OpCode as the start opcode
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_RC0_UPDATE + 2 * RCIndex;
> +
> +  // Create Hii Extend Label OpCode as the end opcode
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_RC0_END + 2 * RCIndex;
> +
> +  // Create textbox to tell socket
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_PCIE_SOCKET),
> +    STRING_TOKEN (STR_PCIE_SOCKET_HELP),
> +    HiiSetString (
> +      PrivateData->HiiHandle,
> +      0,
> +      (RC->Socket) ? L"1" : L"0",
> +      NULL
> +      )
> +    );
> +
> +  // Create textbox to tell Root Complex type
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_PCIE_RC_TYPE),
> +    STRING_TOKEN (STR_PCIE_RC_TYPE_HELP),
> +    HiiSetString (
> +      PrivateData->HiiHandle,
> +      0,
> +      (RC->Type == RCA) ? L"Root Complex Type-A" : L"Root Complex Type-B",
> +      NULL
> +      )
> +    );
> +
> +  UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RCIndex);
> +
> +  DisabledStatusVarOffset = (UINT16)PCIE_RC0_STATUS_OFFSET +
> +                            sizeof (BOOLEAN) * RCIndex;
> +  BifurLoVarOffset = (UINT16)PCIE_RC0_BIFUR_LO_OFFSET +
> +                     sizeof (UINT8) * RCIndex;
> +  BifurHiVarOffset = (UINT16)PCIE_RC0_BIFUR_HI_OFFSET +
> +                     sizeof (UINT8) * RCIndex;
> +
> +  QuestionFlags = EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_CALLBACK;
> +  if (IsEmptyRC (RC)
> +      || (GetNumberOfActiveSockets () == 1 && RC->Socket == 1))
> +  {
> +    //
> +    // Do not allow changing if none of Root Port underneath enabled
> +    // or slave Root Complex on 1P system.
> +    //
> +    QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
> +  }
> +  // Create the RC disabled checkbox
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                        // Container for dynamic created opcodes
> +    0x8002 + MAX_EDITABLE_ELEMENTS * RCIndex, // QuestionId (or "key")
> +    PCIE_VARSTORE_ID,                         // VarStoreId
> +    DisabledStatusVarOffset,                  // VarOffset in Buffer Storage
> +    HiiSetString (
> +      PrivateData->HiiHandle,
> +      0,
> +      Str,
> +      NULL
> +      ),                                       // Prompt
> +    STRING_TOKEN (STR_PCIE_RC_STATUS_HELP),    // Help
> +    QuestionFlags,                             // QuestionFlags
> +    0,                                         // CheckBoxFlags
> +    NULL                                       // DefaultsOpCodeHandle
> +    );
> +
> +  if (RC->Type == RCA) {
> +    // Create Option OpCode to display bifurcation for RCA
> +    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
> +    ASSERT (OptionsOpCodeHandle != NULL);
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE0),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      0 // Devmap=0
> +      );
> +
> +
> +    if (RC->DefaultDevMapLo != 0) {
> +      QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
> +    }
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE1),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      1 // Devmap=1
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE2),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      2 // Devmap=2
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE3),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      3 // Devmap=3
> +      );
> +
> +    HiiCreateOneOfOpCode (
> +      StartOpCodeHandle,                        // Container for dynamic created opcodes
> +      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key")
> +      PCIE_VARSTORE_ID,                         // VarStore ID
> +      BifurLoVarOffset,                         // Offset in Buffer Storage
> +      STRING_TOKEN (STR_PCIE_RCA_BIFUR),        // Question prompt text
> +      STRING_TOKEN (STR_PCIE_RCA_BIFUR_HELP),   // Question help text
> +      QuestionFlags,                            // Question flag
> +      EFI_IFR_NUMERIC_SIZE_1,                   // Data type of Question Value
> +      OptionsOpCodeHandle,                      // Option Opcode list
> +      NULL                                      // Default Opcode is NULl
> +      );
> +  } else {
> +    // Create Option OpCode to display bifurcation for RCB-Lo
> +    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
> +    ASSERT (OptionsOpCodeHandle != NULL);
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      0 // Devmap=0
> +      );
> +
> +    QuestionFlagsSubItem = QuestionFlags;
> +    if (RC->DefaultDevMapLo != 0) {
> +      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
> +    }
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      1 // Devmap=1
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      2 // Devmap=2
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      3 // Devmap=3
> +      );
> +
> +    HiiCreateOneOfOpCode (
> +      StartOpCodeHandle,                         // Container for dynamic created opcodes
> +      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
> +      PCIE_VARSTORE_ID,                          // VarStore ID
> +      BifurLoVarOffset,                          // Offset in Buffer Storage
> +      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR),      // Question prompt text
> +      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR_HELP), // Question help text
> +      QuestionFlagsSubItem,                      // Question flag
> +      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
> +      OptionsOpCodeHandle,                       // Option Opcode list
> +      NULL                                       // Default Opcode is NULl
> +      );
> +
> +    // Create Option OpCode to display bifurcation for RCB-Hi
> +    OptionsHiOpCodeHandle = HiiAllocateOpCodeHandle ();
> +    ASSERT (OptionsHiOpCodeHandle != NULL);
> +
> +    QuestionFlagsSubItem = QuestionFlags;
> +    if (RC->DefaultDevMapHi != 0) {
> +      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
> +    }
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsHiOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      0 // Devmap=0
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsHiOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      1 // Devmap=1
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsHiOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      2 // Devmap=2
> +      );
> +
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsHiOpCodeHandle,
> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      3 // Devmap=3
> +      );
> +
> +    HiiCreateOneOfOpCode (
> +      StartOpCodeHandle,                         // Container for dynamic created opcodes
> +      0x8004 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
> +      PCIE_VARSTORE_ID,                          // VarStore ID
> +      BifurHiVarOffset,                          // Offset in Buffer Storage
> +      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR),      // Question prompt text
> +      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR_HELP), // Question help text
> +      QuestionFlagsSubItem,                      // Question flag
> +      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
> +      OptionsHiOpCodeHandle,                     // Option Opcode list
> +      NULL                                       // Default Opcode is NULl
> +      );
> +  }
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,     // HII handle
> +    &gPcieFormSetGuid,          // Formset GUID
> +    PCIE_RC0_FORM_ID + RCIndex, // Form ID
> +    StartOpCodeHandle,          // Label for where to insert opcodes
> +    EndOpCodeHandle             // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function sets up the first elements of the form.
> +  @param  PrivateData            Private data.
> +  @retval EFI_SUCCESS            The form is set up successfully.
> +**/
> +EFI_STATUS
> +PcieMainScreenSetup (
> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  VOID                 *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL   *StartLabel;
> +  VOID                 *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL   *EndLabel;
> +  CHAR16               Str[MAX_STRING_SIZE];
> +  UINTN                RC;
> +  PCIE_SETUP_GOTO_DATA *GotoItem = NULL;
> +  EFI_QUESTION_ID      GotoId;
> +
> +  // Initialize the container for dynamic opcodes
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  // Create Hii Extend Label OpCode as the start opcode
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  // Create Hii Extend Label OpCode as the end opcode
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                       // Container for dynamic created opcodes
> +    0x9000,                                  // Question ID
> +    PCIE_VARSTORE_ID,                        // VarStore ID
> +    (UINT16)PCIE_SMMU_PMU_OFFSET,            // Offset in Buffer Storage
> +    STRING_TOKEN (STR_PCIE_SMMU_PMU_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_PCIE_SMMU_PMU_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  //
> +  // Create the a seperated line
> +  //
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE)
> +    );
> +
> +  // Create Goto form for each RC
> +  for (RC = 0; RC < MAX_AC01_PCIE_ROOT_COMPLEX; RC++) {
> +
> +    GotoItem = AllocateZeroPool (sizeof (PCIE_SETUP_GOTO_DATA));
> +    if (GotoItem == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    GotoItem->PciDevIdx = RC;
> +
> +    GotoId = PCIE_GOTO_ID_BASE + (UINT16)RC;
> +
> +    // Update HII string
> +    UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RC);
> +    GotoItem->GotoStringId = HiiSetString (
> +                               PrivateData->HiiHandle,
> +                               0,
> +                               Str,
> +                               NULL
> +                               );
> +    GotoItem->GotoHelpStringId = STRING_TOKEN (STR_PCIE_GOTO_HELP);
> +    GotoItem->ShowItem = TRUE;
> +
> +    // Add goto control
> +    HiiCreateGotoOpCode (
> +      StartOpCodeHandle,
> +      PCIE_RC0_FORM_ID + RC,
> +      GotoItem->GotoStringId,
> +      GotoItem->GotoHelpStringId,
> +      EFI_IFR_FLAG_CALLBACK,
> +      GotoId
> +      );
> +  }
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,  // HII handle
> +    &gPcieFormSetGuid,       // Formset GUID
> +    PCIE_FORM_ID,            // Form ID
> +    StartOpCodeHandle,       // Label for where to insert opcodes
> +    EndOpCodeHandle          // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +PcieBoardScreenInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable,
> +  IN AC01_RC          *NewRCList
> +  )
> +{
> +  EFI_STATUS                          Status;
> +  EFI_HII_HANDLE                      HiiHandle;
> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
> +  EFI_HII_STRING_PROTOCOL             *HiiString;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
> +  UINTN                               BufferSize;
> +  BOOLEAN                             IsUpdated;
> +  PCIE_VARSTORE_DATA                  *VarStoreConfig;
> +  UINT8                               RCIndex;
> +  AC01_RC                             *RC;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (PCIE_SCREEN_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = PCIE_SCREEN_PRIVATE_DATA_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
> +  mPrivateData->ConfigAccess.Callback = DriverCallback;
> +
> +  //
> +  // Locate Hii Database protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiDatabaseProtocolGuid,
> +                  NULL,
> +                  (VOID **)&HiiDatabase
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiDatabase = HiiDatabase;
> +
> +  //
> +  // Locate HiiString protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiStringProtocolGuid,
> +                  NULL,
> +                  (VOID **)&HiiString
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiString = HiiString;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiConfigRoutingProtocolGuid,
> +                  NULL,
> +                  (VOID **)&HiiConfigRouting
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  //
> +  // Locate keyword handler protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiConfigKeywordHandlerProtocolGuid,
> +                  NULL,
> +                  (VOID **)&HiiKeywordHandler
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiKeywordHandler = HiiKeywordHandler;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = DriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gPcieFormSetGuid,
> +                DriverHandle,
> +                PcieBoardLibStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  // Make a shadow copy all Root Complexes' properties
> +  CopyMem ((VOID *)RCList, (VOID *)NewRCList, sizeof (RCList));
> +
> +  //
> +  // Initialize efi varstore configuration data
> +  //
> +  VarStoreConfig = &mPrivateData->VarStoreConfig;
> +  ZeroMem (VarStoreConfig, sizeof (PCIE_VARSTORE_DATA));
> +
> +  // Get Buffer Storage data from EFI variable
> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  VariableName,
> +                  &gPcieFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  VarStoreConfig
> +                  );
> +
> +  IsUpdated = FALSE;
> +
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->SmmuPmu = 0; /* Disable by default */
> +    IsUpdated = TRUE;
> +  }
> +  // Update board settings to menu
> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +    RC = &RCList[RCIndex];
> +
> +    if (EFI_ERROR (Status)) {
> +      VarStoreConfig->RCBifurLo[RCIndex] = RC->DevMapLo;
> +      VarStoreConfig->RCBifurHi[RCIndex] = RC->DevMapHi;
> +      VarStoreConfig->RCStatus[RCIndex] = RC->Active;
> +      IsUpdated = TRUE;
> +    }
> +    // FIXME: Disable Root Complex 6 (USB and VGA) as default

Please get rid of the FIXME.

/
    Leif

> +    if (EFI_ERROR (Status) && RCIndex == 6) {
> +      VarStoreConfig->RCStatus[RCIndex] = 0;
> +    }
> +  }
> +
> +  if (IsUpdated) {
> +    // Update Buffer Storage
> +    Status = gRT->SetVariable (
> +                    VariableName,
> +                    &gPcieFormSetGuid,
> +                    EFI_VARIABLE_NON_VOLATILE |
> +                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                    EFI_VARIABLE_RUNTIME_ACCESS,
> +                    sizeof (PCIE_VARSTORE_DATA),
> +                    VarStoreConfig
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +  Status = PcieMainScreenSetup (mPrivateData);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
> +    Status = PcieRCScreenSetup (RCIndex, mPrivateData);
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
> new file mode 100644
> index 000000000000..776eaa476787
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
> @@ -0,0 +1,99 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US "English"
> +
> +#string STR_PCIE_FORM                   #language en-US "PCIE Root Complex Configuration"
> +#string STR_PCIE_FORM_HELP              #language en-US "Configure Root Complex"
> +
> +#string STR_PCIE_FORM_SEPERATE_LINE     #language en-US ""
> +
> +/////
> +
> +#string STR_PCIE_GOTO                   #language en-US ""
> +#string STR_PCIE_GOTO_HELP              #language en-US "Change On Board Root Complex Settings."
> +
> +#string STR_PCIE_RC_STATUS              #language en-US ""
> +#string STR_PCIE_RC_STATUS_HELP         #language en-US "Enable / Disable Root Complex"
> +
> +#string STR_PCIE_RCA_BIFUR              #language en-US "Bifurcation x16"
> +#string STR_PCIE_RCA_BIFUR_HELP         #language en-US "Set bifurcation mode for x16 Root Complex Type-A"
> +
> +#string STR_PCIE_RCB_LO_BIFUR           #language en-US "Bifurcation 1st x8"
> +#string STR_PCIE_RCB_LO_BIFUR_HELP      #language en-US "Set bifurcation mode for 1st x8 Root Complex Type-B"
> +
> +#string STR_PCIE_RCB_HI_BIFUR           #language en-US "Bifurcation 2nd x8"
> +#string STR_PCIE_RCB_HI_BIFUR_HELP      #language en-US "Set bifurcation mode for 2nd x8 Root Complex Type-B"
> +
> +/////
> +
> +#string STR_PCIE_RC0_FORM               #language en-US "Root Complex 0 Configuration"
> +#string STR_PCIE_RC0_FORM_HELP          #language en-US "Root Complex 0 Configuration"
> +
> +#string STR_PCIE_RC1_FORM               #language en-US "Root Complex 1 Configuration"
> +#string STR_PCIE_RC1_FORM_HELP          #language en-US "Root Complex 1 Configuration"
> +
> +#string STR_PCIE_RC2_FORM               #language en-US "Root Complex 2 Configuration"
> +#string STR_PCIE_RC2_FORM_HELP          #language en-US "Root Complex 2 Configuration"
> +
> +#string STR_PCIE_RC3_FORM               #language en-US "Root Complex 3 Configuration"
> +#string STR_PCIE_RC3_FORM_HELP          #language en-US "Root Complex 3 Configuration"
> +
> +#string STR_PCIE_RC4_FORM               #language en-US "Root Complex 4 Configuration"
> +#string STR_PCIE_RC4_FORM_HELP          #language en-US "Root Complex 4 Configuration"
> +
> +#string STR_PCIE_RC5_FORM               #language en-US "Root Complex 5 Configuration"
> +#string STR_PCIE_RC5_FORM_HELP          #language en-US "Root Complex 5 Configuration"
> +
> +#string STR_PCIE_RC6_FORM               #language en-US "Root Complex 6 Configuration"
> +#string STR_PCIE_RC6_FORM_HELP          #language en-US "Root Complex 6 Configuration"
> +
> +#string STR_PCIE_RC7_FORM               #language en-US "Root Complex 7 Configuration"
> +#string STR_PCIE_RC7_FORM_HELP          #language en-US "Root Complex 7 Configuration"
> +
> +#string STR_PCIE_RC8_FORM               #language en-US "Root Complex 8 Configuration"
> +#string STR_PCIE_RC8_FORM_HELP          #language en-US "Root Complex 8 Configuration"
> +
> +#string STR_PCIE_RC9_FORM               #language en-US "Root Complex 9 Configuration"
> +#string STR_PCIE_RC9_FORM_HELP          #language en-US "Root Complex 9 Configuration"
> +
> +#string STR_PCIE_RC10_FORM              #language en-US "Root Complex 10 Configuration"
> +#string STR_PCIE_RC10_FORM_HELP         #language en-US "Root Complex 10 Configuration"
> +
> +#string STR_PCIE_RC11_FORM              #language en-US "Root Complex 11 Configuration"
> +#string STR_PCIE_RC11_FORM_HELP         #language en-US "Root Complex 11 Configuration"
> +
> +#string STR_PCIE_RC12_FORM              #language en-US "Root Complex 12 Configuration"
> +#string STR_PCIE_RC12_FORM_HELP         #language en-US "Root Complex 12 Configuration"
> +
> +#string STR_PCIE_RC13_FORM              #language en-US "Root Complex 13 Configuration"
> +#string STR_PCIE_RC13_FORM_HELP         #language en-US "Root Complex 13 Configuration"
> +
> +#string STR_PCIE_RC14_FORM              #language en-US "Root Complex 14 Configuration"
> +#string STR_PCIE_RC14_FORM_HELP         #language en-US "Root Complex 14 Configuration"
> +
> +#string STR_PCIE_RC15_FORM              #language en-US "Root Complex 15 Configuration"
> +#string STR_PCIE_RC15_FORM_HELP         #language en-US "Root Complex 15 Configuration"
> +
> +#string STR_PCIE_BIFUR_SELECT_VALUE0    #language en-US "x16"
> +#string STR_PCIE_BIFUR_SELECT_VALUE1    #language en-US "x8+x8"
> +#string STR_PCIE_BIFUR_SELECT_VALUE2    #language en-US "x8+x4+x4"
> +#string STR_PCIE_BIFUR_SELECT_VALUE3    #language en-US "x4+x4+x4+x4"
> +#string STR_PCIE_BIFUR_SELECT_VALUE4    #language en-US "x8"
> +#string STR_PCIE_BIFUR_SELECT_VALUE5    #language en-US "x4+x4"
> +#string STR_PCIE_BIFUR_SELECT_VALUE6    #language en-US "x4+x2+x2"
> +#string STR_PCIE_BIFUR_SELECT_VALUE7    #language en-US "x2+x2+x2+x2"
> +
> +#string STR_PCIE_SOCKET                 #language en-US "Socket"
> +#string STR_PCIE_SOCKET_HELP            #language en-US "Socket 0 - Master; Socket 1 - Slave"
> +#string STR_PCIE_SOCKET_VALUE           #language en-US ""
> +
> +#string STR_PCIE_RC_TYPE                #language en-US "Type"
> +#string STR_PCIE_RC_TYPE_HELP           #language en-US "Type-A: x16 lanes bifurcated down to x4; Type-B: 2 of x8 lanes, each bifurcated down to x2"
> +#string STR_PCIE_RC_TYPE_VALUE          #language en-US ""
> +
> +#string STR_PCIE_SMMU_PMU_PROMPT        #language en-US "SMMU Pmu"
> +#string STR_PCIE_SMMU_PMU_HELP          #language en-US "Enable/Disable PMU feature for SMMU"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
@ 2021-06-07 22:51   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 22:51 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:09 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This change also enables the support for SCSI, NVMe, USB keyboard, and
> USB storage devices.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 34 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/Jade.dsc                     |  5 +++
>  Platform/Ampere/JadePkg/Jade.fdf                     | 33 +++++++++++++++++++
>  3 files changed, 72 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index fc8e0b40ee19..33f5fe7af544 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -83,6 +83,7 @@ [LibraryClasses.common]
>    NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
>    MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
>    SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
> +  PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf
>    PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
>    AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>    TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
> @@ -648,6 +649,39 @@ [Components.common]
>    MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
>    FatPkg/EnhancedFatDxe/Fat.inf
>  
> +  #
> +  # SCSI Bus and Disk Driver
> +  #
> +  MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +
> +  #
> +  # SATA Support
> +  #
> +  MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +  MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> +  MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
> +
> +  #
> +  # NVME Support
> +  #
> +  MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
> +  #
> +  # USB Support
> +  #
> +  MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +  #
> +  # PCIe Support
> +  #
> +  MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
>    #
>    # Bds
>    #
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 0f9d0adbd34e..576e1c3ab663 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -88,6 +88,11 @@ [LibraryClasses]
>    AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
>    AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
>  
> +  #
> +  # Pcie Board
> +  #
> +  PcieBoardLib|Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
> +
>  ################################################################################
>  #
>  # Specific Platform Pcds
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 2c6f9fac76fd..fc47556b072b 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -266,6 +266,39 @@ [FV.FvMain]
>    INF FatPkg/EnhancedFatDxe/Fat.inf
>    INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
>  
> +  #
> +  # SCSI Bus and Disk Driver
> +  #
> +  INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf
> +  INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf
> +
> +  #
> +  # SATA Support
> +  #
> +  INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf
> +  INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf
> +  INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf
> +  INF MdeModulePkg/Bus/Pci/NonDiscoverablePciDeviceDxe/NonDiscoverablePciDeviceDxe.inf
> +
> +  #
> +  # NVME Support
> +  #
> +  INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf
> +
> +  #
> +  # USB Support
> +  #
> +  INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf
> +  INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
> +
> +  #
> +  # PCIe Support
> +  #
> +  INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
>    #
>    # UEFI application (Shell Embedded Boot Loader)
>    #
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
@ 2021-06-07 22:51   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 22:51 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:10 +0700, Nhi Pham wrote:
> This wires up the pre-built binary placed in the edk2-non-osi
> repository for PCIe VGA Controller support.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Platform/Ampere/JadePkg/Jade.dsc | 12 ++++++++++++
>  Platform/Ampere/JadePkg/Jade.fdf |  5 +++++
>  2 files changed, 17 insertions(+)
> 
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 576e1c3ab663..6aaa644ad298 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -115,6 +115,13 @@ [PcdsFixedAtBuild.common]
>  !endif
>  
>  
> +[PcdsPatchableInModule]
> +  #
> +  # Console Resolution (HD mode)
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1024
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|768
> +
>  ################################################################################
>  #
>  # Specific Platform Component
> @@ -136,3 +143,8 @@ [Components.common]
>    Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>    Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> +
> +  #
> +  # VGA Aspeed
> +  #
> +  Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index fc47556b072b..6820a197568b 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -299,6 +299,11 @@ [FV.FvMain]
>    INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  
> +  #
> +  # VGA Aspeed
> +  #
> +  INF Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
> +
>    #
>    # UEFI application (Shell Embedded Boot Loader)
>    #
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
@ 2021-06-07 23:00   ` Leif Lindholm
  2021-06-15 16:51     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:00 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:12 +0700, Nhi Pham wrote:
> From: Quan Nguyen <quan@os.amperecomputing.com>
> 
> This supports various SMBIOS tables type 0, 1, 2, 3, 4, 7, 8, 9, 11,
> 13, 16, 17, 19, 24 and 32.
> 
> SMBIOS Type 1, 2 and 3 are hardcoded as Host-BMC communication is not
> supported yet. And, this module does not support fixup tables to reflect
> changes of the system at booting time.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                    |   12 +
>  Platform/Ampere/JadePkg/Jade.dsc                                        |   26 +
>  Platform/Ampere/JadePkg/Jade.fdf                                        |    8 +
>  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf           |   45 +
>  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf   |   45 +
>  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   52 +
>  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c             |  709 +++++++++++++
>  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c     |  705 +++++++++++++
>  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c   | 1049 ++++++++++++++++++++
>  9 files changed, 2651 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> index 0ac075047276..368136b5342f 100755
> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> @@ -63,11 +63,23 @@ [PcdsFixedAtBuild]
>    gAmpereTokenSpaceGuid.PcdSmproNsMailboxIndex|0x1|UINT32|0x00000003
>    gAmpereTokenSpaceGuid.PcdPmproDbBaseReg|0x100001540000|UINT64|0x00000004
>  
> +  #
> +  # SMBIOS Type 1 Pcd
> +  #
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|0|UINT8|0x00000005
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|0|UINT8|0x00000006
> +
>  [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
>    #
>    # Firmware Volume Pcds
>    #
>    gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
>  
> +  #
> +  # SMBIOS, default or template values
> +  #
> +  # SMBIOS Type 0 - BIOS Information
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"|VOID*|0xB0000002 # Must follow this MM/DD/YYYY SMBIOS date format
> +
>    # NVRam Pcds
>    gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 6aaa644ad298..9c7d7cad4915 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -104,7 +104,22 @@ [PcdsFeatureFlag.common]
>    #
>    gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
>  
> +[PcdsFixedAtBuild]
> +!ifdef $(FIRMWARE_VER)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
> +!endif
> +
>  [PcdsFixedAtBuild.common]
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|$(MAJOR_VER)
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|$(MINOR_VER)
> +
> +  # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
> +  # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
> +  # presence of the 32-bit entry point anyway (because many AARCH64 systems
> +  # don't have 32-bit addressable physical RAM), and the additional allocations
> +  # below 4 GB needlessly fragment the memory map. So expose the 64-bit entry
> +  # point only, for entry point versions >= 3.0.
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
>  
>  !if $(SECURE_BOOT_ENABLE) == TRUE
>    # Override the default values from SecurityPkg to ensure images
> @@ -114,6 +129,9 @@ [PcdsFixedAtBuild.common]
>    gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
>  !endif
>  
> +[PcdsDynamicDefault.common.DEFAULT]
> +  # SMBIOS Type 0 - BIOS Information
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
>  
>  [PcdsPatchableInModule]
>    #
> @@ -148,3 +166,11 @@ [Components.common]
>    # VGA Aspeed
>    #
>    Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
> +
> +  #
> +  # SMBIOS
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index ef24e6f1f8e0..3d5d857178b3 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -340,4 +340,12 @@ [FV.FvMain]
>    INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>    INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>  
> +  #
> +  # SMBIOS
> +  #
> +  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> +
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> new file mode 100644
> index 000000000000..f723ad612a52
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> @@ -0,0 +1,45 @@
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = SmbiosCpuDxe
> +  FILE_GUID                      = 4DD7C2E4-E6A6-11EA-8736-D3C56ABBB5C4
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmbiosCpuDxeEntry
> +
> +[Sources]
> +  SmbiosCpuDxe.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  ArmLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
> +
> +[Guids]
> +  gPlatformHobGuid
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> new file mode 100644
> index 000000000000..87b9123df856
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> @@ -0,0 +1,45 @@
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = SmbiosMemInfoDxe
> +  FILE_GUID                      = ECF38190-EBF8-11EA-B646-830715BDF83A
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmbiosMemInfoDxeEntry
> +
> +[Sources]
> +  SmbiosMemInfoDxe.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  ArmLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
> +
> +[Guids]
> +  gPlatformHobGuid
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> new file mode 100755
> index 000000000000..73a601b0df08
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> @@ -0,0 +1,52 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = SmbiosPlatformDxe
> +  FILE_GUID                      = F0CC7D0B-CD83-4DDA-A5D4-613AB02D4E52
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = SmbiosPlatformDxeEntry
> +
> +[Sources]
> +  SmbiosPlatformDxe.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  HobLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
> +
> +[Pcd]
> +  # Type 0
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion
> +
> +  gArmTokenSpaceGuid.PcdFdSize
> +
> +[Guids]
> +  gPlatformHobGuid
> +
> +[Depex]
> +  gEfiSmbiosProtocolGuid
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
> new file mode 100644
> index 000000000000..659212a2cc90
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
> @@ -0,0 +1,709 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Guid/SmBios.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/ArmLib/ArmLibPrivate.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/Smbios.h>
> +
> +#define CPU_CACHE_LEVEL_MAX 3
> +
> +#define MHZ_SCALE_FACTOR 1000000
> +
> +#define CACHE_SIZE(x)   (UINT16) (0x8000 | (x) >> 16)
> +#define CACHE_SIZE_2(x) (0x80000000 | (x) >> 16)
> +
> +#define TYPE4_ADDITIONAL_STRINGS                                  \
> +  "SOCKET 0\0"                       /* socket type */            \
> +  "Ampere(R)\0"                      /* manufacturer */           \
> +  "Ampere(R) Altra(R) Processor\0"   /* processor description */  \
> +  "NotSet\0"                         /* part number */
> +
> +#define TYPE7_ADDITIONAL_STRINGS                                  \
> +  "L1 Cache\0" /* L1 Cache  */
> +
> +//
> +// Type definition and contents of the default SMBIOS table.
> +// This table covers only the minimum structures required by
> +// the SMBIOS specification (section 6.2, version 3.0)
> +//
> +#pragma pack(1)
> +typedef struct {
> +  SMBIOS_TABLE_TYPE4 Base;
> +  CHAR8              Strings[sizeof (TYPE4_ADDITIONAL_STRINGS)];
> +} ARM_TYPE4;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE7 Base;
> +  CHAR8              Strings[sizeof (TYPE7_ADDITIONAL_STRINGS)];
> +} ARM_TYPE7;
> +
> +#pragma pack()
> +//-------------------------------------
> +//        SMBIOS Platform Common
> +//-------------------------------------
> +enum {
> +  ADDITIONAL_STR_INDEX_1 = 1,
> +  ADDITIONAL_STR_INDEX_2,
> +  ADDITIONAL_STR_INDEX_3,
> +  ADDITIONAL_STR_INDEX_4,
> +  ADDITIONAL_STR_INDEX_5,
> +  ADDITIONAL_STR_INDEX_6,
> +  ADDITIONAL_STR_INDEX_7,
> +  ADDITIONAL_STR_INDEX_8,
> +  ADDITIONAL_STR_INDEX_9,
> +  ADDITIONAL_STR_INDEX_MAX
> +};
> +
> +// Type 4 Processor Socket 0
> +STATIC ARM_TYPE4 mArmDefaultType4Sk0 = {
> +  {
> +    {                                        // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,          // socket type
> +    3,                               // processor type CPU
> +    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
> +    ADDITIONAL_STR_INDEX_2,          // manufacturer
> +    {{0,},{0.}},                     // processor id
> +    ADDITIONAL_STR_INDEX_3,          // version
> +    {0,0,0,0,0,1},                   // voltage
> +    0,                               // external clock
> +    3000,                            // max speed
> +    3000,                            // current speed
> +    0x41,                            // status
> +    ProcessorUpgradeOther,
> +    0xFFFF,                 // l1 cache handle
> +    0xFFFF,                 // l2 cache handle
> +    0xFFFF,                 // l3 cache handle
> +    0,                      // serial not set
> +    0,                      // asset not set
> +    ADDITIONAL_STR_INDEX_4, // part number
> +    80,                     // core count in socket
> +    80,                     // enabled core count in socket
> +    0,                      // threads per socket
> +    0xEC,                   // processor characteristics
> +    ProcessorFamilyARMv8,   // ARM core
> +  },
> +  TYPE4_ADDITIONAL_STRINGS
> +};
> +
> +// Type 4 Processor Socket 1
> +STATIC ARM_TYPE4 mArmDefaultType4Sk1 = {
> +  {
> +    {                                        // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,          // socket type
> +    3,                               // processor type CPU
> +    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
> +    ADDITIONAL_STR_INDEX_2,          // manufacturer
> +    {{0,},{0.}},                     // processor id
> +    ADDITIONAL_STR_INDEX_3,          // version
> +    {0,0,0,0,0,1},                   // voltage
> +    0,                               // external clock
> +    3000,                            // max speed
> +    3000,                            // current speed
> +    0x41,                            // status
> +    ProcessorUpgradeOther,
> +    0xFFFF,                 // l1 cache handle
> +    0xFFFF,                 // l2 cache handle
> +    0xFFFF,                 // l3 cache handle
> +    0,                      // serial not set
> +    0,                      // asset not set
> +    ADDITIONAL_STR_INDEX_4, // part number
> +    80,                     // core count in socket
> +    80,                     // enabled core count in socket
> +    0,                      // threads per socket
> +    0xEC,                   // processor characteristics
> +    ProcessorFamilyARMv8,   // ARM core
> +  },
> +  TYPE4_ADDITIONAL_STRINGS
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L1 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x180,                  // L1 enabled, Write Back
> +    0x8001,                 // 64k i cache max
> +    0x8001,                 // 64k installed
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    0,                      // unkown speed
> +    CacheErrorParity,       // parity checking
> +    CacheTypeUnified,       // Unified cache
> +    CacheAssociativity4Way, // 4-way
> +  },
> +  "L1 Cache\0"
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L2 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x181,                  // L2 enabled, Write Back
> +    0x8010,                 // 1M cache max
> +    0x8010,                 // 1M installed
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    0,                      // unkown speed
> +    CacheErrorSingleBit,    // single bit ECC
> +    CacheTypeUnified,       // Unified cache
> +    CacheAssociativity8Way, // 8-way
> +  },
> +  "L2 Cache\0"
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L3 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x182,                   // L3 enabled, Write Back
> +    0x8200,                  // 32M cache max
> +    0x8200,                  // 32M installed
> +    {0, 0, 0, 0, 0, 1},      // SRAM type
> +    {0, 0, 0, 0, 0, 1},      // SRAM type
> +    0,                       // unkown speed
> +    CacheErrorParity,        // parity checking
> +    CacheTypeUnified,        // Unified cache
> +    CacheAssociativity16Way, // 16-way
> +  },
> +  "L3 Cache\0"
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L1 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x180,                  // L1 enabled, Write Back
> +    0x8001,                 // 64k i cache max
> +    0x8001,                 // 64k installed
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    0,                      // unkown speed
> +    CacheErrorParity,       // parity checking
> +    CacheTypeUnified,       // Unified cache
> +    CacheAssociativity4Way, // 4-way
> +  },
> +  "L1 Cache\0"
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L2 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x181,                  // L2 enabled, Write Back
> +    0x8010,                 // 1M cache max
> +    0x8010,                 // 1M installed
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    {0, 0, 0, 0, 0, 1},     // SRAM type
> +    0,                      // unkown speed
> +    CacheErrorSingleBit,    // single bit ECC
> +    CacheTypeUnified,       // Unified cache
> +    CacheAssociativity8Way, // 8-way
> +  },
> +  "L2 Cache\0"
> +};
> +
> +// Type 7 Cache Information
> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L3 = {
> +  {
> +    {                                    // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    0x182,                   // L3 enabled, Write Back
> +    0x8200,                  // 32M cache max
> +    0x8200,                  // 32M installed
> +    {0, 0, 0, 0, 0, 1},      // SRAM type
> +    {0, 0, 0, 0, 0, 1},      // SRAM type
> +    0,                       // unkown speed
> +    CacheErrorParity,        // parity checking
> +    CacheTypeUnified,        // Unified cache
> +    CacheAssociativity16Way, // 16-way
> +  },
> +  "L3 Cache\0"
> +};
> +
> +STATIC CONST VOID *DefaultCommonTables[] =
> +{
> +  &mArmDefaultType4Sk0,
> +  &mArmDefaultType4Sk1,
> +  NULL
> +};
> +
> +STATIC CONST VOID *DefaultType7Sk0Tables[] =
> +{
> +  &mArmDefaultType7Sk0L1,
> +  &mArmDefaultType7Sk0L2,
> +  &mArmDefaultType7Sk0L3,
> +  NULL
> +};
> +
> +STATIC CONST VOID *DefaultType7Sk1Tables[] =
> +{
> +  &mArmDefaultType7Sk1L1,
> +  &mArmDefaultType7Sk1L2,
> +  &mArmDefaultType7Sk1L3,
> +  NULL
> +};
> +
> +STATIC
> +UINT32
> +GetCacheConfig (
> +  UINT32 Level
> +  )
> +{
> +  UINT64  Val;
> +  BOOLEAN SupportWB;
> +  BOOLEAN SupportWT;
> +
> +  Val = ReadCCSIDR (Level);
> +  SupportWT = (Val & (1 << 31)) ? TRUE : FALSE;
> +  SupportWB = (Val & (1 << 30)) ? TRUE : FALSE;
> +  if (SupportWT && SupportWB) {
> +    return 2; /* Varies with Memory Address */
> +  }
> +
> +  if (SupportWT) {
> +    return 0;
> +  }
> +
> +  return 1; /* WB */
> +}
> +
> +STATIC
> +UINTN
> +GetStringPackSize (
> +  CHAR8 *StringPack
> +  )
> +{
> +  UINTN StrCount;
> +  CHAR8 *StrStart;
> +
> +  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
> +    return 0;
> +  }
> +
> +  // String section ends in double-null (0000h)
> +  for (StrCount = 0, StrStart = StringPack;
> +       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
> +  {
> +  }
> +
> +  return StrCount + 2; // Included the double NULL
> +}
> +
> +// Update String at String number to String Pack
> +EFI_STATUS
> +UpdateStringPack (
> +  CHAR8 *StringPack,
> +  CHAR8 *String,
> +  UINTN StringNumber
> +  )
> +{
> +  CHAR8 *StrStart;
> +  UINTN StrIndex;
> +  UINTN InputStrLen;
> +  UINTN TargetStrLen;
> +  UINTN BufferSize;
> +  CHAR8 *Buffer;
> +
> +  StrStart = StringPack;
> +  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
> +    // A string ends in 00h
> +    if (*StrStart == 0) {
> +      StrIndex++;
> +    }
> +    // String section ends in double-null (0000h)
> +    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
> +      return EFI_NOT_FOUND;
> +    }
> +  }
> +
> +  if (*StrStart == 0) {
> +    StrStart++;
> +  }
> +
> +  InputStrLen = AsciiStrLen (String);
> +  TargetStrLen = AsciiStrLen (StrStart);
> +  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
> +
> +  // Replace the String if length matched
> +  // OR this is the last string
> +  if (InputStrLen == TargetStrLen || (BufferSize == 0)) {
> +    CopyMem (StrStart, String, InputStrLen);
> +  }
> +  // Otherwise, buffer is needed to apply new string
> +  else {

Move else to same line as {

Apart from that, with the understanding that this is a work in
progress, but provides some value already:

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

For the improvement works, I would appreciate if you could look at
what we've done so far both with regards to ArmPkg/Universal/Smbios
and the helper functions added for that, to see how we could reduce
the amount of platform-specific code.

/
    Leif

> +    Buffer = AllocateZeroPool (BufferSize);
> +    if (Buffer == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
> +    CopyMem (StrStart, String, InputStrLen + 1);
> +    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
> +
> +    FreePool (Buffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +VOID
> +UpdateSmbiosType4 (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  UINTN              Index;
> +  CHAR8              Str[40];
> +  CHAR8              *StringPack;
> +  SMBIOS_TABLE_TYPE4 *Table;
> +
> +  ASSERT (PlatformHob != NULL);
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    if (Index == 0) {
> +      Table = &mArmDefaultType4Sk0.Base;
> +      StringPack = mArmDefaultType4Sk0.Strings;
> +    } else {
> +      Table = &mArmDefaultType4Sk1.Base;
> +      StringPack = mArmDefaultType4Sk1.Strings;
> +    }
> +
> +    AsciiSPrint (Str, sizeof (Str), "CPU %d", Index);
> +    UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_1);
> +
> +    Table->CoreCount = (UINT8)GetMaximumNumberOfCores ();
> +    Table->ThreadCount = (UINT8)GetMaximumNumberOfCores ();
> +    Table->EnabledCoreCount = (UINT8)GetNumberOfActiveCoresPerSocket (Index);
> +
> +    if (Table->EnabledCoreCount) {
> +      Table->CurrentSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
> +      Table->ExternalClock = (UINT16)(PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
> +      Table->MaxSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
> +      if (PlatformHob->TurboCapability[Index]) {
> +        Table->MaxSpeed = (UINT16)(PlatformHob->TurboFrequency[Index]);
> +      }
> +    } else {
> +      Table->CurrentSpeed = 0;
> +      Table->ExternalClock = 0;
> +      Table->MaxSpeed = 0;
> +      Table->Status = 0;
> +    }
> +
> +    *((UINT32 *)&Table->ProcessorId) = (UINT32)ArmReadMidr ();
> +    *((UINT32 *)&Table->ProcessorId + 1) = 0;
> +    *((UINT8 *)&Table->Voltage) = 0x80 | PlatformHob->CoreVoltage[Index] / 100;
> +
> +    /* Type 4 Part number */
> +    if (Table->EnabledCoreCount) {
> +      if ((PlatformHob->ScuProductId[Index] & 0xff) == 0x01) {
> +        AsciiSPrint (
> +          Str,
> +          sizeof (Str),
> +          "Q%02d-%02X",
> +          PlatformHob->SkuMaxCore[Index],
> +          PlatformHob->SkuMaxTurbo[Index]
> +          );
> +      } else {
> +        AsciiSPrint (
> +          Str,
> +          sizeof (Str),
> +          "M%02d%02X",
> +          PlatformHob->SkuMaxCore[Index],
> +          PlatformHob->SkuMaxTurbo[Index]
> +          );
> +      }
> +
> +      UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_4);
> +    }
> +  }
> +}
> +
> +STATIC
> +VOID
> +UpdateSmbiosType7 (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  UINTN              Index;
> +  SMBIOS_TABLE_TYPE7 *Table;
> +
> +  ASSERT (PlatformHob != NULL);
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
> +    if (Index == 0) {
> +      Table = &mArmDefaultType7Sk0L1.Base;
> +    } else {
> +      Table = &mArmDefaultType7Sk1L1.Base;
> +    }
> +
> +    Table->Associativity = (UINT8)CpuGetAssociativity (1);
> +    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (1) << 8); /* Enabled, Internal, L1 */
> +    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (1));
> +    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (1));
> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (1));
> +    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (1));
> +
> +    if (Index == 0) {
> +      Table = &mArmDefaultType7Sk0L2.Base;
> +    } else {
> +      Table = &mArmDefaultType7Sk1L2.Base;
> +    }
> +
> +    Table->Associativity = (UINT8)CpuGetAssociativity (2);
> +    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (2) << 8 | 1); /* Enabled, Internal, L2 */
> +    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (2));
> +    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (2));
> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (2));
> +    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (2));
> +
> +    if (Index == 0) {
> +      Table = &mArmDefaultType7Sk0L3.Base;
> +    } else {
> +      Table = &mArmDefaultType7Sk1L3.Base;
> +    }
> +
> +    // CpuGetCacheSize() not return L3 size, set it to 32MB
> +    Table->MaximumCacheSize  = CACHE_SIZE (32 << 20);
> +    Table->InstalledSize     = CACHE_SIZE (32 << 20);
> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (32 << 20);
> +    Table->InstalledSize2    = CACHE_SIZE_2 (32 << 20);
> +  }
> +
> +  if (GetNumberOfSupportedSockets () == 2 && GetNumberOfActiveCoresPerSocket (1) == 0) {
> +    mArmDefaultType7Sk1L1.Base.InstalledSize = 0;
> +    mArmDefaultType7Sk1L1.Base.InstalledSize2 = 0;
> +    mArmDefaultType7Sk1L2.Base.InstalledSize = 0;
> +    mArmDefaultType7Sk1L2.Base.InstalledSize2 = 0;
> +    mArmDefaultType7Sk1L3.Base.InstalledSize = 0;
> +    mArmDefaultType7Sk1L3.Base.InstalledSize2 = 0;
> +  }
> +
> +}
> +
> +STATIC
> +VOID
> +UpdateSmbiosInfo (
> +  VOID
> +  )
> +{
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  ASSERT (Hob != NULL);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  UpdateSmbiosType4 (PlatformHob);
> +  UpdateSmbiosType7 (PlatformHob);
> +}
> +
> +/**
> +   Install SMBIOS Type 7 table
> +
> +   @param  Smbios               SMBIOS protocol.
> +**/
> +EFI_STATUS
> +InstallType7Structures (
> +  IN EFI_SMBIOS_PROTOCOL *Smbios
> +  )
> +{
> +  EFI_STATUS         Status = EFI_SUCCESS;
> +  EFI_SMBIOS_HANDLE  SmbiosHandle;
> +  SMBIOS_TABLE_TYPE4 *Type4Table;
> +  CONST VOID         **Tables;
> +  UINTN              Index;
> +  UINTN              Level;
> +
> +  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
> +    if ( Index == 0) {
> +      Tables = DefaultType7Sk0Tables;
> +      Type4Table = &mArmDefaultType4Sk0.Base;
> +    } else {
> +      Tables = DefaultType7Sk1Tables;
> +      Type4Table = &mArmDefaultType4Sk1.Base;
> +    }
> +
> +    for (Level = 0; Level < CPU_CACHE_LEVEL_MAX; Level++ ) {
> +      SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)Tables[Level])->Handle;
> +      Status = Smbios->Add (
> +                         Smbios,
> +                         NULL,
> +                         &SmbiosHandle,
> +                         (EFI_SMBIOS_TABLE_HEADER *)Tables[Level]
> +                         );
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((
> +          DEBUG_ERROR,
> +          "%a: adding SMBIOS type 7 Socket %d L%d cache failed\n",
> +          __FUNCTION__,
> +          Index,
> +          Level + 1
> +          ));
> +        // stop adding rather than continuing
> +        return Status;
> +      }
> +
> +      // Save handle to Type 4
> +      if (Level == 0) { // L1 cache
> +        Type4Table->L1CacheHandle = SmbiosHandle;
> +      } else if (Level == 1) { // L2 cache
> +        Type4Table->L2CacheHandle = SmbiosHandle;
> +      } else if (Level == 2) { // L3 cache
> +        Type4Table->L3CacheHandle = SmbiosHandle;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Install a whole table worth of structructures
> +
> +   @param  Smbios               SMBIOS protocol.
> +   @param  DefaultTables        A pointer to the default SMBIOS table structure.
> +**/
> +EFI_STATUS
> +InstallStructures (
> +  IN       EFI_SMBIOS_PROTOCOL *Smbios,
> +  IN CONST VOID                *DefaultTables[]
> +  )
> +{
> +  EFI_STATUS        Status = EFI_SUCCESS;
> +  EFI_SMBIOS_HANDLE SmbiosHandle;
> +  UINTN             Index;
> +
> +  for (Index = 0; Index < GetNumberOfSupportedSockets () && DefaultTables[Index] != NULL; Index++) {
> +    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index])->Handle;
> +    Status = Smbios->Add (
> +                       Smbios,
> +                       NULL,
> +                       &SmbiosHandle,
> +                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index]
> +                       );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, Index));
> +
> +      // stop adding rather than continuing
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Install all structures from the DefaultTables structure
> +
> +   @param  Smbios               SMBIOS protocol
> +
> +**/
> +EFI_STATUS
> +InstallAllStructures (
> +  IN EFI_SMBIOS_PROTOCOL *Smbios
> +  )
> +{
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  UpdateSmbiosInfo ();
> +
> +  // Install Type 7 structures
> +  InstallType7Structures (Smbios);
> +
> +  // Install Tables
> +  Status = InstallStructures (Smbios, DefaultCommonTables);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +
> +EFI_STATUS
> +EFIAPI
> +SmbiosCpuDxeEntry (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS          Status;
> +  EFI_SMBIOS_PROTOCOL *Smbios;
> +
> +  //
> +  // Find the SMBIOS protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Smbios
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  Status = InstallAllStructures (Smbios);
> +  DEBUG ((DEBUG_ERROR, "SmbiosCpu install: %r\n", Status));
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
> new file mode 100644
> index 000000000000..a262239b53ba
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
> @@ -0,0 +1,705 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Guid/SmBios.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/Smbios.h>
> +
> +#define TYPE16_ADDITIONAL_STRINGS        \
> +  "\0" /* no string*/
> +
> +#define TYPE17_ADDITIONAL_STRINGS        \
> +  "Device Locator not set \0"  \
> +  "Bank Locator not set \0"    \
> +  "Manufacturer not set \0"    \
> +  "Serial Number not set \0"   \
> +  "Asset Tag not set \0"       \
> +  "Part Number not set \0"     \
> +
> +#define TYPE19_ADDITIONAL_STRINGS        \
> +  "\0" /* no string */
> +
> +//
> +// Type definition and contents of the default SMBIOS table.
> +// This table covers only the minimum structures required by
> +// the SMBIOS specification (section 6.2, version 3.0)
> +//
> +#pragma pack(1)
> +typedef struct {
> +  SMBIOS_TABLE_TYPE16 Base;
> +  CHAR8               Strings[sizeof (TYPE16_ADDITIONAL_STRINGS)];
> +} ARM_TYPE16;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE17 Base;
> +  CHAR8               Strings[sizeof (TYPE17_ADDITIONAL_STRINGS)];
> +} ARM_TYPE17;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE19 Base;
> +  CHAR8               Strings[sizeof (TYPE19_ADDITIONAL_STRINGS)];
> +} ARM_TYPE19;
> +
> +#pragma pack()
> +// Type 16 Physical Memory Array
> +STATIC ARM_TYPE16 mArmDefaultType16 = {
> +  {
> +    {                                        // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE16),          // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    MemoryArrayLocationSystemBoard,   // on motherboard
> +    MemoryArrayUseSystemMemory,       // system RAM
> +    MemoryErrorCorrectionMultiBitEcc, // ECC RAM
> +    0x80000000,
> +    0xFFFE,   // No error information structure
> +    0x10,
> +    0x40000000000ULL,
> +  },
> +  TYPE16_ADDITIONAL_STRINGS
> +};
> +
> +// Type 17 Memory Device
> +STATIC ARM_TYPE17 mArmDefaultType17 = {
> +  {
> +    { // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_MEMORY_DEVICE,
> +      sizeof (SMBIOS_TABLE_TYPE17),
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    0xFFFF,                         // array to which this module belongs
> +    0xFFFE,                         // no errors
> +    72,                             // single DIMM with ECC
> +    64,                             // data width of this device (64-bits)
> +    0,                              // no module installed
> +    0x09,                           // DIMM
> +    1,                              // part of a set
> +    1,                              // device locator
> +    2,                              // bank locator
> +    MemoryTypeDdr4,                 // DDR4
> +    {},                             // type detail
> +    0,                              // ? MHz
> +    3,                              // manufacturer
> +    4,                              // serial
> +    5,                              // asset tag
> +    6,                              // part number
> +    0,                              // rank
> +  },
> +  TYPE17_ADDITIONAL_STRINGS
> +};
> +
> +// Type 19 Memory Array Mapped Address
> +STATIC ARM_TYPE19 mArmDefaultType19 = {
> +  {
> +    {  // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
> +      sizeof (SMBIOS_TABLE_TYPE19),
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    0xFFFFFFFF, // invalid, look at extended addr field
> +    0xFFFFFFFF,
> +    0xFFFF,    // handle
> +    1,
> +    0x0,
> +    0x0,
> +  },
> +  TYPE19_ADDITIONAL_STRINGS
> +};
> +
> +typedef struct _JEDEC_MF_ID {
> +  UINT8 VendorId;
> +  CHAR8 *ManufacturerString;
> +} JEDEC_MF_ID;
> +
> +JEDEC_MF_ID Bank0Table[] = {
> +  { 0x01, "AMD" },
> +  { 0x04, "Fujitsu" },
> +  { 0x07, "Hitachi" },
> +  { 0x89, "Intel" },
> +  { 0x10, "NEC" },
> +  { 0x97, "Texas Instrument" },
> +  { 0x98, "Toshiba" },
> +  { 0x1c, "Mitsubishi" },
> +  { 0x1f, "Atmel" },
> +  { 0x20, "STMicroelectronics" },
> +  { 0xa4, "IBM" },
> +  { 0x2c, "Micron Technology" },
> +  { 0xad, "SK Hynix" },
> +  { 0xb0, "Sharp" },
> +  { 0xb3, "IDT" },
> +  { 0x3e, "Oracle" },
> +  { 0xbf, "SST" },
> +  { 0x40, "ProMos/Mosel" },
> +  { 0xc1, "Infineon" },
> +  { 0xc2, "Macronix" },
> +  { 0x45, "SanDisk" },
> +  { 0xce, "Samsung" },
> +  { 0xda, "Winbond" },
> +  { 0xe0, "LG Semi" },
> +  { 0x62, "Sanyo" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank1Table[] = {
> +  { 0x98, "Kingston" },
> +  { 0xba, "PNY" },
> +  { 0x4f, "Transcend" },
> +  { 0x7a, "Apacer" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank2Table[] = {
> +  { 0x9e, "Corsair" },
> +  { 0xfe, "Elpida" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank3Table[] = {
> +  { 0x0b, "Nanya" },
> +  { 0x94, "Mushkin" },
> +  { 0x25, "Kingmax" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank4Table[] = {
> +  { 0xb0, "OCZ" },
> +  { 0xcb, "A-DATA" },
> +  { 0xcd, "G Skill" },
> +  { 0xef, "Team" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank5Table[] = {
> +  { 0x02, "Patriot" },
> +  { 0x9b, "Crucial" },
> +  { 0x51, "Qimonda" },
> +  { 0x57, "AENEON" },
> +  { 0xf7, "Avant" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank6Table[] = {
> +  { 0x34, "Super Talent" },
> +  { 0xd3, "Silicon Power" },
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID Bank7Table[] = {
> +  { 0xff, "Undefined" }
> +};
> +
> +JEDEC_MF_ID *ManufacturerJedecIdBankTable[] = {
> +  Bank0Table,
> +  Bank1Table,
> +  Bank2Table,
> +  Bank3Table,
> +  Bank4Table,
> +  Bank5Table,
> +  Bank6Table,
> +  Bank7Table
> +};
> +
> +STATIC
> +UINTN
> +GetStringPackSize (
> +  CHAR8 *StringPack
> +  )
> +{
> +  UINTN StrCount;
> +  CHAR8 *StrStart;
> +
> +  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
> +    return 0;
> +  }
> +
> +  // String section ends in double-null (0000h)
> +  for (StrCount = 0, StrStart = StringPack;
> +       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
> +  {
> +  }
> +
> +  return StrCount + 2; // Included the double NULL
> +}
> +
> +// Update String at String number to String Pack
> +EFI_STATUS
> +UpdateStringPack (
> +  CHAR8 *StringPack,
> +  CHAR8 *String,
> +  UINTN StringNumber
> +  )
> +{
> +  CHAR8 *StrStart;
> +  UINTN StrIndex;
> +  UINTN InputStrLen;
> +  UINTN TargetStrLen;
> +  UINTN BufferSize;
> +  CHAR8 *Buffer;
> +
> +  StrStart = StringPack;
> +  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
> +    // A string ends in 00h
> +    if (*StrStart == 0) {
> +      StrIndex++;
> +    }
> +    // String section ends in double-null (0000h)
> +    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
> +      return EFI_NOT_FOUND;
> +    }
> +  }
> +
> +  if (*StrStart == 0) {
> +    StrStart++;
> +  }
> +
> +  InputStrLen = AsciiStrLen (String);
> +  TargetStrLen = AsciiStrLen (StrStart);
> +  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
> +
> +  // Replace the String if length matched
> +  // OR this is the last string
> +  if ((InputStrLen == TargetStrLen) || (BufferSize == 0)) {
> +    CopyMem (StrStart, String, InputStrLen);
> +  }
> +  // Otherwise, buffer is needed to apply new string
> +  else {
> +    Buffer = AllocateZeroPool (BufferSize);
> +    if (Buffer == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
> +    CopyMem (StrStart, String, InputStrLen + 1);
> +    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
> +
> +    FreePool (Buffer);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +UINT8
> +GetMemoryType (
> +  IN UINT8 *SpdData
> +  )
> +{
> +  return (SpdData[2] == 0x08) ? 1 :    // DDR2
> +         (SpdData[2] == 0x0B) ? 2 :    // DDR3
> +         (SpdData[2] == 0x0C) ? 3 : 0; // DDR4
> +}
> +
> +EFI_STATUS
> +UpdateManufacturer (
> +  IN VOID  *Table,
> +  IN UINT8 *SpdData
> +  )
> +{
> +  EFI_STATUS  Status = EFI_SUCCESS;
> +  UINTN       i;
> +  UINT8       Data8;
> +  UINT8       MemType;
> +  JEDEC_MF_ID *IdTblPtr = NULL;
> +
> +  MemType = GetMemoryType (SpdData);
> +
> +  switch (MemType) {
> +  case 1:
> +    for (i = 0; i < 8; i++) {      // DDR2
> +      Data8 = SpdData[64 + i];
> +      if (Data8 != 0x7f) {
> +        break;
> +      }
> +    }
> +    break;
> +
> +  case 2:                    // DDR3
> +    i = SpdData[117] & 0x7f; // Remove parity bit
> +    Data8 = SpdData[118];
> +    break;
> +
> +  case 3:                    // DDR4
> +    i = SpdData[320] & 0x7f; // Remove parity bit
> +    Data8 = SpdData[321];
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;  // Not supported
> +  }
> +
> +  if (i > 7) {
> +    i = 7;
> +  }
> +  IdTblPtr = ManufacturerJedecIdBankTable[i];
> +
> +  // Search in Manufacturer table
> +  while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
> +    IdTblPtr++;
> +  }
> +
> +  if (IdTblPtr->VendorId != 0xff) {
> +    Status = UpdateStringPack (
> +               ((ARM_TYPE17 *)Table)->Strings,
> +               IdTblPtr->ManufacturerString,
> +               ((ARM_TYPE17 *)Table)->Base.Manufacturer
> +               );
> +  }
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +UpdateSerialNumber (
> +  IN VOID  *Table,
> +  IN UINT8 *SpdData
> +  )
> +{
> +  UINT8 MemType;
> +  UINTN Offset;
> +  CHAR8 Str[64];
> +
> +  MemType = GetMemoryType (SpdData);
> +
> +  switch (MemType) {
> +  case 1:
> +    Offset = 95;
> +    break;
> +
> +  case 2:                          // DDR3
> +    Offset = 122;
> +    break;
> +
> +  case 3:                          // DDR4
> +    Offset = 325;
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;        // Not supported
> +  }
> +
> +  AsciiSPrint (
> +    Str,
> +    sizeof (Str),
> +    "%02X%02X%02X%02X",
> +    SpdData[Offset],
> +    SpdData[Offset + 1],
> +    SpdData[Offset + 2],
> +    SpdData[Offset + 3]
> +    );
> +
> +  return UpdateStringPack (
> +           ((ARM_TYPE17 *)Table)->Strings,
> +           Str,
> +           ((ARM_TYPE17 *)Table)->Base.SerialNumber
> +           );
> +}
> +
> +CHAR8
> +Printable (
> +  IN CHAR8 Character
> +  )
> +{
> +  if((Character >= 0x20) && (Character <= 0x7E)) {
> +    return Character;
> +  }
> +
> +  return ' ';
> +}
> +
> +EFI_STATUS
> +UpdatePartNumber (
> +  IN VOID  *Table,
> +  IN UINT8 *SpdData
> +  )
> +{
> +  UINT8 MemType;
> +  UINTN Offset;
> +  CHAR8 Str[64];
> +
> +  MemType = GetMemoryType (SpdData);
> +
> +  switch (MemType) {
> +  case 1:
> +    Offset = 73;
> +    break;
> +
> +  case 2:                          // DDR3
> +    Offset = 128;
> +    break;
> +
> +  case 3:                          // DDR4
> +    Offset = 329;
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;        // Not supported
> +  }
> +
> +  AsciiSPrint (
> +    Str,
> +    sizeof (Str),
> +    "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
> +    Printable (SpdData[Offset]),
> +    Printable (SpdData[Offset + 1]),
> +    Printable (SpdData[Offset + 2]),
> +    Printable (SpdData[Offset + 3]),
> +    Printable (SpdData[Offset + 4]),
> +    Printable (SpdData[Offset + 5]),
> +    Printable (SpdData[Offset + 6]),
> +    Printable (SpdData[Offset + 7]),
> +    Printable (SpdData[Offset + 8]),
> +    Printable (SpdData[Offset + 9]),
> +    Printable (SpdData[Offset + 10]),
> +    Printable (SpdData[Offset + 11]),
> +    Printable (SpdData[Offset + 12]),
> +    Printable (SpdData[Offset + 13]),
> +    Printable (SpdData[Offset + 14]),
> +    Printable (SpdData[Offset + 15]),
> +    Printable (SpdData[Offset + 16]),
> +    Printable (SpdData[Offset + 17])
> +    );
> +
> +  return UpdateStringPack (
> +           ((ARM_TYPE17 *)Table)->Strings,
> +           Str,
> +           ((ARM_TYPE17 *)Table)->Base.PartNumber
> +           );
> +}
> +
> +/**
> +   Install SMBIOS Type 16 17 and 19 table
> +
> +   @param  Smbios               SMBIOS protocol.
> +**/
> +EFI_STATUS
> +InstallMemStructures (
> +  IN EFI_SMBIOS_PROTOCOL *Smbios
> +  )
> +{
> +  EFI_STATUS         Status = EFI_SUCCESS;
> +  EFI_SMBIOS_HANDLE  SmbiosHandle;
> +  EFI_SMBIOS_HANDLE  Type16Handle;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  PLATFORM_DIMM      *Dimm;
> +  CHAR8              *Table;
> +  VOID               *Hob;
> +  UINTN              Index;
> +  UINTN              SlotIndex;
> +  UINTN              MemRegionIndex;
> +  UINT64             MemorySize = 0;
> +  CHAR8              Str[64];
> +
> +  ASSERT (Smbios != NULL);
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  ASSERT (Hob != NULL);
> +  if (Hob == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  Table = AllocateZeroPool (sizeof (ARM_TYPE17));
> +  if (Table == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
> +    // Copy template to Type 16
> +    CopyMem (Table, (VOID *)&mArmDefaultType16, sizeof (ARM_TYPE16));
> +
> +    ((ARM_TYPE16 *)Table)->Base.MaximumCapacity = 0x80000000;
> +    ((ARM_TYPE16 *)Table)->Base.ExtendedMaximumCapacity = 0x40000000000ULL; /* 4TB per socket */
> +    ((ARM_TYPE16 *)Table)->Base.MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
> +
> +    // Install Type 16 and hold the handle so that the subsequence type17/19 could use
> +    Type16Handle = ((ARM_TYPE16 *)Table)->Base.Hdr.Handle;
> +    Status = Smbios->Add (
> +                       Smbios,
> +                       NULL,
> +                       &Type16Handle,
> +                       (EFI_SMBIOS_TABLE_HEADER *)Table
> +                       );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 16 socket %d failed\n", __FUNCTION__, Index));
> +      FreePool (Table);
> +      // stop adding rather than continuing
> +      return Status;
> +    }
> +
> +    for (SlotIndex = 0; SlotIndex < PlatformHob->DimmList.BoardDimmSlots; SlotIndex++) {
> +      // Copy Tempplate to Type 17
> +      CopyMem (Table, (VOID *)&mArmDefaultType17, sizeof (ARM_TYPE17));
> +
> +      // Fill up type 17 table's content here
> +      Dimm = &PlatformHob->DimmList.Dimm[SlotIndex];
> +      if (Dimm->NodeId != Index) {
> +        continue;
> +      }
> +
> +      if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
> +
> +        UpdateManufacturer ((VOID *)Table, Dimm->SpdData.Data);
> +        UpdateSerialNumber ((VOID *)Table, Dimm->SpdData.Data);
> +        UpdatePartNumber ((VOID *)Table, Dimm->SpdData.Data);
> +
> +        MemorySize = Dimm->Info.DimmSize * 1024;
> +        if (MemorySize >= 0x7FFF) {
> +          ((ARM_TYPE17 *)Table)->Base.Size = 0x7FFF;
> +          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = MemorySize;
> +        } else {
> +          ((ARM_TYPE17 *)Table)->Base.Size = (UINT16)MemorySize;
> +          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = 0;
> +        }
> +
> +        ((ARM_TYPE17 *)Table)->Base.MemoryType = 0x1A; /* DDR4 */
> +        ((ARM_TYPE17 *)Table)->Base.Speed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
> +        ((ARM_TYPE17 *)Table)->Base.ConfiguredMemoryClockSpeed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
> +        ((ARM_TYPE17 *)Table)->Base.Attributes = Dimm->Info.DimmNrRank & 0x0F;
> +        ((ARM_TYPE17 *)Table)->Base.ConfiguredVoltage = 1200;
> +        ((ARM_TYPE17 *)Table)->Base.MinimumVoltage = 1140;
> +        ((ARM_TYPE17 *)Table)->Base.MaximumVoltage = 1260;
> +        ((ARM_TYPE17 *)Table)->Base.DeviceSet = 0; // None
> +
> +        if (Dimm->Info.DimmType == UDIMM || Dimm->Info.DimmType == SODIMM) {
> +          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Unbuffered = 1; /* BIT 14: unregistered */
> +        } else if (Dimm->Info.DimmType == RDIMM
> +                   || Dimm->Info.DimmType == LRDIMM
> +                   || Dimm->Info.DimmType == RSODIMM)
> +        {
> +          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Registered = 1; /* BIT 13: registered */
> +        }
> +        /* FIXME: Determine if need to set technology to NVDIMM-* when supported */
> +        ((ARM_TYPE17 *)Table)->Base.MemoryTechnology = 0x3; // DRAM
> +      }
> +      AsciiSPrint (Str, sizeof (Str), "Socket %d DIMM %d", Index, SlotIndex);
> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.DeviceLocator);
> +      AsciiSPrint (Str, sizeof (Str), "Bank %d", SlotIndex);
> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.BankLocator);
> +      AsciiSPrint (Str, sizeof (Str), "Array %d Asset Tag %d", Index, SlotIndex);
> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.AssetTag);
> +
> +      // Update Type 16 handle
> +      ((ARM_TYPE17 *)Table)->Base.MemoryArrayHandle = Type16Handle;
> +
> +      // Install structure
> +      SmbiosHandle = ((ARM_TYPE17 *)Table)->Base.Hdr.Handle;
> +      Status = Smbios->Add (
> +                         Smbios,
> +                         NULL,
> +                         &SmbiosHandle,
> +                         (EFI_SMBIOS_TABLE_HEADER *)Table
> +                         );
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((
> +          DEBUG_ERROR,
> +          "%a: adding SMBIOS type 17 Socket %d Slot %d failed\n",
> +          __FUNCTION__,
> +          Index,
> +          SlotIndex
> +          ));
> +        FreePool (Table);
> +        // stop adding rather than continuing
> +        return Status;
> +      }
> +    }
> +
> +    for (MemRegionIndex = 0; MemRegionIndex < PlatformHob->DramInfo.NumRegion; MemRegionIndex++) {
> +      // Copy Tempplate to Type 19
> +      CopyMem (Table, (VOID *)&mArmDefaultType19, sizeof (ARM_TYPE19));
> +
> +      if (PlatformHob->DramInfo.NvdRegion[MemRegionIndex] > 0
> +          || PlatformHob->DramInfo.Socket[MemRegionIndex] != Index)
> +      {
> +        continue;
> +      }
> +
> +      ((ARM_TYPE19 *)Table)->Base.StartingAddress = 0xFFFFFFFF;
> +      ((ARM_TYPE19 *)Table)->Base.EndingAddress = 0xFFFFFFFF;
> +      ((ARM_TYPE19 *)Table)->Base.ExtendedStartingAddress = PlatformHob->DramInfo.Base[MemRegionIndex];
> +      ((ARM_TYPE19 *)Table)->Base.ExtendedEndingAddress = PlatformHob->DramInfo.Base[MemRegionIndex] +
> +                                                          PlatformHob->DramInfo.Size[MemRegionIndex] - 1;
> +
> +      if (MemorySize != 0) {
> +        ((ARM_TYPE19 *)Table)->Base.PartitionWidth = (PlatformHob->DramInfo.Size[MemRegionIndex] - 1) / MemorySize + 1;
> +      }
> +
> +      // Update Type 16 handle
> +      ((ARM_TYPE19 *)Table)->Base.MemoryArrayHandle = Type16Handle;
> +
> +      // Install structure
> +      SmbiosHandle = ((ARM_TYPE19 *)Table)->Base.Hdr.Handle;
> +      Status = Smbios->Add (
> +                         Smbios,
> +                         NULL,
> +                         &SmbiosHandle,
> +                         (EFI_SMBIOS_TABLE_HEADER *)Table
> +                         );
> +      if (EFI_ERROR (Status)) {
> +        DEBUG ((
> +          DEBUG_ERROR,
> +          "%a: adding SMBIOS type 19 Socket %d MemRegion %d failed\n",
> +          __FUNCTION__,
> +          Index,
> +          MemRegionIndex
> +          ));
> +        FreePool (Table);
> +        // stop adding rather than continuing
> +        return Status;
> +      }
> +    }
> +  }
> +
> +  FreePool (Table);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +SmbiosMemInfoDxeEntry (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS          Status;
> +  EFI_SMBIOS_PROTOCOL *Smbios;
> +
> +  //
> +  // Find the SMBIOS protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Smbios
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  Status = InstallMemStructures (Smbios);
> +  DEBUG ((DEBUG_ERROR, "SmbiosMemInfoDxe install: %r\n", Status));
> +
> +  return Status;
> +}
> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
> new file mode 100644
> index 000000000000..086fdd9749fb
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
> @@ -0,0 +1,1049 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Guid/SmBios.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/Smbios.h>
> +
> +// Type0 Data
> +#define VENDOR_TEMPLATE       "Ampere(R)\0"
> +#define BIOS_VERSION_TEMPLATE "TianoCore EDKII\0"
> +#define RELEASE_DATE_TEMPLATE "MM/DD/YYYY\0"
> +
> +#define TYPE0_ADDITIONAL_STRINGS                    \
> +  VENDOR_TEMPLATE       /* Vendor */         \
> +  BIOS_VERSION_TEMPLATE /* BiosVersion */    \
> +  RELEASE_DATE_TEMPLATE /* BiosReleaseDate */
> +
> +// Type1 Data
> +#define MANUFACTURER_TEMPLATE "Ampere(R)\0"
> +#define PRODUCT_NAME_TEMPLATE "Mt. Jade\0"
> +#define SYS_VERSION_TEMPLATE  "PR010\0"
> +#define SERIAL_TEMPLATE       "123456789ABCDEFF123456789ABCDEFF\0"
> +#define SKU_TEMPLATE          "FEDCBA9876543211FEDCBA9876543211\0"
> +#define FAMILY_TEMPLATE       "ARMv8\0"
> +
> +#define TYPE1_ADDITIONAL_STRINGS                  \
> +  MANUFACTURER_TEMPLATE /* Manufacturer */  \
> +  PRODUCT_NAME_TEMPLATE /* Product Name */  \
> +  SYS_VERSION_TEMPLATE  /* Version */       \
> +  SERIAL_TEMPLATE       /* Serial Number */ \
> +  SKU_TEMPLATE          /* SKU Number */    \
> +  FAMILY_TEMPLATE       /* Family */
> +
> +#define TYPE2_ADDITIONAL_STRINGS                   \
> +  MANUFACTURER_TEMPLATE /* Manufacturer */   \
> +  PRODUCT_NAME_TEMPLATE /* Product Name */   \
> +  "EVT2\0"              /* Version */        \
> +  "Serial Not Set\0"    /* Serial */         \
> +  "Base of Chassis\0"   /* board location */ \
> +  "FF\0"                /* Version */        \
> +  "FF\0"                /* Version */
> +
> +#define CHASSIS_VERSION_TEMPLATE    "None               \0"
> +#define CHASSIS_SERIAL_TEMPLATE     "Serial Not Set     \0"
> +#define CHASSIS_ASSET_TAG_TEMPLATE  "Asset Tag Not Set  \0"
> +
> +#define TYPE3_ADDITIONAL_STRINGS                 \
> +  MANUFACTURER_TEMPLATE      /* Manufacturer */ \
> +  CHASSIS_VERSION_TEMPLATE   /* Version */      \
> +  CHASSIS_SERIAL_TEMPLATE    /* Serial  */      \
> +  CHASSIS_ASSET_TAG_TEMPLATE /* Asset Tag */    \
> +  SKU_TEMPLATE               /* SKU Number */
> +
> +#define TYPE8_ADDITIONAL_STRINGS      \
> +  "VGA1 - Rear VGA Connector\0"       \
> +  "DB-15 Male (VGA)         \0"
> +
> +#define TYPE9_ADDITIONAL_STRINGS       \
> +  "Socket 0 Riser 1 x32 - Slot 1\0"
> +
> +#define TYPE11_ADDITIONAL_STRINGS       \
> +  "www.amperecomputing.com\0"
> +
> +#define TYPE13_ADDITIONAL_STRINGS       \
> +  "en|US|iso8859-1\0"
> +
> +#define TYPE41_ADDITIONAL_STRINGS       \
> +  "Onboard VGA\0"
> +
> +//
> +// Type definition and contents of the default SMBIOS table.
> +// This table covers only the minimum structures required by
> +// the SMBIOS specification (section 6.2, version 3.0)
> +//
> +#pragma pack(1)
> +typedef struct {
> +  SMBIOS_TABLE_TYPE0 Base;
> +  CHAR8              Strings[sizeof (TYPE0_ADDITIONAL_STRINGS)];
> +} ARM_TYPE0;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE1 Base;
> +  CHAR8              Strings[sizeof (TYPE1_ADDITIONAL_STRINGS)];
> +} ARM_TYPE1;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE2 Base;
> +  CHAR8              Strings[sizeof (TYPE2_ADDITIONAL_STRINGS)];
> +} ARM_TYPE2;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE3 Base;
> +  CHAR8              Strings[sizeof (TYPE3_ADDITIONAL_STRINGS)];
> +} ARM_TYPE3;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE8 Base;
> +  CHAR8              Strings[sizeof (TYPE8_ADDITIONAL_STRINGS)];
> +} ARM_TYPE8;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE9 Base;
> +  CHAR8              Strings[sizeof (TYPE9_ADDITIONAL_STRINGS)];
> +} ARM_TYPE9;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE11 Base;
> +  CHAR8               Strings[sizeof (TYPE11_ADDITIONAL_STRINGS)];
> +} ARM_TYPE11;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE13 Base;
> +  CHAR8               Strings[sizeof (TYPE13_ADDITIONAL_STRINGS)];
> +} ARM_TYPE13;
> +
> +typedef struct {
> +  SMBIOS_TABLE_TYPE41 Base;
> +  CHAR8               Strings[sizeof (TYPE41_ADDITIONAL_STRINGS)];
> +} ARM_TYPE41;
> +
> +#pragma pack()
> +
> +//-------------------------------------
> +//        SMBIOS Platform Common
> +//-------------------------------------
> +enum {
> +  ADDITIONAL_STR_INDEX_1 = 1,
> +  ADDITIONAL_STR_INDEX_2,
> +  ADDITIONAL_STR_INDEX_3,
> +  ADDITIONAL_STR_INDEX_4,
> +  ADDITIONAL_STR_INDEX_5,
> +  ADDITIONAL_STR_INDEX_6,
> +  ADDITIONAL_STR_INDEX_MAX
> +};
> +
> +
> +// Type 0 BIOS information
> +STATIC ARM_TYPE0 mArmDefaultType0 = {
> +  {
> +    {                                   // Header
> +      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length, The length of the structure's string-set is not included.
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +
> +    ADDITIONAL_STR_INDEX_1,     // SMBIOS_TABLE_STRING       Vendor
> +    ADDITIONAL_STR_INDEX_2,     // SMBIOS_TABLE_STRING       BiosVersion
> +    0,                          // UINT16                    BiosSegment
> +    ADDITIONAL_STR_INDEX_3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
> +    0,                          // UINT8                     BiosSize
> +
> +    // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
> +    {
> +      0,0,0,0,0,0,
> +      1, // PCI supported
> +      0,
> +      1, // PNP supported
> +      0,
> +      1, // BIOS upgradable
> +      0, 0, 0,
> +      0, // Boot from CD
> +      1, // selectable boot
> +    },
> +
> +    // BIOSCharacteristicsExtensionBytes[2]
> +    {
> +      0,
> +      0,
> +    },
> +
> +    0,     // UINT8                     SystemBiosMajorRelease
> +    0,     // UINT8                     SystemBiosMinorRelease
> +
> +    // If the system does not have field upgradeable embedded controller
> +    // firmware, the value is 0FFh
> +    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
> +    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
> +  },
> +
> +  // Text strings (unformatted area)
> +  TYPE0_ADDITIONAL_STRINGS
> +};
> +
> +// Type 1 System information
> +STATIC ARM_TYPE1 mArmDefaultType1 = {
> +  {
> +    { // Header
> +      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
> +      sizeof (SMBIOS_TABLE_TYPE1),
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +
> +    ADDITIONAL_STR_INDEX_1,                                                     // Manufacturer
> +    ADDITIONAL_STR_INDEX_2,                                                     // Product Name
> +    ADDITIONAL_STR_INDEX_3,                                                     // Version
> +    ADDITIONAL_STR_INDEX_4,                                                     // Serial Number
> +    { 0x12345678, 0x9ABC, 0xDEFF, { 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xFF }}, // UUID
> +    SystemWakeupTypePowerSwitch,                                                // Wakeup type
> +    ADDITIONAL_STR_INDEX_5,                                                     // SKU Number
> +    ADDITIONAL_STR_INDEX_6,                                                     // Family
> +  },
> +
> +  // Text strings (unformatted)
> +  TYPE1_ADDITIONAL_STRINGS
> +};
> +
> +// Type 2 Baseboard
> +STATIC ARM_TYPE2 mArmDefaultType2 = {
> +  {
> +    {                                        // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE2),           // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1, // Manufacturer
> +    ADDITIONAL_STR_INDEX_2, // Product Name
> +    ADDITIONAL_STR_INDEX_3, // Version
> +    ADDITIONAL_STR_INDEX_4, // Serial
> +    0,                      // Asset tag
> +    {1},                    // motherboard, not replaceable
> +    ADDITIONAL_STR_INDEX_5, // location of board
> +    0xFFFF,                 // chassis handle
> +    BaseBoardTypeMotherBoard,
> +    0,
> +    {0},
> +  },
> +  TYPE2_ADDITIONAL_STRINGS
> +};
> +
> +// Type 3 Enclosure
> +STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
> +  {
> +    {                                   // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE3),      // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,          // Manufacturer
> +    MiscChassisTypeRackMountChassis, // Rack-mounted chassis
> +    ADDITIONAL_STR_INDEX_2,          // version
> +    ADDITIONAL_STR_INDEX_3,          // serial
> +    ADDITIONAL_STR_INDEX_4,          // asset tag
> +    ChassisStateUnknown,             // boot chassis state
> +    ChassisStateSafe,                // power supply state
> +    ChassisStateSafe,                // thermal state
> +    ChassisSecurityStatusNone,       // security state
> +    {0,0,0,0},                       // OEM defined
> +    1,                               // 1U height
> +    2,                               // number of power cords
> +    0,                               // no contained elements
> +    3,                               // ContainedElementRecordLength;
> +  },
> +  TYPE3_ADDITIONAL_STRINGS
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8Vga = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
> +    PortConnectorTypeDB15Female,  // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
> +    PortTypeOther,                // ExternalConnectorType;
> +    PortTypeVideoPort,            // PortType;
> +  },
> +  "VGA1 - Rear VGA Connector\0" \
> +  "DB-15 Male (VGA)\0"
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8USBFront = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
> +    PortConnectorTypeUsb,         // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
> +    PortTypeOther,                // ExternalConnectorType;
> +    PortTypeUsb,                  // PortType;
> +  },
> +  "Front Panel USB 3.0\0"  \
> +  "USB\0"
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8USBRear = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
> +    PortConnectorTypeUsb,         // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
> +    PortTypeOther,                // ExternalConnectorType;
> +    PortTypeUsb,                  // PortType;
> +  },
> +  "Rear Panel USB 3.0\0"   \
> +  "USB\0"
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8NetRJ45 = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
> +    PortConnectorTypeRJ45,        // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
> +    PortConnectorTypeRJ45,        // ExternalConnectorType;
> +    PortTypeNetworkPort,          // PortType;
> +  },
> +  "RJ1 - BMC RJ45 Port\0" \
> +  "RJ45 Connector\0"
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8NetOcp = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
> +    PortTypeOther,                // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
> +    PortTypeOther,                // ExternalConnectorType;
> +    PortTypeNetworkPort,          // PortType;
> +  },
> +  "OCP1 - OCP NIC 3.0 Connector\0"  \
> +  "OCP NIC 3.0\0"
> +};
> +
> +// Type 8 Port Connector Information
> +STATIC CONST ARM_TYPE8 mArmDefaultType8Uart = {
> +  {
> +    {                                             // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,        // InternalReferenceDesignator String
> +    PortTypeOther,                 // InternalConnectorType;
> +    ADDITIONAL_STR_INDEX_2,        // ExternalReferenceDesignator String
> +    PortConnectorTypeDB9Female,    // ExternalConnectorType;
> +    PortTypeSerial16550Compatible, // PortType;
> +  },
> +  "UART1 - BMC UART5 Connector\0"  \
> +  "DB-9 female\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot1 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth16X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    0,
> +    0,
> +    0,
> +  },
> +  "S0 Riser 1 x32 - Slot 1\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot2 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    4,
> +    0,
> +    0,
> +  },
> +  "S0 Riser x32 - Slot 2\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot3 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    5,
> +    0,
> +    0,
> +  },
> +  "S0 Riser x32 - Slot 3\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot1 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    7,
> +    0,
> +    0,
> +  },
> +  "S1 Riser x24 - Slot 1\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot2 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    8,
> +    0,
> +    0,
> +  },
> +  "S1 Riser x24 - Slot 2\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot3 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    9,
> +    0,
> +    0,
> +  },
> +  "S1 Riser x24 - Slot 3\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX8Slot1 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth8X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    8,
> +    0,
> +    0,
> +  },
> +  "S1 Riser x8 - Slot 1\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk0OcpNic = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth16X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    1,
> +    0,
> +    0,
> +  },
> +  "S0 OCP NIC 3.0\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot1 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth4X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    5,
> +    0,
> +    0,
> +  },
> +  "S1 NVMe M.2 - Slot 1\0"
> +};
> +
> +// Type 9 System Slots
> +STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot2 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1,
> +    SlotTypePciExpressGen3,
> +    SlotDataBusWidth4X,
> +    SlotUsageAvailable,
> +    SlotLengthLong,
> +    0,
> +    {0, 0, 1}, // Provides 3.3 Volts
> +    {1},       // PME
> +    5,
> +    0,
> +    0,
> +  },
> +  "S1 NVMe M.2 - Slot 2\0"
> +};
> +
> +// Type 11 OEM Strings
> +STATIC ARM_TYPE11 mArmDefaultType11 = {
> +  {
> +    {                               // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_OEM_STRINGS,  // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE11), // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    ADDITIONAL_STR_INDEX_1
> +  },
> +  TYPE11_ADDITIONAL_STRINGS
> +};
> +
> +// Type 13 BIOS Language Information
> +STATIC ARM_TYPE13 mArmDefaultType13 = {
> +  {
> +    {                                            // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION, // UINT8 Type
> +      sizeof (SMBIOS_TABLE_TYPE13),              // UINT8 Length
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    1,
> +    0,
> +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
> +    1,
> +  },
> +  TYPE13_ADDITIONAL_STRINGS
> +};
> +
> +// Type 24 Hardware Security
> +STATIC SMBIOS_TABLE_TYPE24 mArmDefaultType24 = {
> +  {                                    // SMBIOS_STRUCTURE Hdr
> +    EFI_SMBIOS_TYPE_HARDWARE_SECURITY, // UINT8 Type
> +    sizeof (SMBIOS_TABLE_TYPE24),      // UINT8 Length
> +    SMBIOS_HANDLE_PI_RESERVED,
> +  },
> +  0
> +};
> +
> +// Type 32 System Boot Information
> +STATIC SMBIOS_TABLE_TYPE32 mArmDefaultType32 = {
> +  {                                          // SMBIOS_STRUCTURE Hdr
> +    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, // UINT8 Type
> +    sizeof (SMBIOS_TABLE_TYPE32),            // UINT8 Length
> +    SMBIOS_HANDLE_PI_RESERVED,
> +  },
> +  {0, 0, 0, 0, 0, 0},
> +  0
> +};
> +
> +// Type 38 IPMI Device Information
> +STATIC SMBIOS_TABLE_TYPE38 mArmDefaultType38 = {
> +  {                                          // SMBIOS_STRUCTURE Hdr
> +    EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION, // UINT8 Type
> +    sizeof (SMBIOS_TABLE_TYPE38),            // UINT8 Length
> +    SMBIOS_HANDLE_PI_RESERVED,
> +  },
> +  IPMIDeviceInfoInterfaceTypeSSIF,
> +  0x20,
> +  0x20,
> +  0xFF,
> +  0x20
> +};
> +
> +// Type 41 Onboard Devices Extended Information
> +STATIC ARM_TYPE41 mArmDefaultType41 = {
> +  {
> +    { // SMBIOS_STRUCTURE Hdr
> +      EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION,
> +      sizeof (SMBIOS_TABLE_TYPE41),
> +      SMBIOS_HANDLE_PI_RESERVED,
> +    },
> +    1,
> +    0x83,  // OnBoardDeviceExtendedTypeVideo, Enabled
> +    1,
> +    4,
> +    2,
> +    0,
> +  },
> +  TYPE41_ADDITIONAL_STRINGS
> +};
> +
> +// Type 42 System Boot Information
> +STATIC SMBIOS_TABLE_TYPE42 mArmDefaultType42 = {
> +  { // SMBIOS_STRUCTURE Hdr
> +    EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE,
> +    sizeof (SMBIOS_TABLE_TYPE42),
> +    SMBIOS_HANDLE_PI_RESERVED,
> +  },
> +  MCHostInterfaceTypeOemDefined,
> +  4,
> +  {0xFF, 0, 0, 0}
> +};
> +
> +STATIC CONST VOID *DefaultCommonTables[] =
> +{
> +  &mArmDefaultType0,
> +  &mArmDefaultType1,
> +  &mArmDefaultType2,
> +  &mArmDefaultType8Vga,
> +  &mArmDefaultType8USBFront,
> +  &mArmDefaultType8USBRear,
> +  &mArmDefaultType8NetRJ45,
> +  &mArmDefaultType8NetOcp,
> +  &mArmDefaultType8Uart,
> +  &mArmDefaultType9Sk0RiserX32Slot1,
> +  &mArmDefaultType9Sk0RiserX32Slot2,
> +  &mArmDefaultType9Sk0RiserX32Slot3,
> +  &mArmDefaultType9Sk1RiserX24Slot1,
> +  &mArmDefaultType9Sk1RiserX24Slot2,
> +  &mArmDefaultType9Sk1RiserX24Slot3,
> +  &mArmDefaultType9Sk1RiserX8Slot1,
> +  &mArmDefaultType9Sk0OcpNic,
> +  &mArmDefaultType9Sk1NvmeM2Slot1,
> +  &mArmDefaultType9Sk1NvmeM2Slot2,
> +  &mArmDefaultType11,
> +  &mArmDefaultType13,
> +  &mArmDefaultType24,
> +  &mArmDefaultType32,
> +  &mArmDefaultType38,
> +  &mArmDefaultType41,
> +  &mArmDefaultType42,
> +  NULL
> +};
> +
> +typedef struct {
> +  CHAR8 MonthNameStr[4]; // example "Jan", Compiler build date, month
> +  CHAR8 DigitStr[3];     // example "01", Smbios date format, month
> +} MonthStringDig;
> +
> +STATIC MonthStringDig MonthMatch[12] = {
> +  { "Jan", "01" },
> +  { "Feb", "02" },
> +  { "Mar", "03" },
> +  { "Apr", "04" },
> +  { "May", "05" },
> +  { "Jun", "06" },
> +  { "Jul", "07" },
> +  { "Aug", "08" },
> +  { "Sep", "09" },
> +  { "Oct", "10" },
> +  { "Nov", "11" },
> +  { "Dec", "12" }
> +};
> +
> +STATIC
> +VOID
> +ConstructBuildDate (
> +  OUT CHAR8 *DateBuf
> +  )
> +{
> +  UINTN i;
> +
> +  // GCC __DATE__ format is "Feb  2 1996"
> +  // If the day of the month is less than 10, it is padded with a space on the left
> +  CHAR8 *BuildDate = __DATE__;
> +
> +  // SMBIOS spec date string: MM/DD/YYYY
> +  CHAR8 SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE)] = { 0 };
> +
> +  SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE) - 1] = '\0';
> +
> +  SmbiosDateStr[2] = '/';
> +  SmbiosDateStr[5] = '/';
> +
> +  // Month
> +  for (i = 0; i < sizeof (MonthMatch) / sizeof (MonthMatch[0]); i++) {
> +    if (AsciiStrnCmp (&BuildDate[0], MonthMatch[i].MonthNameStr, AsciiStrLen (MonthMatch[i].MonthNameStr)) == 0) {
> +      CopyMem (&SmbiosDateStr[0], MonthMatch[i].DigitStr, AsciiStrLen (MonthMatch[i].DigitStr));
> +      break;
> +    }
> +  }
> +
> +  // Day
> +  CopyMem (&SmbiosDateStr[3], &BuildDate[4], 2);
> +  if (BuildDate[4] == ' ') {
> +    // day is less then 10, SAPCE filed by compiler, SMBIOS requires 0
> +    SmbiosDateStr[3] = '0';
> +  }
> +
> +  // Year
> +  CopyMem (&SmbiosDateStr[6], &BuildDate[7], 4);
> +
> +  CopyMem (DateBuf, SmbiosDateStr, AsciiStrLen (RELEASE_DATE_TEMPLATE));
> +}
> +
> +STATIC
> +UINT8
> +GetBiosVerMajor (
> +  VOID
> +  )
> +{
> +  return (PcdGet8 (PcdSmbiosTables1MajorVersion));
> +}
> +
> +STATIC
> +UINT8
> +GetBiosVerMinor (
> +  VOID
> +  )
> +{
> +  return (PcdGet8 (PcdSmbiosTables1MinorVersion));
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateSmbiosType0 (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  EFI_STATUS                          Status        = EFI_SUCCESS;
> +  MISC_BIOS_CHARACTERISTICS_EXTENSION *MiscExt      = NULL;
> +  CHAR8                               *ReleaseDateBuf = NULL;
> +  CHAR8                               *PcdReleaseDate = NULL;
> +  CHAR8                               AsciiVersion[32];
> +  UINTN                               Index;
> +
> +  //
> +  //  Update Type0 information
> +  //
> +  ReleaseDateBuf = &mArmDefaultType0.Strings[0]
> +                   + sizeof (VENDOR_TEMPLATE) - 1
> +                   + sizeof (BIOS_VERSION_TEMPLATE) - 1;
> +  PcdReleaseDate = (CHAR8 *)PcdGetPtr (PcdSmbiosTables0BiosReleaseDate);
> +
> +  if (AsciiStrnCmp (PcdReleaseDate, RELEASE_DATE_TEMPLATE, AsciiStrLen (RELEASE_DATE_TEMPLATE)) == 0) {
> +    // If PCD is still template date MM/DD/YYYY, use compiler date
> +    ConstructBuildDate (ReleaseDateBuf);
> +  } else {
> +    // PCD is updated somehow, use PCD date
> +    CopyMem (ReleaseDateBuf, PcdReleaseDate, AsciiStrLen (PcdReleaseDate));
> +  }
> +
> +  if (PcdGet32 (PcdFdSize) < SIZE_16MB) {
> +    mArmDefaultType0.Base.BiosSize = (PcdGet32 (PcdFdSize) / SIZE_64KB) - 1;
> +
> +    mArmDefaultType0.Base.ExtendedBiosSize.Size = 0;
> +    mArmDefaultType0.Base.ExtendedBiosSize.Unit = 0;
> +  } else {
> +    // TODO: Need to update Extended BIOS ROM Size
> +    mArmDefaultType0.Base.BiosSize = 0xFF;
> +
> +    // As a reminder
> +    ASSERT (FALSE);
> +  }
> +
> +  // Type0 BIOS Characteristics Extension Byte 1
> +  MiscExt = (MISC_BIOS_CHARACTERISTICS_EXTENSION *)&(mArmDefaultType0.Base.BIOSCharacteristicsExtensionBytes);
> +
> +  MiscExt->BiosReserved.AcpiIsSupported = 1;
> +
> +  // Type0 BIOS Characteristics Extension Byte 2
> +  MiscExt->SystemReserved.BiosBootSpecIsSupported = 1;
> +  MiscExt->SystemReserved.FunctionKeyNetworkBootIsSupported = 1;
> +  MiscExt->SystemReserved.UefiSpecificationSupported = 1;
> +
> +  // Type0 BIOS Release
> +  // TODO: to decide another way: If the system does not support the use of this
> +  // field, the value is 0FFh
> +  mArmDefaultType0.Base.SystemBiosMajorRelease = GetBiosVerMajor ();
> +  mArmDefaultType0.Base.SystemBiosMinorRelease = GetBiosVerMinor ();
> +
> +  /* Update SMBIOS Type 0 EC Info */
> +  CopyMem (
> +    (VOID *)&AsciiVersion,
> +    (VOID *)&PlatformHob->SmPmProVer,
> +    sizeof (PlatformHob->SmPmProVer)
> +    );
> +  /* The AsciiVersion is formated as "major.minor" */
> +  for (Index = 0; Index < (UINTN)AsciiStrLen (AsciiVersion); Index++) {
> +    if (AsciiVersion[Index] == '.') {
> +      AsciiVersion[Index] = '\0';
> +      break;
> +    }
> +  }
> +
> +  mArmDefaultType0.Base.EmbeddedControllerFirmwareMajorRelease =
> +    (UINT8)AsciiStrDecimalToUintn (AsciiVersion);
> +  mArmDefaultType0.Base.EmbeddedControllerFirmwareMinorRelease =
> +    (UINT8)AsciiStrDecimalToUintn (AsciiVersion + Index + 1);
> +
> +  return Status;
> +}
> +
> +STATIC
> +EFI_STATUS
> +InstallType3Structure (
> +  IN EFI_SMBIOS_PROTOCOL *Smbios
> +  )
> +{
> +  EFI_STATUS          Status = EFI_SUCCESS;
> +  EFI_SMBIOS_HANDLE   SmbiosHandle;
> +
> +  ASSERT (Smbios != NULL);
> +
> +  SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) &mArmDefaultType3)->Handle;
> +  Status = Smbios->Add (
> +                     Smbios,
> +                     NULL,
> +                     &SmbiosHandle,
> +                     (EFI_SMBIOS_TABLE_HEADER *)&mArmDefaultType3
> +                     );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "adding SMBIOS type 3 failed\n"));
> +    // stop adding rather than continuing
> +    return Status;
> +  }
> +
> +  // Save this handle to type 2 table
> +  mArmDefaultType2.Base.ChassisHandle = SmbiosHandle;
> +
> +  return Status;
> +}
> +
> +/**
> +   Install a whole table worth of structures
> +
> +   @param  Smbios               SMBIOS protocol.
> +   @param  DefaultTables        A pointer to the default SMBIOS table structure.
> +**/
> +EFI_STATUS
> +InstallStructures (
> +  IN       EFI_SMBIOS_PROTOCOL *Smbios,
> +  IN CONST VOID                *DefaultTables[]
> +  )
> +{
> +  EFI_STATUS        Status = EFI_SUCCESS;
> +  EFI_SMBIOS_HANDLE SmbiosHandle;
> +  UINTN             TableIndex;
> +
> +  ASSERT (Smbios != NULL);
> +
> +  for (TableIndex = 0; DefaultTables[TableIndex] != NULL; TableIndex++) {
> +    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex])->Handle;
> +    Status = Smbios->Add (
> +                       Smbios,
> +                       NULL,
> +                       &SmbiosHandle,
> +                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex]
> +                       );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, TableIndex));
> +
> +      // stop adding rather than continuing
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +VOID
> +UpdateSmbiosInfo (
> +  VOID
> +  )
> +{
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  ASSERT (Hob != NULL);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  //
> +  //  Update Type0 information
> +  //
> +  UpdateSmbiosType0 (PlatformHob);
> +
> +}
> +
> +/**
> +   Install all structures from the DefaultTables structure
> +
> +   @param  Smbios               SMBIOS protocol
> +
> +**/
> +EFI_STATUS
> +InstallAllStructures (
> +  IN EFI_SMBIOS_PROTOCOL *Smbios
> +  )
> +{
> +  EFI_STATUS Status = EFI_SUCCESS;
> +
> +  ASSERT (Smbios != NULL);
> +
> +  // Update SMBIOS Tables
> +  UpdateSmbiosInfo ();
> +
> +  // Install Type 3 table
> +  InstallType3Structure (Smbios);
> +
> +  // Install Tables
> +  Status = InstallStructures (Smbios, DefaultCommonTables);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return Status;
> +}
> +
> +/**
> +   Installs SMBIOS information for ARM platforms
> +
> +   @param ImageHandle     Module's image handle
> +   @param SystemTable     Pointer of EFI_SYSTEM_TABLE
> +
> +   @retval EFI_SUCCESS    Smbios data successfully installed
> +   @retval Other          Smbios data was not installed
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmbiosPlatformDxeEntry (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS          Status;
> +  EFI_SMBIOS_PROTOCOL *Smbios;
> +
> +  //
> +  // Find the SMBIOS protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiSmbiosProtocolGuid,
> +                  NULL,
> +                  (VOID **)&Smbios
> +                  );
> +
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = InstallAllStructures (Smbios);
> +  DEBUG ((DEBUG_ERROR, "SmbiosPlatform install - %r\n", Status));
> +
> +  return Status;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
@ 2021-06-07 23:08   ` Leif Lindholm
  2021-06-15 16:51     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:08 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:13 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Helps to show various system information like CPU info and Board Setting
> values to UART console during boot process.
>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                    |   2 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf |  41 ++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c   | 230 ++++++++++++++++++++
>  4 files changed, 274 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 930bbb5d385b..2d380b21df24 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -534,6 +534,7 @@ [Components.common]
>    ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>    ArmPkg/Drivers/CpuPei/CpuPei.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 3d5d857178b3..8c09e2a49089 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -167,6 +167,8 @@ [FV.FVMAIN_COMPACT]
>    #
>    # Print platform information before passing control into the Driver Execution Environment (DXE) phase
>    #
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
> +
>    INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>  
>    FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
> new file mode 100755
> index 000000000000..11414f72f369
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
> @@ -0,0 +1,41 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = DebugInfo
> +  FILE_GUID                      = C0571D26-6176-11E9-8647-D663BD873D93
> +  MODULE_TYPE                    = PEIM
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = DebugInfoPeiEntryPoint
> +
> +[Sources]
> +  DebugInfoPei.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  ArmLib
> +  HobLib
> +  NVParamLib
> +  PeimEntryPoint
> +  PrintLib
> +  SerialPortLib
> +
> +[Guids]
> +  gPlatformHobGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
> new file mode 100644
> index 000000000000..d6775ffa4a79
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
> @@ -0,0 +1,230 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <PiPei.h>
> +#include <Uefi.h>
> +
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PeimEntryPoint.h>
> +#include <Library/PeiServicesLib.h>
> +#include <Library/PeiServicesTablePointerLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/SerialPortLib.h>
> +#include <NVParamDef.h>
> +#include <Pcie.h>
> +#include <PlatformInfoHob.h>
> +
> +#define MAX_PRINT_LEN       512
> +
> +#define GB_SCALE_FACTOR     1073741824
> +#define MB_SCALE_FACTOR     1048576
> +#define KB_SCALE_FACTOR     1024
> +#define MHZ_SCALE_FACTOR    1000000
> +
> +STATIC VOID
> +SerialPrint (
> +  IN CONST CHAR8 *FormatString,
> +  ...
> +  )
> +{
> +  CHAR8   Buf[MAX_PRINT_LEN];
> +  VA_LIST Marker;
> +  UINTN   NumberOfPrinted;
> +
> +  VA_START (Marker, FormatString);
> +  NumberOfPrinted = AsciiVSPrint (Buf, sizeof (Buf), FormatString, Marker);
> +  SerialPortWrite ((UINT8 *)Buf, NumberOfPrinted);
> +  VA_END (Marker);
> +}

Why not use BaseDebugLibSerialPort?

/
    Leif

> +
> +/**
> +  Print any existence NVRAM.
> +**/
> +STATIC VOID
> +PrintNVRAM (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  NVPARAM    Idx;
> +  UINT32     Val;
> +  UINT16     ACLRd = NV_PERM_ALL;
> +  BOOLEAN    Flag;
> +
> +  Flag = FALSE;
> +  for (Idx = NV_PREBOOT_PARAM_START; Idx <= NV_PREBOOT_PARAM_MAX; Idx += NVPARAM_SIZE) {
> +    Status = NVParamGet (Idx, ACLRd, &Val);
> +    if (!EFI_ERROR (Status)) {
> +      if (!Flag) {
> +        SerialPrint ("Pre-boot Configuration Setting:\n");
> +        Flag = TRUE;
> +      }
> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
> +    }
> +  }
> +
> +  Flag = FALSE;
> +  for (Idx = NV_MANU_PARAM_START; Idx <= NV_MANU_PARAM_MAX; Idx += NVPARAM_SIZE) {
> +    Status = NVParamGet (Idx, ACLRd, &Val);
> +    if (!EFI_ERROR (Status)) {
> +      if (!Flag) {
> +        SerialPrint ("Manufacturer Configuration Setting:\n");
> +        Flag = TRUE;
> +      }
> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
> +    }
> +  }
> +
> +  Flag = FALSE;
> +  for (Idx = NV_USER_PARAM_START; Idx <= NV_USER_PARAM_MAX; Idx += NVPARAM_SIZE) {
> +    Status = NVParamGet (Idx, ACLRd, &Val);
> +    if (!EFI_ERROR (Status)) {
> +      if (!Flag) {
> +        SerialPrint ("User Configuration Setting:\n");
> +        Flag = TRUE;
> +      }
> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
> +    }
> +  }
> +
> +  Flag = FALSE;
> +  for (Idx = NV_BOARD_PARAM_START; Idx <= NV_BOARD_PARAM_MAX; Idx += NVPARAM_SIZE) {
> +    Status = NVParamGet (Idx, ACLRd, &Val);
> +    if (!EFI_ERROR (Status)) {
> +      if (!Flag) {
> +        SerialPrint ("Board Configuration Setting:\n");
> +        Flag = TRUE;
> +      }
> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
> +    }
> +  }
> +}
> +
> +STATIC
> +CHAR8 *
> +GetCCIXLinkSpeed (
> +  IN UINTN Speed
> +  )
> +{
> +  switch (Speed) {
> +  case 1:
> +    return "2.5 GT/s";
> +
> +  case 2:
> +    return "5 GT/s";
> +
> +  case 3:
> +    return "8 GT/s";
> +
> +  case 4:
> +  case 6:
> +    return "16 GT/s";
> +
> +  case 0xa:
> +    return "20 GT/s";
> +
> +  case 0xf:
> +    return "25 GT/s";
> +  }
> +
> +  return "Unknown";
> +}
> +
> +/**
> +  Print system info
> +**/
> +STATIC VOID
> +PrintSystemInfo (
> +  VOID
> +  )
> +{
> +  UINTN              Idx;
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return;
> +  }
> +
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  SerialPrint ("SCP FW version    : %a\n", (const CHAR8 *)PlatformHob->SmPmProVer);
> +  SerialPrint ("SCP FW build date : %a\n", (const CHAR8 *)PlatformHob->SmPmProBuild);
> +
> +  SerialPrint ("Failsafe status                 : %d\n", PlatformHob->FailSafeStatus);
> +  SerialPrint ("Reset status                    : %d\n", PlatformHob->ResetStatus);
> +  SerialPrint ("CPU info\n");
> +  SerialPrint ("    CPU ID                      : %X\n", ArmReadMidr ());
> +  SerialPrint ("    CPU Clock                   : %d MHz\n", PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
> +  SerialPrint ("    Number of active sockets    : %d\n", GetNumberOfActiveSockets ());
> +  SerialPrint ("    Number of active cores      : %d\n", GetNumberOfActiveCores ());
> +  if (IsSlaveSocketActive ()) {
> +    SerialPrint (
> +      "    Inter Socket Connection 0   : Width: x%d / Speed %a\n",
> +      PlatformHob->Link2PWidth[0],
> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[0])
> +      );
> +    SerialPrint (
> +      "    Inter Socket Connection 1   : Width: x%d / Speed %a\n",
> +      PlatformHob->Link2PWidth[1],
> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[1])
> +      );
> +  }
> +  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
> +    SerialPrint ("    Socket[%d]: Core voltage     : %d\n", Idx, PlatformHob->CoreVoltage[Idx]);
> +    SerialPrint ("    Socket[%d]: SCU ProductID    : %X\n", Idx, PlatformHob->ScuProductId[Idx]);
> +    SerialPrint ("    Socket[%d]: Max cores        : %d\n", Idx, PlatformHob->MaxNumOfCore[Idx]);
> +    SerialPrint ("    Socket[%d]: Warranty         : %d\n", Idx, PlatformHob->Warranty[Idx]);
> +    SerialPrint ("    Socket[%d]: Subnuma          : %d\n", Idx, PlatformHob->SubNumaMode[Idx]);
> +    SerialPrint ("    Socket[%d]: RC disable mask  : %X\n", Idx, PlatformHob->RcDisableMask[Idx]);
> +    SerialPrint ("    Socket[%d]: AVS enabled      : %d\n", Idx, PlatformHob->AvsEnable[Idx]);
> +    SerialPrint ("    Socket[%d]: AVS voltage      : %d\n", Idx, PlatformHob->AvsVoltageMV[Idx]);
> +  }
> +
> +  SerialPrint ("SOC info\n");
> +  SerialPrint ("    DDR Frequency               : %d MHz\n", PlatformHob->DramInfo.MaxSpeed);
> +  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
> +    SerialPrint ("    Socket[%d]: Soc voltage      : %d\n", Idx, PlatformHob->SocVoltage[Idx]);
> +    SerialPrint ("    Socket[%d]: DIMM1 voltage    : %d\n", Idx, PlatformHob->Dimm1Voltage[Idx]);
> +    SerialPrint ("    Socket[%d]: DIMM2 voltage    : %d\n", Idx, PlatformHob->Dimm2Voltage[Idx]);
> +  }
> +
> +  SerialPrint ("    PCP Clock                   : %d MHz\n", PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
> +  SerialPrint ("    SOC Clock                   : %d MHz\n", PlatformHob->SocClk / MHZ_SCALE_FACTOR);
> +  SerialPrint ("    SYS Clock                   : %d MHz\n", PlatformHob->SysClk / MHZ_SCALE_FACTOR);
> +  SerialPrint ("    AHB Clock                   : %d MHz\n", PlatformHob->AhbClk / MHZ_SCALE_FACTOR);
> +}
> +
> +/**
> +  Entry point function for the PEIM
> +
> +  @param FileHandle      Handle of the file being invoked.
> +  @param PeiServices     Describes the list of possible PEI Services.
> +
> +  @return EFI_SUCCESS    If we installed our PPI
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DebugInfoPeiEntryPoint (
> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
> +  IN CONST EFI_PEI_SERVICES    **PeiServices
> +  )
> +{
> +  PrintSystemInfo ();
> +  PrintNVRAM ();
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
@ 2021-06-07 23:10   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:10 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:14 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Provide screen menu with basic platform information include:
> * Platform name
> * SCP firmware info
> * System bus clock frequency.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Platform/Ampere/JadePkg/Jade.dsc                                          |   5 +
>  Platform/Ampere/JadePkg/Jade.fdf                                          |   5 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf |  52 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h   |  22 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr             | 112 ++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c   | 391 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni      |  56 +++
>  7 files changed, 643 insertions(+)
> 
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 9c7d7cad4915..b5edb673abba 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -174,3 +174,8 @@ [Components.common]
>    Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>    Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>    Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> +
> +  #
> +  # HII
> +  #
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 8c09e2a49089..6dd759322d9d 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -350,4 +350,9 @@ [FV.FvMain]
>    INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>    INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>  
> +  #
> +  # HII
> +  #
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> +
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> new file mode 100644
> index 000000000000..09de87915510
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> @@ -0,0 +1,52 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PlatformInfoDxe
> +  FILE_GUID                      = 6FDFB3E8-105E-48C4-94AA-3D7646F9B50D
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PlatformInfoEntryPoint
> +
> +[Sources.common]
> +  PlatformInfoDxe.c
> +  PlatformInfoHii.h
> +  Vfr.vfr
> +  VfrStrings.uni
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  DevicePathLib
> +  HiiLib
> +  HobLib
> +  IoLib
> +  MemoryAllocationLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Guids]
> +  gPlatformManagerFormsetGuid
> +  gEfiIfrTianoGuid
> +  gPlatformHobGuid
> +
> +[Protocols]
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
> new file mode 100644
> index 000000000000..7f363160afc8
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoHii.h
> @@ -0,0 +1,22 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PLATFORM_INFO_HII_H_
> +#define PLATFORM_INFO_HII_H_
> +
> +#define PLATFORM_INFO_FORMSET_GUID \
> +  { \
> +    0x8DF0F6FB, 0x65A5, 0x434B, { 0xB2, 0xA6, 0xCE, 0xDF, 0xD2, 0x0A, 0x96, 0x8A } \
> +  }
> +
> +#define LABEL_UPDATE             0x2223
> +#define LABEL_END                0x2224
> +
> +#define PLATFORM_INFO_FORM_ID    0x1
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..5dd32a30f0ad
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/Vfr.vfr
> @@ -0,0 +1,112 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "PlatformInfoHii.h"
> +
> +formset
> +  guid      = PLATFORM_INFO_FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_PLATFORM_INFO_FORM),
> +  help      = STRING_TOKEN(STR_PLATFORM_INFO_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  form
> +    formid = PLATFORM_INFO_FORM_ID,
> +    title  = STRING_TOKEN(STR_PLATFORM_INFO_FORM);
> +    subtitle text = STRING_TOKEN(STR_PLATFORM_INFO_FORM_HELP);
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_BOARD_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPVER_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SCPBUILD_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUINFO_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_CPUCLK_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_PCPCLK_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1ICACHE_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L1DCACHE_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_L2CACHE_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SOCCLK_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_SYSCLK_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    text
> +      help   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK),
> +      text   = STRING_TOKEN(STR_PLATFORM_INFO_AHBCLK_VALUE),
> +      flags  = 0,
> +      key    = 0;
> +
> +    label LABEL_UPDATE;
> +    // dynamic content here
> +    label LABEL_END;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
> new file mode 100644
> index 000000000000..a55d0e9da9e7
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.c
> @@ -0,0 +1,391 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <PlatformInfoHob.h>
> +
> +#include "PlatformInfoHii.h"
> +
> +//
> +// uni string and Vfr Binary data.
> +//
> +extern UINT8 VfrBin[];
> +extern UINT8 PlatformInfoDxeStrings[];
> +
> +EFI_HANDLE     mDriverHandle = NULL;
> +EFI_HII_HANDLE mHiiHandle = NULL;
> +
> +#pragma pack(1)
> +
> +//
> +// HII specific Vendor Device Path definition.
> +//
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +// PLATFORM_INFO_FORMSET_GUID
> +EFI_GUID gPlatformInfoFormSetGuid = PLATFORM_INFO_FORMSET_GUID;
> +
> +HII_VENDOR_DEVICE_PATH mPlatformInfoHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    PLATFORM_INFO_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +#define MAX_STRING_SIZE     64
> +#define MHZ_SCALE_FACTOR    1000000
> +
> +STATIC
> +CHAR8 *
> +GetCCIXLinkSpeed (
> +  IN UINTN Speed
> +  )
> +{
> +  switch (Speed) {
> +  case 1:
> +    return "2.5 GT/s";
> +
> +  case 2:
> +    return "5 GT/s";
> +
> +  case 3:
> +    return "8 GT/s";
> +
> +  case 4:
> +  case 6:
> +    return "16 GT/s";
> +
> +  case 0xa:
> +    return "20 GT/s";
> +
> +  case 0xf:
> +    return "25 GT/s";
> +  }
> +
> +  return "Unknown";
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdatePlatformInfoScreen (
> +  IN EFI_HII_HANDLE *HiiHandle
> +  )
> +{
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  CHAR16             Str[MAX_STRING_SIZE];
> +
> +  VOID               *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  /* SCP Version */
> +  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->SmPmProVer, Str, MAX_STRING_SIZE);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_SCPVER_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* SCP build */
> +  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->SmPmProBuild, Str, MAX_STRING_SIZE);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_SCPBUILD_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* CPU Info */
> +  AsciiStrToUnicodeStrS ((const CHAR8 *)PlatformHob->CpuInfo, Str, MAX_STRING_SIZE);
> +  UnicodeSPrint (Str, sizeof (Str), L"%s", Str);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_CPUINFO_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* CPU clock */
> +  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_CPUCLK_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* PCP clock */
> +  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_PCPCLK_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* SOC clock */
> +  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->SocClk / MHZ_SCALE_FACTOR);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_SOCCLK_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* L1 Cache */
> +  UnicodeSPrint (Str, sizeof (Str), L"64KB");
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_L1ICACHE_VALUE),
> +    Str,
> +    NULL
> +    );
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_L1DCACHE_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* L2 Cache */
> +  UnicodeSPrint (Str, sizeof (Str), L"1MB");
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_L2CACHE_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* AHB clock */
> +  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->AhbClk / MHZ_SCALE_FACTOR);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_AHBCLK_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* SYS clock */
> +  UnicodeSPrint (Str, sizeof (Str), L"%dMHz", PlatformHob->SysClk / MHZ_SCALE_FACTOR);
> +  HiiSetString (
> +    HiiHandle,
> +    STRING_TOKEN (STR_PLATFORM_INFO_SYSCLK_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* Initialize the container for dynamic opcodes */
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  /* Create Hii Extend Label OpCode as the start opcode */
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  ASSERT (StartLabel != NULL);
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  /* Create Hii Extend Label OpCode as the end opcode */
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  ASSERT (EndLabel != NULL);
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  if (IsSlaveSocketActive ()) {
> +    /* Create the inter socket link text string */
> +    UnicodeSPrint (
> +      Str,
> +      sizeof (Str),
> +      L"Width x%d / Speed %a",
> +      PlatformHob->Link2PWidth[0],
> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[0])
> +      );
> +
> +    HiiSetString (
> +      mHiiHandle,
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE),
> +      Str,
> +      NULL
> +      );
> +
> +    HiiCreateTextOpCode (
> +      StartOpCodeHandle,
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0),
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0),
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE)
> +      );
> +
> +    UnicodeSPrint (
> +      Str,
> +      sizeof (Str),
> +      L"Width x%d / Speed %a",
> +      PlatformHob->Link2PWidth[1],
> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[1])
> +      );
> +
> +    HiiSetString (
> +      mHiiHandle,
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE),
> +      Str,
> +      NULL
> +      );
> +
> +    HiiCreateTextOpCode (
> +      StartOpCodeHandle,
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1),
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1),
> +      STRING_TOKEN (STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE)
> +      );
> +  }
> +
> +  HiiUpdateForm (
> +    mHiiHandle,                 // HII handle
> +    &gPlatformInfoFormSetGuid,  // Formset GUID
> +    PLATFORM_INFO_FORM_ID,      // Form ID
> +    StartOpCodeHandle,          // Label for where to insert opcodes
> +    EndOpCodeHandle             // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformInfoUnload (
> +  VOID
> +  )
> +{
> +  if (mDriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mPlatformInfoHiiVendorDevicePath,
> +           NULL
> +           );
> +    mDriverHandle = NULL;
> +  }
> +
> +  if (mHiiHandle != NULL) {
> +    HiiRemovePackages (mHiiHandle);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +PlatformInfoEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mDriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mPlatformInfoHiiVendorDevicePath,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  //
> +  // Publish our HII data
> +  //
> +  mHiiHandle = HiiAddPackages (
> +                 &gPlatformInfoFormSetGuid,
> +                 mDriverHandle,
> +                 PlatformInfoDxeStrings,
> +                 VfrBin,
> +                 NULL
> +                 );
> +  if (mHiiHandle == NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mPlatformInfoHiiVendorDevicePath,
> +           NULL
> +           );
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Status = UpdatePlatformInfoScreen (mHiiHandle);
> +  if (EFI_ERROR (Status)) {
> +    PlatformInfoUnload ();
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a %d Fail to update the platform info screen \n",
> +      __FUNCTION__,
> +      __LINE__
> +      ));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
> new file mode 100644
> index 000000000000..235d104c217f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/VfrStrings.uni
> @@ -0,0 +1,56 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US  "English"
> +
> +#string STR_PLATFORM_INFO_FORM                      #language en-US "Platform Board Information"
> +#string STR_PLATFORM_INFO_FORM_HELP                 #language en-US "Platform Board Information"
> +
> +#string STR_PLATFORM_INFO_SEPERATE_LINE             #language en-US ""
> +
> +#string STR_PLATFORM_INFO_BOARD                     #language en-US "Board"
> +#string STR_PLATFORM_INFO_BOARD_VALUE               #language en-US "Mt. Jade"
> +
> +#string STR_PLATFORM_INFO_SCPVER                    #language en-US "SCP FW Version"
> +#string STR_PLATFORM_INFO_SCPVER_VALUE              #language en-US "0"
> +
> +#string STR_PLATFORM_INFO_RCVER                     #language en-US "Reference Code version"
> +#string STR_PLATFORM_INFO_RCVER_VALUE               #language en-US "0"
> +
> +#string STR_PLATFORM_INFO_SCPBUILD                  #language en-US "SCP FW Build"
> +#string STR_PLATFORM_INFO_SCPBUILD_VALUE            #language en-US "0"
> +
> +#string STR_PLATFORM_INFO_CPUINFO                   #language en-US "CPU"
> +#string STR_PLATFORM_INFO_CPUINFO_VALUE             #language en-US " "
> +
> +#string STR_PLATFORM_INFO_CPUCLK                    #language en-US "CPU Clock"
> +#string STR_PLATFORM_INFO_CPUCLK_VALUE              #language en-US "0MHz"
> +
> +#string STR_PLATFORM_INFO_PCPCLK                    #language en-US "PCP Clock"
> +#string STR_PLATFORM_INFO_PCPCLK_VALUE              #language en-US "0MHz"
> +
> +#string STR_PLATFORM_INFO_L1ICACHE                  #language en-US "L1I CACHE"
> +#string STR_PLATFORM_INFO_L1ICACHE_VALUE            #language en-US "0KB"
> +
> +#string STR_PLATFORM_INFO_L1DCACHE                  #language en-US "L1D CACHE"
> +#string STR_PLATFORM_INFO_L1DCACHE_VALUE            #language en-US "0KB"
> +
> +#string STR_PLATFORM_INFO_L2CACHE                   #language en-US "L2 CACHE"
> +#string STR_PLATFORM_INFO_L2CACHE_VALUE             #language en-US "0KB"
> +
> +#string STR_PLATFORM_INFO_SOCCLK                    #language en-US "SOC Clock"
> +#string STR_PLATFORM_INFO_SOCCLK_VALUE              #language en-US "0MHz"
> +
> +#string STR_PLATFORM_INFO_SYSCLK                    #language en-US "Sys Clock"
> +#string STR_PLATFORM_INFO_SYSCLK_VALUE              #language en-US "0MHz"
> +
> +#string STR_PLATFORM_INFO_AHBCLK                    #language en-US "AHB Clock"
> +#string STR_PLATFORM_INFO_AHBCLK_VALUE              #language en-US "0MHz"
> +
> +#string STR_CPU_FORM_INTER_SOCKET_LINK0             #language en-US "Inter Socket Connection: Link 0"
> +#string STR_CPU_FORM_INTER_SOCKET_LINK0_VALUE       #language en-US ""
> +#string STR_CPU_FORM_INTER_SOCKET_LINK1             #language en-US "Inter Socket Connection: Link 1"
> +#string STR_CPU_FORM_INTER_SOCKET_LINK1_VALUE       #language en-US ""
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
@ 2021-06-07 23:14   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:14 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:15 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Provide memory screen with below info:
> * Memory total capacity
> * Memory RAS and Performance Configuration
> * Per DIMM Information
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Platform/Ampere/JadePkg/Jade.dsc                                          |    1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                          |    1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf           |   59 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h          |  168 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h            |   47 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr                  |   62 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c        |  394 ++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c          | 1325 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni           |    9 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni      |    9 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni |   64 +
>  11 files changed, 2139 insertions(+)
> 
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index b5edb673abba..75b3ece3817e 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -179,3 +179,4 @@ [Components.common]
>    # HII
>    #
>    Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 6dd759322d9d..e71f3e79e6b3 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -354,5 +354,6 @@ [FV.FvMain]
>    # HII
>    #
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
> new file mode 100644
> index 000000000000..2328051c6e1a
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
> @@ -0,0 +1,59 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = MemInfoDxe
> +  MODULE_UNI_FILE                = MemInfoDxe.uni
> +  FILE_GUID                      = D9EFCEFE-189B-4599-BB07-04F0A8DF5C2F
> +  MODULE_TYPE                    = DXE_DRIVER
> +  ENTRY_POINT                    = MemInfoScreenInitialize
> +
> +[Sources]
> +  MemInfoNvramLib.c
> +  MemInfoScreen.c
> +  MemInfoScreen.h
> +  MemInfoScreenStrings.uni
> +  NVDataStruc.h
> +  Vfr.vfr
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  BaseLib
> +  DevicePathLib
> +  HiiLib
> +  HobLib
> +  MemoryAllocationLib
> +  NVParamLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Guids]
> +  gEfiIfrTianoGuid                              ## PRODUCES ## UNDEFINED
> +  gPlatformManagerFormsetGuid
> +  gPlatformHobGuid
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +
> +[Depex]
> +  TRUE
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  MemInfoDxeExtra.uni
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
> new file mode 100644
> index 000000000000..546f554f8fb2
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.h
> @@ -0,0 +1,168 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef MEM_INFO_SCREEN_H_
> +#define MEM_INFO_SCREEN_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigKeyword.h>
> +#include <Protocol/HiiConfigRouting.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>
> +
> +#include "NVDataStruc.h"
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 VfrBin[];

MemInfoVfrBin?

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 MemInfoDxeStrings[];
> +
> +enum DDR_ECC_MODE {
> +  ECC_DISABLE = 0,
> +  ECC_SECDED,
> +  SYMBOL_ECC
> +};
> +
> +enum DDR_ERROR_CTRL_MODE_DE {
> +  ERRCTLR_DE_DISABLE = 0,
> +  ERRCTLR_DE_ENABLE,
> +};
> +
> +enum DDR_ERROR_CTRL_MODE_FI {
> +  ERRCTLR_FI_DISABLE = 0,
> +  ERRCTLR_FI_ENABLE,
> +};
> +
> +#define MEM_INFO_DDR_SPEED_SEL_OFFSET                     OFFSET_OF (MEM_INFO_VARSTORE_DATA, DDRSpeedSel)
> +#define MEM_INFO_ECC_MODE_SEL_OFFSET                      OFFSET_OF (MEM_INFO_VARSTORE_DATA, EccMode)
> +#define MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET              OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_DE)
> +#define MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET              OFFSET_OF (MEM_INFO_VARSTORE_DATA, ErrCtrl_FI)
> +#define MEM_INFO_ERR_SLAVE_32BIT_OFFSET                   OFFSET_OF (MEM_INFO_VARSTORE_DATA, Slave32bit)
> +#define MEM_INFO_DDR_SCRUB_OFFSET                         OFFSET_OF (MEM_INFO_VARSTORE_DATA, ScrubPatrol)
> +#define MEM_INFO_DDR_DEMAND_SCRUB_OFFSET                  OFFSET_OF (MEM_INFO_VARSTORE_DATA, DemandScrub)
> +#define MEM_INFO_DDR_WRITE_CRC_OFFSET                     OFFSET_OF (MEM_INFO_VARSTORE_DATA, WriteCrc)
> +#define MEM_INFO_FGR_MODE_OFFSET                          OFFSET_OF (MEM_INFO_VARSTORE_DATA, FGRMode)
> +#define MEM_INFO_REFRESH2X_MODE_OFFSET                    OFFSET_OF (MEM_INFO_VARSTORE_DATA, Refresh2x)
> +#define MEM_INFO_NVDIMM_MODE_SEL_OFFSET                   OFFSET_OF (MEM_INFO_VARSTORE_DATA, NvdimmModeSel)
> +
> +#define MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE            SIGNATURE_32 ('M', 'E', 'M', 'i')
> +
> +#define MEM_INFO_DDR_SPEED_SEL_QUESTION_ID                       0x8001
> +#define MEM_INFO_FORM_PERFORMANCE_QUESTION_ID                    0x8002
> +#define MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID                0x8003
> +#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID        0x8004
> +#define MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID        0x8005
> +#define MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID                     0x8006
> +#define MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID                    0x8007
> +#define MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID                    0x8008
> +#define MEM_INFO_DDR_WRITE_CRC_QUESTION_ID                       0x8009
> +#define MEM_INFO_FGR_MODE_QUESTION_ID                            0x800A
> +#define MEM_INFO_REFRESH2X_MODE_QUESTION_ID                      0x800B
> +#define MEM_INFO_FORM_NVDIMM_QUESTION_ID                         0x800C
> +#define MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID                0x800D
> +
> +#define DDR_DEFAULT_SCRUB_PATROL_DURATION 24
> +#define DDR_DEFAULT_DEMAND_SCRUB          1
> +#define DDR_DEFAULT_WRITE_CRC             0
> +#define DDR_DEFAULT_FGR_MODE              0
> +#define DDR_DEFAULT_REFRESH2X_MODE        0
> +#define DDR_DEFAULT_NVDIMM_MODE_SEL       3
> +
> +#define DDR_FGR_MODE_GET(Value)           ((Value) & 0x3) /* Bit 0, 1 */
> +#define DDR_FGR_MODE_SET(Dst, Src)        do { Dst = (((Dst) & ~0x3) | ((Src) & 0x3)); } while (0)
> +
> +#define DDR_REFRESH_2X_GET(Value)         ((Value) & 0x10000) >> 16 /* Bit 16 only */
> +#define DDR_REFRESH_2X_SET(Dst, Src)      do { Dst = (((Dst) & ~0x10000) | ((Src) & 0x1) << 16); } while (0)
> +
> +#define DDR_NVDIMM_MODE_SEL_MASK         0x7FFFFFFF
> +#define DDR_NVDIMM_MODE_SEL_VALID_BIT    BIT31
> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE             DriverHandle;
> +  EFI_HII_HANDLE         HiiHandle;
> +  MEM_INFO_VARSTORE_DATA VarStoreConfig;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
> +  EFI_HII_STRING_PROTOCOL             *HiiString;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
> +  EFI_FORM_BROWSER2_PROTOCOL          *FormBrowser2;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} MEM_INFO_SCREEN_PRIVATE_DATA;
> +
> +#define MEM_INFO_SCREEN_PRIVATE_FROM_THIS(a)  CR (a, MEM_INFO_SCREEN_PRIVATE_DATA, ConfigAccess, MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +EFI_STATUS
> +MemInfoScreenInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  );
> +
> +EFI_STATUS
> +MemInfoScreenUnload (
> +  IN EFI_HANDLE ImageHandle
> +  );
> +
> +EFI_STATUS
> +MemInfoNvparamGet (
> +  OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
> +  );
> +
> +EFI_STATUS
> +MemInfoNvparamSet (
> +  IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
> +  );
> +
> +#endif /* MEM_INFO_SCREEN_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
> new file mode 100644
> index 000000000000..7a6e776e7f4e
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/NVDataStruc.h
> @@ -0,0 +1,47 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef NVDATASTRUC_H_
> +#define NVDATASTRUC_H_
> +
> +#define MEM_INFO_VARSTORE_NAME        L"MemInfoIfrNVData"
> +#define MEM_INFO_VARSTORE_ID          0x1234
> +#define MEM_INFO_FORM_ID              0x1235
> +#define MEM_INFO_FORM_PERFORMANCE_ID  0x1236
> +#define MEM_INFO_FORM_NVDIMM_ID       0x1237
> +#define MEM_INFO_FORM_SET_GUID                    { 0xd58338ee, 0xe9f7, 0x4d8d, { 0xa7, 0x08, 0xdf, 0xb2, 0xc6, 0x66, 0x1d, 0x61 } }
> +#define MEM_INFO_FORM_SET_PERFORMANCE_GUID        { 0x4a072c78, 0x42f9, 0x11ea, { 0xb7, 0x7f, 0x2e, 0x28, 0xce, 0x88, 0x12, 0x62 } }
> +
> +#pragma pack(1)
> +
> +//
> +// NV data structure definition
> +//
> +typedef struct {
> +  UINT32 DDRSpeedSel;
> +  UINT32 EccMode;
> +  UINT32 ErrCtrl_DE;
> +  UINT32 ErrCtrl_FI;
> +  UINT32 Slave32bit;
> +  UINT32 ScrubPatrol;
> +  UINT32 DemandScrub;
> +  UINT32 WriteCrc;
> +  UINT32 FGRMode;
> +  UINT32 Refresh2x;
> +  UINT32 NvdimmModeSel;
> +} MEM_INFO_VARSTORE_DATA;
> +
> +//
> +// Labels definition
> +//
> +#define LABEL_UPDATE             0x2223
> +#define LABEL_END                0x2224
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..6c7ccb7375d0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/Vfr.vfr
> @@ -0,0 +1,62 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/PlatformManagerHii.h>
> +#include "NVDataStruc.h"
> +
> +formset
> +  guid    = MEM_INFO_FORM_SET_GUID,
> +  title   = STRING_TOKEN(STR_MEM_INFO_FORM),
> +  help    = STRING_TOKEN(STR_MEM_INFO_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  //
> +  // Define a variable Storage
> +  //
> +  varstore MEM_INFO_VARSTORE_DATA,
> +    varid = MEM_INFO_VARSTORE_ID,
> +    name  = MemInfoIfrNVData,
> +    guid  = MEM_INFO_FORM_SET_GUID;
> +
> +  form
> +    formid = MEM_INFO_FORM_ID,
> +    title = STRING_TOKEN(STR_MEM_INFO_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_MEM_INFO_FORM);
> +
> +    label LABEL_UPDATE;
> +    // dynamic content here
> +    label LABEL_END;
> +
> +  endform;
> +
> +  form
> +    formid = MEM_INFO_FORM_PERFORMANCE_ID,
> +    title = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_MEM_INFO_PERFORMANCE_FORM);
> +
> +    label LABEL_UPDATE;
> +    // dynamic content here
> +    label LABEL_END;
> +
> +  endform;
> +
> +  form
> +    formid = MEM_INFO_FORM_NVDIMM_ID,
> +    title = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_MEM_INFO_NVDIMM_FORM);
> +
> +    label LABEL_UPDATE;
> +    // dynamic content here
> +    label LABEL_END;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
> new file mode 100644
> index 000000000000..c83f489f4078
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoNvramLib.c
> @@ -0,0 +1,394 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/NVParamLib.h>
> +
> +#include "MemInfoScreen.h"
> +#include "NVParamDef.h"
> +
> +#define DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT    0
> +#define DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK     0x1
> +
> +#define DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT    1
> +#define DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK     0x2
> +
> +/**
> +  This is function collects meminfo from NVParam
> +
> +  @param  Data                  The buffer to return the contents.
> +
> +  @retval EFI_SUCCESS           Get response data successfully.
> +  @retval Other value           Failed to get meminfo from NVParam
> +**/
> +EFI_STATUS
> +MemInfoNvparamGet (
> +  OUT MEM_INFO_VARSTORE_DATA *VarStoreConfig
> +  )
> +{
> +  UINT32     Value;
> +  EFI_STATUS Status;
> +
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_SPEED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->DDRSpeedSel = 0; /* Default auto mode */
> +  } else {
> +    VarStoreConfig->DDRSpeedSel = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_ECC_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->EccMode = ECC_SECDED; /* Default enable */
> +  } else {
> +    VarStoreConfig->EccMode = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_ERRCTRL,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->ErrCtrl_DE = ERRCTLR_DE_ENABLE;
> +    VarStoreConfig->ErrCtrl_FI = ERRCTLR_FI_ENABLE;
> +  } else {
> +    VarStoreConfig->ErrCtrl_DE = (Value & DDR_NVPARAM_ERRCTRL_DE_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT;
> +    VarStoreConfig->ErrCtrl_FI = (Value & DDR_NVPARAM_ERRCTRL_FI_FIELD_MASK) >> DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_SLAVE_32BIT_MEM_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->Slave32bit = 0; /* Default disabled */
> +  } else {
> +    VarStoreConfig->Slave32bit = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_SCRUB_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->ScrubPatrol = DDR_DEFAULT_SCRUB_PATROL_DURATION;
> +  } else {
> +    VarStoreConfig->ScrubPatrol = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_WR_BACK_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->DemandScrub = DDR_DEFAULT_DEMAND_SCRUB;
> +  } else {
> +    VarStoreConfig->DemandScrub = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_CRC_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->WriteCrc = DDR_DEFAULT_WRITE_CRC;
> +  } else {
> +    VarStoreConfig->WriteCrc = Value;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_REFRESH_GRANULARITY,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->FGRMode = DDR_DEFAULT_FGR_MODE;
> +    VarStoreConfig->Refresh2x = DDR_DEFAULT_REFRESH2X_MODE;
> +  } else {
> +    VarStoreConfig->FGRMode = DDR_FGR_MODE_GET (Value);
> +    VarStoreConfig->Refresh2x = DDR_REFRESH_2X_GET (Value);
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_NVDIMM_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->NvdimmModeSel = DDR_DEFAULT_NVDIMM_MODE_SEL;
> +  } else {
> +    VarStoreConfig->NvdimmModeSel = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This is function stores meminfo to corresponding NVParam
> +
> +  @param  VarStoreConfig         The contents for the variable.
> +
> +  @retval EFI_SUCCESS            Set data successfully.
> +  @retval Other value            Failed to set meminfo to NVParam
> +
> +**/
> +EFI_STATUS
> +MemInfoNvparamSet (
> +  IN MEM_INFO_VARSTORE_DATA *VarStoreConfig
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value, TmpValue, Value2, Update;
> +
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  /* Set DDR speed */
> +  Status = NVParamGet (
> +             NV_SI_DDR_SPEED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != VarStoreConfig->DDRSpeedSel) {
> +    Status = NVParamSet (
> +               NV_SI_DDR_SPEED,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               VarStoreConfig->DDRSpeedSel
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Set ECC mode */
> +  Status = NVParamGet (
> +             NV_SI_DDR_ECC_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != VarStoreConfig->EccMode) {
> +    Status = NVParamSet (
> +               NV_SI_DDR_ECC_MODE,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               VarStoreConfig->EccMode
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Set ErrCtrl */
> +  TmpValue = (VarStoreConfig->ErrCtrl_DE << DDR_NVPARAM_ERRCTRL_DE_FIELD_SHIFT) |
> +             (VarStoreConfig->ErrCtrl_FI << DDR_NVPARAM_ERRCTRL_FI_FIELD_SHIFT);
> +  Status = NVParamGet (
> +             NV_SI_DDR_ERRCTRL,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != TmpValue ) {
> +    Status = NVParamSet (
> +               NV_SI_DDR_ERRCTRL,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               TmpValue
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Set slave's 32bit region */
> +  TmpValue = VarStoreConfig->Slave32bit;
> +  Status = NVParamGet (
> +             NV_SI_DDR_SLAVE_32BIT_MEM_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != TmpValue ) {
> +    if (TmpValue == 0) {
> +      /* Default is disabled so just clear nvparam */
> +      Status = NVParamClr (
> +                 NV_SI_DDR_SLAVE_32BIT_MEM_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
> +                 );
> +    } else {
> +      Status = NVParamSet (
> +                 NV_SI_DDR_SLAVE_32BIT_MEM_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 TmpValue
> +                 );
> +    }
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Set Scrub patrol */
> +  TmpValue = VarStoreConfig->ScrubPatrol;
> +  Status = NVParamGet (
> +             NV_SI_DDR_SCRUB_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != TmpValue ) {
> +    if (TmpValue == DDR_DEFAULT_SCRUB_PATROL_DURATION) {
> +      Status = NVParamClr (
> +                 NV_SI_DDR_SCRUB_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
> +                 );
> +    } else {
> +      Status = NVParamSet (
> +                 NV_SI_DDR_SCRUB_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 TmpValue
> +                 );
> +    }
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Demand Scrub */
> +  TmpValue = VarStoreConfig->DemandScrub;
> +  Status = NVParamGet (
> +             NV_SI_DDR_WR_BACK_EN,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != TmpValue ) {
> +    if (TmpValue == DDR_DEFAULT_DEMAND_SCRUB) {
> +      Status = NVParamClr (
> +                 NV_SI_DDR_WR_BACK_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC
> +                 );
> +    } else {
> +      Status = NVParamSet (
> +                 NV_SI_DDR_WR_BACK_EN,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU |NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 TmpValue
> +                 );
> +    }
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Write CRC */
> +  TmpValue = VarStoreConfig->WriteCrc;
> +  Status = NVParamGet (
> +             NV_SI_DDR_CRC_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status) || Value != TmpValue ) {
> +    if (TmpValue == DDR_DEFAULT_WRITE_CRC) {
> +      Status = NVParamClr (
> +                 NV_SI_DDR_CRC_MODE,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
> +                 );
> +    } else {
> +      Status = NVParamSet (
> +                 NV_SI_DDR_CRC_MODE,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 TmpValue
> +                 );
> +    }
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Write FGR/Refresh2X */
> +  Value = 0;
> +  Update = 0;
> +  TmpValue = VarStoreConfig->FGRMode;
> +  Status = NVParamGet (
> +             NV_SI_DDR_REFRESH_GRANULARITY,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  Value2 = DDR_FGR_MODE_GET (Value);
> +  if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_FGR_MODE)
> +      || Value2 != TmpValue)
> +  {

{ on line before

> +    DDR_FGR_MODE_SET (Value, TmpValue);
> +    Update = 1;
> +  }
> +
> +  Value2 = DDR_REFRESH_2X_GET (Value);
> +  TmpValue = VarStoreConfig->Refresh2x;
> +  if ((EFI_ERROR (Status) && TmpValue != DDR_DEFAULT_REFRESH2X_MODE)
> +      || Value2 != TmpValue)
> +  {

{ on line before

> +    DDR_REFRESH_2X_SET (Value, TmpValue);
> +    Update = 1;
> +  }
> +
> +  if (Update == 1) {
> +    Status = NVParamSet (
> +               NV_SI_DDR_REFRESH_GRANULARITY,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  /* Write NVDIMM-N Mode selection */
> +  Value = 0;
> +  TmpValue = VarStoreConfig->NvdimmModeSel;
> +  Status = NVParamGet (
> +             NV_SI_NVDIMM_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  Value2 = Value & DDR_NVDIMM_MODE_SEL_MASK; /* Mask out valid bit */
> +  if (EFI_ERROR (Status) || Value2 != TmpValue ) {
> +    if (TmpValue == DDR_DEFAULT_NVDIMM_MODE_SEL) {
> +      Status = NVParamClr (
> +                 NV_SI_NVDIMM_MODE,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC
> +                 );
> +    } else {
> +      Value = TmpValue | DDR_NVDIMM_MODE_SEL_VALID_BIT; /* Add valid bit */
> +      Status = NVParamSet (
> +                 NV_SI_NVDIMM_MODE,
> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +                 NV_PERM_BIOS | NV_PERM_MANU,
> +                 Value
> +                 );
> +    }
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
> new file mode 100644
> index 000000000000..75f743b824e0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreen.c
> @@ -0,0 +1,1325 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "MemInfoScreen.h"
> +
> +#define MAX_STRING_SIZE     64
> +#define GB_SCALE_FACTOR     (1024*1024*1024)
> +#define MB_SCALE_FACTOR     (1024*1024)
> +
> +EFI_GUID gMemInfoFormSetGuid = MEM_INFO_FORM_SET_GUID;
> +
> +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    MEM_INFO_FORM_SET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +EFI_HANDLE                   DriverHandle = NULL;
> +MEM_INFO_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Request,
> +  OUT      EFI_STRING                     *Progress,
> +  OUT      EFI_STRING                     *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  MEM_INFO_SCREEN_PRIVATE_DATA    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  CHAR16                          *StrPointer;
> +  BOOLEAN                         AllocatedRequest;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +
> +  //
> +  // Get Buffer Storage data from EFI variable.
> +  // Try to get the current setting from variable.
> +  //
> +  BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
> +  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  if (Request == NULL) {
> +    //
> +    // Request is set to NULL, construct full request string.
> +    //
> +
> +    //
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (&gMemInfoFormSetGuid, MEM_INFO_VARSTORE_NAME, PrivateData->DriverHandle);
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +    ConfigRequestHdr = NULL;
> +  } else {
> +    //
> +    // Check routing data in <ConfigHdr>.
> +    // Note: if only one Storage is used, then this checking could be skipped.
> +    //
> +    if (!HiiIsConfigHdrMatch (Request, &gMemInfoFormSetGuid, NULL)) {
> +      return EFI_NOT_FOUND;
> +    }
> +
> +    //
> +    // Set Request to the unified request string.
> +    //
> +    ConfigRequest = Request;
> +
> +    //
> +    // Check whether Request includes Request Element.
> +    //
> +    if (StrStr (Request, L"OFFSET") == NULL) {
> +      //
> +      // Check Request Element does exist in Request String
> +      //
> +      StrPointer = StrStr (Request, L"PATH");
> +      if (StrPointer == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +      if (StrStr (StrPointer, L"&") == NULL) {
> +        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
> +        ConfigRequest    = AllocateZeroPool (Size);
> +        ASSERT (ConfigRequest != NULL);
> +        AllocatedRequest = TRUE;
> +        UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", Request, (UINT64)BufferSize);
> +      }
> +    }
> +  }
> +
> +  //
> +  // Check if requesting Name/Value storage
> +  //
> +  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    Status = EFI_SUCCESS;
> +  } else {
> +    //
> +    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +    //
> +    Status = HiiConfigRouting->BlockToConfig (
> +                                 HiiConfigRouting,
> +                                 ConfigRequest,
> +                                 (UINT8 *)&PrivateData->VarStoreConfig,
> +                                 BufferSize,
> +                                 Results,
> +                                 Progress
> +                                 );
> +  }
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +  }
> +
> +  if (ConfigRequestHdr != NULL) {
> +    FreePool (ConfigRequestHdr);
> +  }
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Configuration,
> +  OUT      EFI_STRING                     *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  MEM_INFO_SCREEN_PRIVATE_DATA    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = MEM_INFO_SCREEN_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &gMemInfoFormSetGuid, NULL)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get Buffer Storage data from NVParam
> +  //
> +  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Check if configuring Name/Value storage
> +  //
> +  if (StrStr (Configuration, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (MEM_INFO_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)&PrivateData->VarStoreConfig,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store Buffer Storage back to NVParam
> +  //
> +  Status = MemInfoNvparamSet (&PrivateData->VarStoreConfig);
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +  @retval EFI_SUCCESS            The callback successfully handled the action.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
> +                                 callback.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
> +       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
> +      || (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  switch (Action) {
> +  case EFI_BROWSER_ACTION_FORM_OPEN:
> +  case EFI_BROWSER_ACTION_FORM_CLOSE:
> +    break;
> +
> +  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
> +  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
> +  {
> +    switch (QuestionId) {
> +    case MEM_INFO_DDR_SPEED_SEL_QUESTION_ID:
> +      //
> +      // DDR speed selection default to auto
> +      //
> +      Value->u32 = 0;
> +      break;
> +
> +    case MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID:
> +      //
> +      // ECC mode default to be enabled
> +      //
> +      Value->u32 = ECC_SECDED;
> +      break;
> +
> +    case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID:
> +      //
> +      // ErrCtrl_DE default to be enabled
> +      //
> +      Value->u32 = ERRCTLR_DE_ENABLE;
> +      break;
> +
> +    case MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID:
> +      //
> +      // ErrCtrl_FI default to be enabled
> +      //
> +      Value->u32 = ERRCTLR_FI_ENABLE;
> +      break;
> +
> +    case MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID:
> +      //
> +      // Slave's 32bit region to be disabled
> +      //
> +      Value->u32 = 0;
> +      break;
> +
> +    case MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_SCRUB_PATROL_DURATION;
> +      break;
> +
> +    case MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_DEMAND_SCRUB;
> +      break;
> +
> +    case MEM_INFO_DDR_WRITE_CRC_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_WRITE_CRC;
> +      break;
> +
> +    case MEM_INFO_FGR_MODE_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_FGR_MODE;
> +      break;
> +
> +    case MEM_INFO_REFRESH2X_MODE_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_REFRESH2X_MODE;
> +      break;
> +
> +    case MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID:
> +      Value->u32 = DDR_DEFAULT_NVDIMM_MODE_SEL;
> +      break;
> +    }
> +  }
> +  break;
> +
> +  case EFI_BROWSER_ACTION_RETRIEVE:
> +  case EFI_BROWSER_ACTION_CHANGING:
> +  case EFI_BROWSER_ACTION_SUBMITTED:
> +    break;
> +
> +  default:
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +MemInfoMainScreen (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
> +  EFI_STATUS                   Status;
> +  VOID                         *StartOpCodeHandle;
> +  VOID                         *OptionsOpCodeHandle;
> +  VOID                         *OptionsOpCodeHandle1;
> +  EFI_IFR_GUID_LABEL           *StartLabel;
> +  EFI_STRING_ID                StringId;
> +  VOID                         *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL           *EndLabel;
> +  CHAR16                       Str[MAX_STRING_SIZE], Str1[MAX_STRING_SIZE];
> +  EFI_HOB_RESOURCE_DESCRIPTOR  *ResHob;
> +  PLATFORM_DIMM_INFO           *DimmInfo;
> +  UINT64                       Size;
> +  UINTN                        Count;
> +
> +  //
> +  // Get Buffer Storage data from EFI variable
> +  //
> +  Status = MemInfoNvparamGet (&PrivateData->VarStoreConfig);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = EFI_SUCCESS;
> +
> +  /* Update Total memory */
> +  UnicodeSPrint (Str, sizeof (Str), L"%d GB", PlatformHob->DramInfo.TotalSize / GB_SCALE_FACTOR);
> +  HiiSetString (
> +    PrivateData->HiiHandle,
> +    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* Update effective memory */
> +  Size = 0;
> +  ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
> +  while (ResHob != NULL) {
> +    if ((ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)) {
> +      Size += ResHob->ResourceLength;
> +    }
> +    ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
> +  }
> +  UnicodeSPrint (Str, sizeof (Str), L"%d GB", Size / GB_SCALE_FACTOR);
> +  HiiSetString (
> +    PrivateData->HiiHandle,
> +    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  /* Update current DDR speed */
> +  UnicodeSPrint (Str, sizeof (Str), L"%d MHz", PlatformHob->DramInfo.MaxSpeed);
> +  HiiSetString (
> +    PrivateData->HiiHandle,
> +    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Option OpCode to display speed configuration
> +  //
> +  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (OptionsOpCodeHandle != NULL);
> +
> +  //
> +  // Create Option OpCode to display FGR mode configuration
> +  //
> +  OptionsOpCodeHandle1 = HiiAllocateOpCodeHandle ();
> +  ASSERT (OptionsOpCodeHandle1 != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  //
> +  // Create a total mem title
> +  //
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
> +    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM),
> +    STRING_TOKEN (STR_MEM_INFO_TOTAL_MEM_VALUE)
> +    );
> +
> +  //
> +  // Create a effective mem title
> +  //
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
> +    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM),
> +    STRING_TOKEN (STR_MEM_INFO_EFFECT_MEM_VALUE)
> +    );
> +
> +  //
> +  // Create a current speed title
> +  //
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
> +    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED),
> +    STRING_TOKEN (STR_MEM_INFO_CURRENT_SPEED_VALUE)
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE0),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    0
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE1),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2133
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE2),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2400
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE3),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2666
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE4),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2933
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_VALUE5),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    3200
> +    );
> +
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_DDR_SPEED_SEL_QUESTION_ID,                  // Question ID (or call it "key")
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_DDR_SPEED_SEL_OFFSET,               // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_PROMPT),     // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_SPEED_SELECT_HELP),       // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
> +    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
> +    OptionsOpCodeHandle,                                 // Option Opcode list
> +    NULL                                                 // Default Opcode is NULl
> +    );
> +
> +  if (IsSlaveSocketActive ()) {
> +    /* Display enable slave's 32bit region */
> +    HiiCreateCheckBoxOpCode (
> +      StartOpCodeHandle,                                    // Container for dynamic created opcodes
> +      MEM_INFO_DDR_SLAVE_32BIT_QUESTION_ID,                 // Question ID
> +      MEM_INFO_VARSTORE_ID,                                 // VarStore ID
> +      (UINT16)MEM_INFO_ERR_SLAVE_32BIT_OFFSET,              // Offset in Buffer Storage
> +      STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT), // Question prompt text
> +      STRING_TOKEN (STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP),   // Question help text
> +      EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +      0,
> +      NULL
> +      );
> +  }
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle1,
> +    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE0),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    0
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle1,
> +    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE1),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    1
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle1,
> +    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_VALUE2),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2
> +    );
> +
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_FGR_MODE_QUESTION_ID,                       // Question ID (or call it "key")
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_FGR_MODE_OFFSET,                    // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_PROMPT),         // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_FGR_MODE_HELP),           // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
> +    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
> +    OptionsOpCodeHandle1,                                // Option Opcode list
> +    NULL                                                 // Default Opcode is NULl
> +    );
> +
> +  //
> +  // Create a Goto OpCode to ras memory configuration
> +  //
> +  HiiCreateGotoOpCode (
> +    StartOpCodeHandle,                                 // Container for dynamic created opcodes
> +    MEM_INFO_FORM_PERFORMANCE_ID,                      // Target Form ID
> +    STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM),      // Prompt text
> +    STRING_TOKEN (STR_MEM_INFO_PERFORMANCE_FORM_HELP), // Help text
> +    0,                                                 // Question flag
> +    MEM_INFO_FORM_PERFORMANCE_QUESTION_ID              // Question ID
> +    );
> +
> +  //
> +  // Create a Goto OpCode to nvdimm-n configuration
> +  //
> +  HiiCreateGotoOpCode (
> +    StartOpCodeHandle,                            // Container for dynamic created opcodes
> +    MEM_INFO_FORM_NVDIMM_ID,                      // Target Form ID
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM),      // Prompt text
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_FORM_HELP), // Help text
> +    0,                                            // Question flag
> +    MEM_INFO_FORM_NVDIMM_QUESTION_ID              // Question ID
> +    );
> +
> +  //
> +  // Display DIMM list info
> +  //
> +  HiiCreateSubTitleOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_DIMM_INFO),
> +    0,
> +    0,
> +    0
> +    );
> +
> +  for (Count = 0; Count < PlatformHob->DimmList.BoardDimmSlots; Count++) {
> +    DimmInfo = &PlatformHob->DimmList.Dimm[Count].Info;
> +    switch (DimmInfo->DimmType) {
> +    case UDIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"UDIMM");
> +      break;
> +
> +    case RDIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"RDIMM");
> +      break;
> +
> +    case SODIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"SODIMM");
> +      break;
> +
> +    case LRDIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"LRDIMM");
> +      break;
> +
> +    case RSODIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"RSODIMM");
> +      break;
> +
> +    case NVRDIMM:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"NV-RDIMM");
> +      break;
> +
> +    default:
> +      UnicodeSPrint (Str, sizeof (Str), L"Unknown Type");
> +    }
> +    if (DimmInfo->DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
> +      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: %d GB %s Installed&Operational", Count + 1, DimmInfo->DimmSize, Str);
> +    } else if (DimmInfo->DimmStatus == DIMM_NOT_INSTALLED) {
> +      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Not Installed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
> +    } else if (DimmInfo->DimmStatus == DIMM_INSTALLED_NONOPERATIONAL) {
> +      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Non-Operational", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
> +    } else {
> +      UnicodeSPrint (Str1, sizeof (Str1), L"Slot %2d: Installed&Failed", Count + 1, PlatformHob->DimmList.Dimm[Count].NodeId);
> +    }
> +
> +    StringId = HiiSetString (PrivateData->HiiHandle, 0, Str1, NULL);
> +
> +    HiiCreateSubTitleOpCode (
> +      StartOpCodeHandle,
> +      StringId,
> +      0,
> +      0,
> +      0
> +      );
> +  }
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,  // HII handle
> +    &gMemInfoFormSetGuid,    // Formset GUID
> +    MEM_INFO_FORM_ID,        // Form ID
> +    StartOpCodeHandle,       // Label for where to insert opcodes
> +    EndOpCodeHandle          // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +MemInfoMainPerformanceScreen (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData = mPrivateData;
> +  VOID                         *StartOpCodeHandle;
> +  VOID                         *OptionsEccOpCodeHandle, *OptionsScrubOpCodeHandle;
> +  EFI_IFR_GUID_LABEL           *StartLabel;
> +  VOID                         *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL           *EndLabel;
> +  EFI_STRING_ID                StringId;
> +  CHAR16                       Str[MAX_STRING_SIZE];
> +  UINTN                        Idx;
> +
> +  Status = EFI_SUCCESS;
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  /* Display ECC mode selection */
> +  OptionsEccOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (OptionsEccOpCodeHandle != NULL);
> +
> +  UnicodeSPrint (Str, sizeof (Str), L"Disabled");
> +  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsEccOpCodeHandle,
> +    StringId,
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    0
> +    );
> +
> +  UnicodeSPrint (Str, sizeof (Str), L"SECDED");
> +  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsEccOpCodeHandle,
> +    StringId,
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    1
> +    );
> +
> +  UnicodeSPrint (Str, sizeof (Str), L"Symbol");
> +  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsEccOpCodeHandle,
> +    StringId,
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2
> +    );
> +
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_FORM_PERFORMANCE_ECC_QUESTION_ID,           // Question ID (or call it "key")
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_ECC_MODE_SEL_OFFSET,                // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_PROMPT),       // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ECC_HELP),         // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
> +    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
> +    OptionsEccOpCodeHandle,                              // Option Opcode list
> +    NULL                                                 // Default Opcode is NULl
> +    );
> +
> +  /*
> +   * Display ErrCtrl options
> +   */
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                                    // Container for dynamic created opcodes
> +    MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_DE_QUESTION_ID,    // Question ID
> +    MEM_INFO_VARSTORE_ID,                                 // VarStore ID
> +    (UINT16)MEM_INFO_ERR_CTRL_DE_MODE_SEL_OFFSET,         // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                                    // Container for dynamic created opcodes
> +    MEM_INFO_FORM_PERFORMANCE_ERR_CTRL_FI_QUESTION_ID,    // Question ID
> +    MEM_INFO_VARSTORE_ID,                                 // VarStore ID
> +    (UINT16)MEM_INFO_ERR_CTRL_FI_MODE_SEL_OFFSET,         // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  /* Display Scrub Patrol selection */
> +  OptionsScrubOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (OptionsScrubOpCodeHandle != NULL);
> +
> +  UnicodeSPrint (Str, sizeof (Str), L"Disabled");
> +  StringId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsScrubOpCodeHandle,
> +    StringId,
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    0
> +    );
> +
> +  for (Idx = 1; Idx <= 24; Idx++) {

24?

/
    Leif

> +    UnicodeSPrint (Str, sizeof (Str), L"%d", Idx);
> +    StringId = HiiSetString (
> +                 PrivateData->HiiHandle,
> +                 0,
> +                 Str,
> +                 NULL
> +                 );
> +    HiiCreateOneOfOptionOpCode (
> +      OptionsScrubOpCodeHandle,
> +      StringId,
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_4,
> +      Idx
> +      );
> +  }
> +
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_DDR_SCRUB_PATROL_QUESTION_ID,               // Question ID (or call it "key")
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_DDR_SCRUB_OFFSET,                   // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB),            // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_SCRUB_HELP),       // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
> +    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
> +    OptionsScrubOpCodeHandle,                            // Option Opcode list
> +    NULL                                                 // Default Opcode is NULl
> +    );
> +
> +  /*
> +   * Display Demand Scrub options
> +   */
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                                      // Container for dynamic created opcodes
> +    MEM_INFO_DDR_DEMAND_SCRUB_QUESTION_ID,                  // Question ID
> +    MEM_INFO_VARSTORE_ID,                                   // VarStore ID
> +    (UINT16)MEM_INFO_DDR_DEMAND_SCRUB_OFFSET,               // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  /*
> +   * Display Write CRC options
> +   */
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_DDR_WRITE_CRC_QUESTION_ID,                  // Question ID
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_DDR_WRITE_CRC_OFFSET,               // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_ENABLE_WRITE_CRC_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  /*
> +   * Display CVE-2020-10255 options
> +   */
> +  HiiCreateCheckBoxOpCode (
> +    StartOpCodeHandle,                                 // Container for dynamic created opcodes
> +    MEM_INFO_REFRESH2X_MODE_QUESTION_ID,               // Question ID
> +    MEM_INFO_VARSTORE_ID,                              // VarStore ID
> +    (UINT16)MEM_INFO_REFRESH2X_MODE_OFFSET,            // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_REFRESH2X_MODE_HELP),   // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    0,
> +    NULL
> +    );
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,              // HII handle
> +    &gMemInfoFormSetGuid,                // Formset GUID
> +    MEM_INFO_FORM_PERFORMANCE_ID,        // Form ID
> +    StartOpCodeHandle,                   // Label for where to insert opcodes
> +    EndOpCodeHandle                      // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +  HiiFreeOpCodeHandle (OptionsEccOpCodeHandle);
> +  HiiFreeOpCodeHandle (OptionsScrubOpCodeHandle);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +MemInfoMainNvdimmScreen (
> +  PLATFORM_INFO_HOB  *PlatformHob
> +  )
> +{
> +  EFI_STATUS                   Status;
> +  MEM_INFO_SCREEN_PRIVATE_DATA *PrivateData;
> +  VOID                         *StartOpCodeHandle;
> +  VOID                         *OptionsOpCodeHandle;
> +  EFI_IFR_GUID_LABEL           *StartLabel;
> +  VOID                         *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL           *EndLabel;
> +  CHAR16                       Str[MAX_STRING_SIZE];
> +
> +  Status = EFI_SUCCESS;
> +  PrivateData = mPrivateData;
> +
> +  if (PlatformHob == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  //
> +  // Update Current NVDIMM-N Mode title Socket0
> +  //
> +  switch (PlatformHob->DramInfo.NvdimmMode[0]) {
> +  case 0:
> +    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
> +    break;
> +
> +  case 1:
> +    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
> +    break;
> +
> +  case 2:
> +    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
> +    break;
> +
> +  default:
> +    UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
> +    break;
> +  }
> +
> +  HiiSetString (
> +    PrivateData->HiiHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE),
> +    Str,
> +    NULL
> +    );
> +
> +  HiiCreateTextOpCode (
> +    StartOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0),
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE)
> +    );
> +
> +  //
> +  // Update Current NVDIMM-N Mode title Socket1
> +  //
> +  if (IsSlaveSocketActive ()) {
> +    switch (PlatformHob->DramInfo.NvdimmMode[1]) {
> +    case 0:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-NVDIMM");
> +      break;
> +
> +    case 1:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Non-Hashed");
> +      break;
> +
> +    case 2:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Hashed");
> +      break;
> +
> +    default:
> +      UnicodeSPrint (Str, sizeof (Str), L"%s", L"Unknown");
> +      break;
> +    }
> +
> +    HiiSetString (
> +      PrivateData->HiiHandle,
> +      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE),
> +      Str,
> +      NULL
> +      );
> +
> +    HiiCreateTextOpCode (
> +      StartOpCodeHandle,
> +      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
> +      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1),
> +      STRING_TOKEN (STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE)
> +      );
> +  }
> +  //
> +  // Create Option OpCode to NVDIMM-N Mode Selection
> +  //
> +  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (OptionsOpCodeHandle != NULL);
> +
> +  //
> +  // Create OpCode to NVDIMM-N Mode Selection
> +  //
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    0
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    1
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    2
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    OptionsOpCodeHandle,
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    3
> +    );
> +
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                                   // Container for dynamic created opcodes
> +    MEM_INFO_FORM_NVDIMM_MODE_SEL_QUESTION_ID,           // Question ID (or call it "key")
> +    MEM_INFO_VARSTORE_ID,                                // VarStore ID
> +    (UINT16)MEM_INFO_NVDIMM_MODE_SEL_OFFSET,             // Offset in Buffer Storage
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT),  // Question prompt text
> +    STRING_TOKEN (STR_MEM_INFO_NVDIMM_MODE_SEL_HELP),    // Question help text
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED, // Question flag
> +    EFI_IFR_NUMERIC_SIZE_4,                              // Data type of Question Value
> +    OptionsOpCodeHandle,                                 // Option Opcode list
> +    NULL                                                 // Default Opcode is NULl
> +    );
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,              // HII handle
> +    &gMemInfoFormSetGuid,                // Formset GUID
> +    MEM_INFO_FORM_NVDIMM_ID,             // Form ID
> +    StartOpCodeHandle,                   // Label for where to insert opcodes
> +    EndOpCodeHandle                      // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +  HiiFreeOpCodeHandle (OptionsOpCodeHandle);
> +
> +  return Status;
> +}
> +
> +/**
> +  This function sets up the first elements of the form.
> +  @param  PrivateData            Private data.
> +  @retval EFI_SUCCESS            The form is set up successfully.
> +**/
> +EFI_STATUS
> +MemInfoScreenSetup (
> +  VOID
> +  )
> +{
> +  EFI_STATUS         Status;
> +  VOID               *Hob;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +
> +  /* Get the Platform HOB */
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  if (Hob == NULL) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  Status = MemInfoMainScreen (PlatformHob);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = MemInfoMainPerformanceScreen (PlatformHob);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  Status = MemInfoMainNvdimmScreen (PlatformHob);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +MemInfoScreenInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  BOOLEAN                         ActionFlag;
> +  EFI_STRING                      ConfigRequestHdr;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (MEM_INFO_SCREEN_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = MEM_INFO_SCREEN_PRIVATE_DATA_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
> +  mPrivateData->ConfigAccess.Callback = DriverCallback;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = DriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gMemInfoFormSetGuid,
> +                DriverHandle,
> +                MemInfoDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  //
> +  // Try to read NV config EFI variable first
> +  //
> +  ConfigRequestHdr = HiiConstructConfigHdr (
> +                       &gMemInfoFormSetGuid,
> +                       MEM_INFO_VARSTORE_NAME,
> +                       DriverHandle
> +                       );
> +  ASSERT (ConfigRequestHdr != NULL);
> +
> +  //
> +  // Validate Current Setting
> +  //
> +  ActionFlag = HiiValidateSettings (ConfigRequestHdr);
> +  if (!ActionFlag) {
> +    MemInfoScreenUnload (ImageHandle);
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  FreePool (ConfigRequestHdr);
> +
> +  Status = MemInfoScreenSetup ();
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +MemInfoScreenUnload (
> +  IN EFI_HANDLE ImageHandle
> +  )
> +{
> +  ASSERT (mPrivateData != NULL);
> +
> +  if (DriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           DriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    DriverHandle = NULL;
> +  }
> +
> +  if (mPrivateData->HiiHandle != NULL) {
> +    HiiRemovePackages (mPrivateData->HiiHandle);
> +  }
> +
> +  FreePool (mPrivateData);
> +  mPrivateData = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
> new file mode 100644
> index 000000000000..a8c7cb99d6a7
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.uni
> @@ -0,0 +1,9 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "An Altra DDR screen setup driver"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "This driver exposes a screen setup for DDR information and configuration."
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
> new file mode 100644
> index 000000000000..f44f210594be
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxeExtra.uni
> @@ -0,0 +1,9 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Ampere Altra MemInfo DXE Driver"
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
> new file mode 100644
> index 000000000000..d170f9ee7313
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoScreenStrings.uni
> @@ -0,0 +1,64 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef   en-US "English"    // English
> +
> +#string STR_MEM_INFO_FORM                   #language en-US "Memory Configuration"
> +#string STR_MEM_INFO_FORM_HELP              #language en-US "Memory Configuration"
> +#string STR_MEM_INFO_TOTAL_MEM              #language en-US "Total Memory"
> +#string STR_MEM_INFO_TOTAL_MEM_VALUE        #language en-US "0 GB"
> +#string STR_MEM_INFO_EFFECT_MEM             #language en-US "Effective Memory"
> +#string STR_MEM_INFO_EFFECT_MEM_VALUE       #language en-US "0 MB"
> +#string STR_MEM_INFO_CURRENT_SPEED          #language en-US "Memory Speed"
> +#string STR_MEM_INFO_CURRENT_SPEED_VALUE    #language en-US "0 MHz"
> +#string STR_MEM_INFO_SPEED_SELECT_PROMPT    #language en-US "Memory Operating Speed Selection"
> +#string STR_MEM_INFO_SPEED_SELECT_HELP      #language en-US "Force specific Memory Operating Speed or use Auto setting."
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE0    #language en-US "Auto"
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE1    #language en-US "2133"
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE2    #language en-US "2400"
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE3    #language en-US "2666"
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE4    #language en-US "2933"
> +#string STR_MEM_INFO_SPEED_SELECT_VALUE5    #language en-US "3200"
> +#string STR_MEM_INFO_DIMM_INFO              #language en-US "DIMM Information"
> +
> +#string STR_MEM_INFO_PERFORMANCE_FORM              #language en-US "Memory RAS and Performance Configuration"
> +#string STR_MEM_INFO_PERFORMANCE_FORM_HELP         #language en-US "Displays and provides options to change the memory RAS and performance Settings"
> +#string STR_MEM_INFO_ENABLE_ECC_PROMPT             #language en-US "ECC mode"
> +#string STR_MEM_INFO_ENABLE_ECC_HELP               #language en-US "ECC mode: Disabled, SECDED or Symbol"
> +#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_PROMPT      #language en-US "Defer uncorrectable read errors"
> +#string STR_MEM_INFO_ENABLE_ERRCTRL_DE_HELP        #language en-US "When enabled the DMC defers uncorrectable read errors to the consumer by sending an OK response and setting the TXDAT poison flag on the CHI-B interconnect. If this bit is clear the DMC defaults to non-deferred behavior when encountering an unrecoverable error"
> +#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_PROMPT      #language en-US "Fault handling interrupt"
> +#string STR_MEM_INFO_ENABLE_ERRCTRL_FI_HELP        #language en-US "Enables fault handling interrupt. The fault handling interrupt is raised to give notice that ECC fault has been recorded"
> +#string STR_MEM_INFO_ENABLE_SCRUB                  #language en-US "Scrub Patrol duration (hour)"
> +#string STR_MEM_INFO_ENABLE_SCRUB_HELP             #language en-US "Select duration (hour) for Scrub Patrol"
> +#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_PROMPT    #language en-US "Demand scrub"
> +#string STR_MEM_INFO_ENABLE_DEMAND_SCRUB_HELP      #language en-US "Enable/Disable the ability to write corrected data back to the memory once a correctable error is detected"
> +#string STR_MEM_INFO_ENABLE_WRITE_CRC_PROMPT       #language en-US "Write CRC"
> +#string STR_MEM_INFO_ENABLE_WRITE_CRC_HELP         #language en-US "Enable/Disable Cyclic Redundancy Check (CRC) functionality on write data. Be noted that enabling CRC will degrade Write bandwidth"
> +
> +
> +#string STR_MEM_INFO_ENABLE_32GB_SLAVE_PROMPT      #language en-US "Enable Slave 32bit memory region"
> +#string STR_MEM_INFO_ENABLE_32GB_SLAVE_HELP        #language en-US "Enables 32bit memory region (2GB) for slave socket"
> +#string STR_MEM_INFO_FGR_MODE_PROMPT               #language en-US "Fine Granularity Refresh (FGR)"
> +#string STR_MEM_INFO_FGR_MODE_VALUE0               #language en-US "1x"
> +#string STR_MEM_INFO_FGR_MODE_VALUE1               #language en-US "2x"
> +#string STR_MEM_INFO_FGR_MODE_VALUE2               #language en-US "4x"
> +#string STR_MEM_INFO_FGR_MODE_HELP                 #language en-US "Select DDR Fine Granularity Refresh (FGR) mode 1x/2x/4x"
> +#string STR_MEM_INFO_REFRESH2X_MODE_PROMPT         #language en-US "CVE-2020-10255 mitigation"
> +#string STR_MEM_INFO_REFRESH2X_MODE_HELP           #language en-US "Enable mitigation for CVE-2020-10255, TRRespass"
> +
> +#string STR_MEM_INFO_NVDIMM_FORM                   #language en-US "NVDIMM-N Configuration"
> +#string STR_MEM_INFO_NVDIMM_FORM_HELP              #language en-US "Displays and provides options to change the NVDIMM-N Settings"
> +#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0           #language en-US "Socket0 Configured Mode"
> +#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1           #language en-US "Socket1 Configured Mode"
> +#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK0_VALUE     #language en-US "Non-NVDIMM"
> +#string STR_MEM_INFO_NVDIMM_CUR_MODE_SK1_VALUE     #language en-US "Non-NVDIMM"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_PROMPT        #language en-US "Mode Selection"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE0        #language en-US "Non-NVDIMM"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE1        #language en-US "Non-Hashed"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE2        #language en-US "Hashed"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_VALUE3        #language en-US "Auto"
> +#string STR_MEM_INFO_NVDIMM_MODE_SEL_HELP          #language en-US "Select NVDIMM-N Mode (Non-NVDIMM/Non-Hashed/Hashed/Auto)"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
@ 2021-06-07 23:15   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:15 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:16 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This screen only supports to configure the SubNUMA mode currently.

And what sort of info does it display?

/
    Leif

> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                    |   3 +
>  Platform/Ampere/JadePkg/Jade.dsc                                    |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                    |   1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf |  58 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h   |  74 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h    |  19 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h           |  19 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr          |  43 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c   | 508 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni   |  17 +
>  10 files changed, 743 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index a372a4e0078b..05b4e8576836 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -50,6 +50,9 @@ [LibraryClasses]
>    TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
>  
>  [Guids]
> +  # GUID for the CPU HII configuration form
> +  gCpuConfigFormSetGuid        = { 0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } }
> +
>    ## NVParam MM GUID
>    gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
>  
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 75b3ece3817e..547fbb68b4e3 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -180,3 +180,4 @@ [Components.common]
>    #
>    Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index e71f3e79e6b3..b8342fde9d72 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -355,5 +355,6 @@ [FV.FvMain]
>    #
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
> new file mode 100755
> index 000000000000..a47d2b894b76
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
> @@ -0,0 +1,58 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = CpuConfigDxe
> +  MODULE_UNI_FILE                = CpuConfigDxe.uni
> +  FILE_GUID                      = A20D8E6E-EE6C-43C5-809F-19BB930653AE
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = CpuConfigDxeEntryPoint
> +
> +[Sources.common]
> +  CpuConfigDxe.c
> +  CpuConfigDxe.h
> +  NVDataStruc.h
> +  Vfr.vfr
> +  VfrStrings.uni
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  ArmLib
> +  BaseLib
> +  DebugLib
> +  DevicePathLib
> +  HiiLib
> +  HobLib
> +  IoLib
> +  MemoryAllocationLib
> +  NVParamLib
> +  PcdLib
> +  PrintLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEfiHiiConfigRoutingProtocolGuid             ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid              ## PRODUCES
> +  gEfiDevicePathProtocolGuid                   ## PRODUCES
> +
> +[Guids]
> +  gCpuConfigFormSetGuid
> +  gPlatformManagerFormsetGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
> new file mode 100644
> index 000000000000..930fbea6f9d7
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.h
> @@ -0,0 +1,74 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CPU_CONFIG_H_
> +#define CPU_CONFIG_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/CpuConfigHii.h>
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PlatformManagerHii.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <NVParamDef.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigRouting.h>
> +
> +#include "NVDataStruc.h"
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +//
> +extern UINT8 VfrBin[];
> +
> +//
> +// This is the generated String package data for all .UNI files.
> +//
> +extern UINT8 CpuConfigDxeStrings[];
> +
> +#define CPU_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('C', 'P', 'U', '_')
> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE        DriverHandle;
> +  EFI_HII_HANDLE    HiiHandle;
> +  CPU_VARSTORE_DATA Configuration;
> +
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} CPU_CONFIG_PRIVATE_DATA;
> +
> +#define CPU_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, CPU_CONFIG_PRIVATE_DATA, ConfigAccess, CPU_CONFIG_PRIVATE_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +#endif /* CPU_CONFIG_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
> new file mode 100644
> index 000000000000..d906a395c04c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/NVDataStruc.h
> @@ -0,0 +1,19 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CPU_NV_DATA_STRUC_H_
> +#define CPU_NV_DATA_STRUC_H_
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT32 CpuSubNumaMode;
> +} CPU_VARSTORE_DATA;
> +
> +#pragma pack()
> +
> +#endif /* CPU_NV_DATA_STRUC_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
> new file mode 100644
> index 000000000000..71c8492f76a1
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/CpuConfigHii.h
> @@ -0,0 +1,19 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef CPU_CONFIG_HII_H_
> +#define CPU_CONFIG_HII_H_
> +
> +#define CPU_CONFIGURATION_FORMSET_GUID \
> +  { \
> +    0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } \
> +  }
> +
> +extern EFI_GUID gCpuConfigFormSetGuid;
> +
> +#endif /* CPU_CONFIG_HII_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..b085d030bbc5
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/Vfr.vfr
> @@ -0,0 +1,43 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi/UefiMultiPhase.h>
> +#include <Guid/PlatformManagerHii.h>
> +#include <Guid/CpuConfigHii.h>
> +#include "NVDataStruc.h"
> +
> +#define SUBNUMA_MODE_FORM_ID 1
> +
> +formset
> +  guid      = CPU_CONFIGURATION_FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_CPU_FORM),
> +  help      = STRING_TOKEN(STR_CPU_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  varstore CPU_VARSTORE_DATA,
> +    name  = CpuConfigNVData,
> +    guid  = CPU_CONFIGURATION_FORMSET_GUID;
> +
> +  form
> +    formid = SUBNUMA_MODE_FORM_ID,
> +    title  = STRING_TOKEN(STR_CPU_FORM);
> +    subtitle text = STRING_TOKEN(STR_CPU_FORM_HELP);
> +
> +    oneof
> +      varid   = CpuConfigNVData.CpuSubNumaMode,
> +      prompt  = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_PROMPT),
> +      help    = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HELP),
> +      flags   = RESET_REQUIRED,
> +      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_MONOLITHIC), value = 0x0, flags = DEFAULT;
> +      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_HEMISPHERE), value = 0x1, flags = 0;
> +      option text = STRING_TOKEN(STR_CPU_SUBNUMA_MODE_QUADRANT), value = 0x2, flags = 0;
> +    endoneof;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
> new file mode 100644
> index 000000000000..da0deb74c156
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.c
> @@ -0,0 +1,508 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "CpuConfigDxe.h"
> +
> +//
> +// Default settings definitions
> +//
> +#define NV_SI_SUBNUMA_MODE_DEFAULT   0x00 /* Monolithic mode */
> +#define WA_ERRATUM_1542419_DEFAULT   0x00 /* Disable I-Cache coherency */
> +#define NEAR_ATOMIC_DISABLE_DEFAULT  0x00 /* Enable Near Atomic */
> +#define CPU_SLC_REPLACE_POLICY       0x00 /* eLRU */
> +
> +CHAR16 CpuVarstoreDataName[] = L"CpuConfigNVData";
> +
> +EFI_HANDLE              mDriverHandle = NULL;
> +CPU_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
> +
> +HII_VENDOR_DEVICE_PATH mCpuConfigHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    CPU_CONFIGURATION_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +STATIC
> +EFI_STATUS
> +CpuNvParamGet (
> +  OUT CPU_VARSTORE_DATA *Configuration
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  ASSERT (Configuration != NULL);
> +
> +  Status = NVParamGet (
> +             NV_SI_SUBNUMA_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a %d Fail to write NVParam \n", __FUNCTION__, __LINE__));
> +    Configuration->CpuSubNumaMode = SUBNUMA_MODE_MONOLITHIC;
> +  } else {
> +    Configuration->CpuSubNumaMode = Value;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +CpuNvParamSet (
> +  IN CPU_VARSTORE_DATA *Configuration
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  ASSERT (Configuration != NULL);
> +
> +  Status = NVParamGet (
> +             NV_SI_SUBNUMA_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  if (EFI_ERROR (Status) || Value != Configuration->CpuSubNumaMode) {
> +    Status = NVParamSet (
> +               NV_SI_SUBNUMA_MODE,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Configuration->CpuSubNumaMode
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a %d Fail to access NVParam \n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +SetupDefaultSettings (
> +  VOID
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  //
> +  // Subnuma Mode
> +  //
> +  Status = NVParamGet (
> +             NV_SI_SUBNUMA_MODE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Status = NVParamSet (
> +               NV_SI_SUBNUMA_MODE,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               NV_SI_SUBNUMA_MODE_DEFAULT
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  //
> +  // ARM ERRATA 1542419 workaround
> +  //
> +  Status = NVParamSet (
> +             NV_SI_ERRATUM_1542419_WA,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             WA_ERRATUM_1542419_DEFAULT
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Near atomic
> +  //
> +  Status = NVParamSet (
> +             NV_SI_NEAR_ATOMIC_DISABLE,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             NEAR_ATOMIC_DISABLE_DEFAULT
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // SLC Replacement Policy
> +  //
> +  Status = NVParamSet (
> +             NV_SI_HNF_AUX_CTL_32_63,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             CPU_SLC_REPLACE_POLICY
> +             );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuConfigExtractConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN  CONST EFI_STRING                     Request,
> +  OUT EFI_STRING                           *Progress,
> +  OUT EFI_STRING                           *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  CPU_CONFIG_PRIVATE_DATA         *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  BOOLEAN                         AllocatedRequest;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  PrivateData = CPU_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +
> +  //
> +  // Get current setting from NVParam.
> +  //
> +  Status = CpuNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  BufferSize = sizeof (CPU_VARSTORE_DATA);
> +  ConfigRequest = Request;
> +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> +    //
> +    // Request has no request element, construct full request string.
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (&gCpuConfigFormSetGuid, CpuVarstoreDataName, PrivateData->DriverHandle);
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    if (ConfigRequest == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  Status = HiiConfigRouting->BlockToConfig (
> +                               HiiConfigRouting,
> +                               ConfigRequest,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               BufferSize,
> +                               Results,
> +                               Progress
> +                               );
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +    ConfigRequest = NULL;
> +  }
> +
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuConfigRouteConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Configuration,
> +  OUT      EFI_STRING                     *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  CPU_CONFIG_PRIVATE_DATA         *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = CPU_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &gCpuConfigFormSetGuid, CpuVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get configuration data from NVParam
> +  //
> +  Status = CpuNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (CPU_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store configuration data back to NVParam
> +  //
> +  Status = CpuNvParamSet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +
> +  @retval  EFI_SUCCESS           The callback successfully handled the action.
> +  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +CpuConfigCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  if (Action != EFI_BROWSER_ACTION_CHANGING) {
> +    //
> +    // Do nothing for other UEFI Action. Only do call back when data is changed.
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  if (((Value == NULL) && (Action != EFI_BROWSER_ACTION_FORM_OPEN) && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))||
> +      (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +CpuConfigDxeEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (CPU_CONFIG_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = CPU_CONFIG_PRIVATE_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = CpuConfigExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = CpuConfigRouteConfig;
> +  mPrivateData->ConfigAccess.Callback = CpuConfigCallback;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mDriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mCpuConfigHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = mDriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gCpuConfigFormSetGuid,
> +                mDriverHandle,
> +                CpuConfigDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mCpuConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  //
> +  // With the fresh system, the NVParam value is invalid (0xFFFFFFFF).
> +  // It causes reading from the NVParam is failed.
> +  // So, the NVParam should be setting with default values if any params is invalid.
> +  //
> +  Status = SetupDefaultSettings ();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
> new file mode 100644
> index 000000000000..70c01f65e4b6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/VfrStrings.uni
> @@ -0,0 +1,17 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US  "English"
> +
> +#string STR_CPU_FORM                                #language en-US "CPU Configuration"
> +#string STR_CPU_FORM_HELP                           #language en-US "CPU Configuration"
> +#string STR_CPU_FORM_SEPERATE_LINE                  #language en-US ""
> +
> +#string STR_CPU_SUBNUMA_MODE_PROMPT                 #language en-US "ANC mode"
> +#string STR_CPU_SUBNUMA_MODE_HELP                   #language en-US "Provides 3 modes: Monolithic, Hemisphere, Quadrant. System with Monolithic mode has single NUMA partition per socket. System with Hemisphere has 2 NUMA partitions per socket. System with Quandrant has 4 NUMA partitions per socket"
> +#string STR_CPU_SUBNUMA_MODE_MONOLITHIC             #language en-US "Monolithic"
> +#string STR_CPU_SUBNUMA_MODE_HEMISPHERE             #language en-US "Hemisphere"
> +#string STR_CPU_SUBNUMA_MODE_QUADRANT               #language en-US "Quadrant"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
@ 2021-06-07 23:20   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:20 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:17 +0700, Nhi Pham wrote:
> This supports:
> * Enable/Disable APEI Support
> * Enable/Disable CPPC Support
> * Enable/Disable LPI support
> * Enable/Disable Max Performance Mode
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                      |   3 +
>  Platform/Ampere/JadePkg/Jade.dsc                                      |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                      |   1 +
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf   |   1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf |  56 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h            |   2 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h   |  85 +++
>  Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h               |  28 +
>  Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h        |  19 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr           |  69 ++
>  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c            |  23 +-
>  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c   | 733 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni    |  27 +
>  13 files changed, 1046 insertions(+), 2 deletions(-)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 05b4e8576836..ede85d3a3421 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -53,6 +53,9 @@ [Guids]
>    # GUID for the CPU HII configuration form
>    gCpuConfigFormSetGuid        = { 0x43FAA144, 0xA2DF, 0x4050, { 0xA7, 0xFD, 0xEE, 0x17, 0xC9, 0xB8, 0x88, 0x8E } }
>  
> +  # GUID for the ACPI HII configuration form
> +  gAcpiConfigFormSetGuid = { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } }
> +
>    ## NVParam MM GUID
>    gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
>  
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 547fbb68b4e3..e82b0cce691a 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -181,3 +181,4 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index b8342fde9d72..ddd601075f19 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -356,5 +356,6 @@ [FV.FvMain]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/PlatformInfoDxe/PlatformInfoDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> index a1a323eee472..287b4eadbf4a 100644
> --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> @@ -64,6 +64,7 @@ [Guids]
>    gArmMpCoreInfoGuid
>    gEfiAcpiTableGuid
>    gEfiEventReadyToBootGuid
> +  gAcpiConfigFormSetGuid
>    gPlatformHobGuid
>  
>  [Protocols]
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
> new file mode 100644
> index 000000000000..bc2fbebc84d1
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
> @@ -0,0 +1,56 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = AcpiConfigDxe
> +  FILE_GUID                      = F36685AE-2623-4231-ABC0-2C151451E6B7
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = AcpiConfigEntryPoint
> +
> +[Sources.common]
> +  AcpiConfigDxe.c
> +  AcpiConfigDxe.h
> +  Vfr.vfr
> +  VfrStrings.uni
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AcpiHelperLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  HiiLib
> +  HobLib
> +  MemoryAllocationLib
> +  SystemFirmwareInterfaceLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Guids]
> +  gPlatformManagerFormsetGuid
> +  gAcpiConfigFormSetGuid
> +  gEfiEventReadyToBootGuid
> +  gPlatformHobGuid
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +
> +[Depex]
> +  gEfiVariableArchProtocolGuid AND
> +  gEfiVariableWriteArchProtocolGuid
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
> index c207142459ad..5a0ce9dcc69a 100644
> --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
> @@ -9,7 +9,9 @@
>  #ifndef ACPI_APEI_H_
>  #define ACPI_APEI_H_
>  
> +#include <AcpiNVDataStruc.h>
>  #include <Base.h>
> +#include <Guid/AcpiConfigFormSet.h>
>  #include <IndustryStandard/Acpi63.h>
>  #include <Library/AcpiHelperLib.h>
>  #include <Library/AmpereCpuLib.h>
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
> new file mode 100644
> index 000000000000..45cb08e01f7b
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.h
> @@ -0,0 +1,85 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef DRIVER_SAMPLE_H_
> +#define DRIVER_SAMPLE_H_

*Cough*

> +
> +#include <Uefi.h>
> +
> +#include <AcpiNVDataStruc.h>
> +#include <Guid/AcpiConfigFormSet.h>
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PlatformInfoHobGuid.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/SystemFirmwareInterfaceLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiDriverEntryPoint.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigRouting.h>

Please move all include statements not actually used by this .h file
to the .c files that need them.

> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +//
> +extern UINT8 VfrBin[];

PlatformAcpiConfigVfrBin?

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +//
> +extern UINT8 AcpiConfigDxeStrings[];
> +
> +#define ACPI_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('A', 'C', 'P', 'I')

This signature should be something kind of possible to be unique.

As pointed out for the PCIE config menu - there are a lot of things in
here that look like they form part of the ACPI global symbol/macro
namespace. It would be better if this could be avoided.

/
    Leif

> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE                DriverHandle;
> +  EFI_HII_HANDLE            HiiHandle;
> +  ACPI_CONFIG_VARSTORE_DATA Configuration;
> +  PLATFORM_INFO_HOB         *PlatformHob;
> +  EFI_ACPI_SDT_PROTOCOL     *AcpiTableProtocol;
> +  EFI_ACPI_HANDLE           AcpiTableHandle;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} ACPI_CONFIG_PRIVATE_DATA;
> +
> +#define ACPI_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, ACPI_CONFIG_PRIVATE_DATA, ConfigAccess, ACPI_CONFIG_PRIVATE_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
> new file mode 100644
> index 000000000000..17f80113797d
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiNVDataStruc.h
> @@ -0,0 +1,28 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_NV_DATA_STRUC_H_
> +#define ACPI_NV_DATA_STRUC_H_
> +
> +#pragma pack(1)
> +
> +//
> +// ACPI Configuration NV data structure definition
> +//
> +typedef struct {
> +  UINT32 EnableApeiSupport;
> +  UINT32 AcpiCppcEnable;
> +  UINT32 AcpiLpiEnable;
> +  UINT32 AcpiTurboSupport;
> +  UINT32 AcpiTurboMode;
> +  UINT32 Reserved[4];
> +} ACPI_CONFIG_VARSTORE_DATA;
> +
> +#pragma pack()
> +
> +#endif /* ACPI_NV_DATA_STRUC_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
> new file mode 100644
> index 000000000000..1779a4543769
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/AcpiConfigFormSet.h
> @@ -0,0 +1,19 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef ACPI_CONFIG_FORMSET_GUID_H_
> +#define ACPI_CONFIG_FORMSET_GUID_H_
> +
> +#define ACPI_CONFIGURATION_FORMSET_GUID \
> +  { \
> +    0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } \
> +  }
> +
> +extern EFI_GUID gAcpiConfigFormSetGuid;
> +
> +#endif /* ACPI_CONFIG_FORMSET_GUID_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..6cbd896987b5
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/Vfr.vfr
> @@ -0,0 +1,69 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +
> +#include <Guid/AcpiConfigFormSet.h>
> +#include <AcpiNVDataStruc.h>
> +
> +#define ACPI_CONFIG_FORM_ID  1
> +
> +formset
> +  guid      = ACPI_CONFIGURATION_FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_ACPI_FORM),
> +  help      = STRING_TOKEN(STR_ACPI_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  varstore ACPI_CONFIG_VARSTORE_DATA,
> +    name  = AcpiConfigNVData,
> +    guid  = ACPI_CONFIGURATION_FORMSET_GUID;
> +
> +  form
> +    formid = ACPI_CONFIG_FORM_ID,
> +    title  = STRING_TOKEN(STR_ACPI_FORM);
> +    subtitle text = STRING_TOKEN(STR_ACPI_FORM_HELP);
> +
> +    oneof
> +      varid   = AcpiConfigNVData.EnableApeiSupport,
> +      prompt  = STRING_TOKEN(STR_ACPI_APEI_SUPPORT_PROMPT),
> +      help    = STRING_TOKEN(STR_ACPI_APEI_SUPPORT_HELP),
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +    endoneof;
> +
> +    oneof
> +      varid   = AcpiConfigNVData.AcpiCppcEnable,
> +      prompt  = STRING_TOKEN(STR_ACPI_CPPC_PROMPT),
> +      help    = STRING_TOKEN(STR_ACPI_CPPC_HELP),
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +    endoneof;
> +
> +    oneof
> +      varid   = AcpiConfigNVData.AcpiLpiEnable,
> +      prompt  = STRING_TOKEN(STR_ACPI_LPI_PROMPT),
> +      help    = STRING_TOKEN(STR_ACPI_LPI_HELP),
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
> +      option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +    endoneof;
> +
> +    grayoutif ideqval AcpiConfigNVData.AcpiTurboSupport == 0;
> +      oneof
> +        varid   = AcpiConfigNVData.AcpiTurboMode,
> +        prompt  = STRING_TOKEN(STR_ACPI_TURBO_PROMPT),
> +        help    = STRING_TOKEN(STR_ACPI_TURBO_HELP),
> +        option text = STRING_TOKEN(STR_ACPI_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +        option text = STRING_TOKEN(STR_ACPI_COMMON_DISABLE), value = 0, flags = 0;
> +        suppressif ideqval AcpiConfigNVData.AcpiTurboSupport > 0;
> +        option text = STRING_TOKEN(STR_ACPI_UNSUPPORTED), value = 2, flags = 0;
> +        endif;
> +      endoneof;
> +    endif;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
> index fa188c7776db..3ec63250a5de 100644
> --- a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
> @@ -445,8 +445,27 @@ AcpiApeiUpdate (
>    VOID
>    )
>  {
> -  if (!IsSlaveSocketActive ()) {
> -    AcpiApeiHestUpdateTable1P ();
> +  EFI_STATUS                Status;
> +  ACPI_CONFIG_VARSTORE_DATA AcpiConfigData;
> +  UINTN                     BufferSize;
> +
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  L"AcpiConfigNVData",
> +                  &gAcpiConfigFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &AcpiConfigData
> +                  );
> +  if (!EFI_ERROR (Status) && (AcpiConfigData.EnableApeiSupport == 0)) {
> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE);
> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE);
> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE);
> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_ERROR_INJECTION_TABLE_SIGNATURE);
> +  } else {
> +    if (!IsSlaveSocketActive ()) {
> +      AcpiApeiHestUpdateTable1P ();
> +    }
>    }
>  
>    if (!IsSdeiEnabled ()) {
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
> new file mode 100644
> index 000000000000..ea9004ef2e3c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.c
> @@ -0,0 +1,733 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "AcpiConfigDxe.h"
> +
> +#define ACPI_VARSTORE_ATTRIBUTES EFI_VARIABLE_BOOTSERVICE_ACCESS | \
> +                                 EFI_VARIABLE_RUNTIME_ACCESS     | \
> +                                 EFI_VARIABLE_NON_VOLATILE
> +
> +CHAR16 AcpiVarstoreDataName[] = L"AcpiConfigNVData";
> +
> +EFI_HANDLE               mDriverHandle = NULL;
> +ACPI_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
> +
> +HII_VENDOR_DEVICE_PATH mAcpiConfigHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    ACPI_CONFIGURATION_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN  CONST EFI_STRING                     Request,
> +  OUT EFI_STRING                           *Progress,
> +  OUT EFI_STRING                           *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  ACPI_CONFIG_PRIVATE_DATA        *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  BOOLEAN                         AllocatedRequest;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gAcpiConfigFormSetGuid, AcpiVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  PrivateData = ACPI_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +
> +  //
> +  // Get Buffer Storage data from EFI variable.
> +  // Try to get the current setting from variable.
> +  //
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  AcpiVarstoreDataName,
> +                  &gAcpiConfigFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &PrivateData->Configuration
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  ConfigRequest = Request;
> +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> +    //
> +    // Request has no request element, construct full request string.
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (
> +                         &gAcpiConfigFormSetGuid,
> +                         AcpiVarstoreDataName,
> +                         PrivateData->DriverHandle
> +                         );
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    if (ConfigRequest == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  Status = HiiConfigRouting->BlockToConfig (
> +                               HiiConfigRouting,
> +                               ConfigRequest,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               BufferSize,
> +                               Results,
> +                               Progress
> +                               );
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +    ConfigRequest = NULL;
> +  }
> +
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN  CONST EFI_STRING                     Configuration,
> +  OUT EFI_STRING                           *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  ACPI_CONFIG_PRIVATE_DATA        *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = ACPI_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &gAcpiConfigFormSetGuid, AcpiVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get Buffer Storage data from EFI variable
> +  //
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  AcpiVarstoreDataName,
> +                  &gAcpiConfigFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &PrivateData->Configuration
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store Buffer Storage back to EFI variable
> +  //
> +  Status = gRT->SetVariable (
> +                  AcpiVarstoreDataName,
> +                  &gAcpiConfigFormSetGuid,
> +                  ACPI_VARSTORE_ATTRIBUTES,
> +                  sizeof (ACPI_CONFIG_VARSTORE_DATA),
> +                  &PrivateData->Configuration
> +                  );
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +
> +  @retval  EFI_SUCCESS           The callback successfully handled the action.
> +  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverCallback (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN  EFI_BROWSER_ACTION                   Action,
> +  IN  EFI_QUESTION_ID                      QuestionId,
> +  IN  UINT8                                Type,
> +  IN  EFI_IFR_TYPE_VALUE                   *Value,
> +  OUT EFI_BROWSER_ACTION_REQUEST           *ActionRequest
> +  )
> +{
> +  if (Action != EFI_BROWSER_ACTION_CHANGING) {
> +    //
> +    // Do nothing for other UEFI Action. Only do call back when data is changed.
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  if (((Value == NULL)
> +       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
> +       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
> +      || (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +AcpiNVDataUpdate (
> +  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  EFI_STATUS         Status;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  UINT32             TurboSupport;
> +
> +  ASSERT (PrivateData != NULL);
> +
> +  PlatformHob = PrivateData->PlatformHob;
> +  TurboSupport = PlatformHob->TurboCapability[0] + PlatformHob->TurboCapability[1];
> +
> +  if (TurboSupport == 0) {
> +    PrivateData->Configuration.AcpiTurboMode = 2; // Unsupported mode
> +    PrivateData->Configuration.AcpiTurboSupport = 0;
> +  } else {
> +    PrivateData->Configuration.AcpiTurboSupport = 1;
> +  }
> +
> +  Status = gRT->SetVariable (
> +                  AcpiVarstoreDataName,
> +                  &gAcpiConfigFormSetGuid,
> +                  ACPI_VARSTORE_ATTRIBUTES,
> +                  sizeof (ACPI_CONFIG_VARSTORE_DATA),
> +                  &PrivateData->Configuration
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a %d gRT->SetVariable() failed \n", __FUNCTION__, __LINE__));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateTurboModeConfig (
> +  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  EFI_STATUS         Status;
> +  PLATFORM_INFO_HOB  *PlatformHob;
> +  BOOLEAN            EnableTurbo;
> +
> +  ASSERT (PrivateData != NULL);
> +
> +  if (PrivateData->Configuration.AcpiTurboSupport != 0) {
> +    PlatformHob = PrivateData->PlatformHob;
> +    EnableTurbo = (PrivateData->Configuration.AcpiTurboMode != 0) ? TRUE : FALSE;
> +
> +    if (PlatformHob->TurboCapability[0] != 0) {
> +      Status = MailboxMsgTurboConfig (0, EnableTurbo);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    }
> +
> +    if (PlatformHob->TurboCapability[1] != 0) {
> +      Status = MailboxMsgTurboConfig (1, EnableTurbo);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    }
> +  } else {
> +    DEBUG ((DEBUG_INFO, "%a: Turbo mode is unsupported! \n", __FUNCTION__));
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateCPPCConfig (
> +  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_ACPI_HANDLE       ChildHandle;
> +  CHAR8                 Buffer[64];
> +  EFI_ACPI_DATA_TYPE    DataType;
> +  UINTN                 DataSize;
> +  UINT8                 *Data;
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
> +
> +  ASSERT (PrivateData != NULL);
> +
> +  AcpiTableProtocol = PrivateData->AcpiTableProtocol;
> +
> +  AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.CPCE");
> +  Status = AcpiTableProtocol->FindPath (
> +                                PrivateData->AcpiTableHandle,
> +                                (VOID *)Buffer,
> +                                &ChildHandle
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Failed to find path CPCE\n"));
> +    AcpiTableProtocol->Close (PrivateData->AcpiTableHandle);
> +    return Status;
> +  }
> +
> +  Status = AcpiTableProtocol->GetOption (
> +                                ChildHandle,
> +                                2,
> +                                &DataType,
> +                                (VOID *)&Data,
> +                                &DataSize
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Data[0] = PrivateData->Configuration.AcpiCppcEnable;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +EFI_STATUS
> +UpdateLPIConfig (
> +  IN ACPI_CONFIG_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_ACPI_HANDLE       ChildHandle;
> +  CHAR8                 Buffer[64];
> +  EFI_ACPI_DATA_TYPE    DataType;
> +  UINTN                 DataSize;
> +  UINT8                 *Data;
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
> +
> +  ASSERT (PrivateData != NULL);
> +
> +  AcpiTableProtocol = PrivateData->AcpiTableProtocol;
> +
> +  AsciiSPrint (Buffer, sizeof (Buffer), "\\_SB.LPIE");
> +  Status = AcpiTableProtocol->FindPath (
> +                                PrivateData->AcpiTableHandle,
> +                                (VOID *)Buffer,
> +                                &ChildHandle
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Fail to find path LPIE\n"));
> +    AcpiTableProtocol->Close (PrivateData->AcpiTableHandle);
> +    return Status;
> +  }
> +
> +  Status = AcpiTableProtocol->GetOption (
> +                                ChildHandle,
> +                                2,
> +                                &DataType,
> +                                (VOID *)&Data,
> +                                &DataSize
> +                                );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  Data[0] = PrivateData->Configuration.AcpiLpiEnable;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +STATIC
> +VOID
> +UpdateAcpiOnReadyToBoot (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS            Status;
> +  EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol;
> +  EFI_ACPI_HANDLE       TableHandle;
> +
> +  ASSERT (mPrivateData != NULL);
> +
> +  //
> +  // Find the AcpiTable protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiAcpiSdtProtocolGuid,
> +                  NULL,
> +                  (VOID **)&AcpiTableProtocol
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
> +    return;
> +  }
> +
> +  mPrivateData->AcpiTableProtocol = AcpiTableProtocol;
> +
> +  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Unable to locate DSDT table protocol\n"));
> +    return;
> +  }
> +
> +  mPrivateData->AcpiTableHandle = TableHandle;
> +
> +  Status = UpdateCPPCConfig (mPrivateData);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  Status = UpdateLPIConfig (mPrivateData);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  Status = UpdateTurboModeConfig (mPrivateData);
> +  if (EFI_ERROR (Status)) {
> +    return;
> +  }
> +
> +  //
> +  // Close DSDT Table
> +  //
> +  AcpiTableProtocol->Close (TableHandle);
> +
> +  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
> +}
> +
> +STATIC
> +EFI_STATUS
> +AcpiConfigUnload (
> +  VOID
> +  )
> +{
> +  ASSERT (mPrivateData != NULL);
> +
> +  if (mDriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mAcpiConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    mDriverHandle = NULL;
> +  }
> +
> +  if (mPrivateData->HiiHandle != NULL) {
> +    HiiRemovePackages (mPrivateData->HiiHandle);
> +  }
> +
> +  FreePool (mPrivateData);
> +  mPrivateData = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +AcpiConfigEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  UINTN                           BufferSize;
> +  ACPI_CONFIG_VARSTORE_DATA       *Configuration;
> +  BOOLEAN                         ActionFlag;
> +  EFI_STRING                      ConfigRequestHdr;
> +  EFI_EVENT                       ReadyToBootEvent;
> +  PLATFORM_INFO_HOB               *PlatformHob;
> +  VOID                            *Hob;
> +
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr = NULL;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (ACPI_CONFIG_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = ACPI_CONFIG_PRIVATE_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
> +  mPrivateData->ConfigAccess.Callback = DriverCallback;
> +
> +  //
> +  // Get the Platform HOB
> +  //
> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
> +  ASSERT (Hob != NULL);
> +  if (Hob == NULL) {
> +    AcpiConfigUnload ();
> +    return EFI_DEVICE_ERROR;
> +  }
> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
> +
> +  mPrivateData->PlatformHob = PlatformHob;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mDriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mAcpiConfigHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = mDriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gAcpiConfigFormSetGuid,
> +                mDriverHandle,
> +                AcpiConfigDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mAcpiConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  //
> +  // Initialize configuration data
> +  //
> +  Configuration = &mPrivateData->Configuration;
> +  ZeroMem (Configuration, sizeof (ACPI_CONFIG_VARSTORE_DATA));
> +
> +  //
> +  // Try to read NV config EFI variable first
> +  //
> +  ConfigRequestHdr = HiiConstructConfigHdr (&gAcpiConfigFormSetGuid, AcpiVarstoreDataName, mDriverHandle);
> +  ASSERT (ConfigRequestHdr != NULL);
> +
> +  BufferSize = sizeof (ACPI_CONFIG_VARSTORE_DATA);
> +  Status = gRT->GetVariable (AcpiVarstoreDataName, &gAcpiConfigFormSetGuid, NULL, &BufferSize, Configuration);
> +  if (EFI_ERROR (Status)) {
> +    //
> +    // Store zero data Buffer Storage to EFI variable
> +    //
> +    Status = gRT->SetVariable (
> +                    AcpiVarstoreDataName,
> +                    &gAcpiConfigFormSetGuid,
> +                    ACPI_VARSTORE_ATTRIBUTES,
> +                    sizeof (ACPI_CONFIG_VARSTORE_DATA),
> +                    Configuration
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      AcpiConfigUnload ();
> +      return Status;
> +    }
> +    //
> +    // EFI variable for NV config doesn't exit, we should build this variable
> +    // based on default values stored in IFR
> +    //
> +    ActionFlag = HiiSetToDefaults (ConfigRequestHdr, EFI_HII_DEFAULT_CLASS_STANDARD);
> +    if (!ActionFlag) {
> +      AcpiConfigUnload ();
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  } else {
> +    //
> +    // EFI variable does exist and Validate Current Setting
> +    //
> +    ActionFlag = HiiValidateSettings (ConfigRequestHdr);
> +    if (!ActionFlag) {
> +      AcpiConfigUnload ();
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +  FreePool (ConfigRequestHdr);
> +
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_NOTIFY,
> +                  UpdateAcpiOnReadyToBoot,
> +                  NULL,
> +                  &gEfiEventReadyToBootGuid,
> +                  &ReadyToBootEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Fail to create ready to boot event %r!\n", Status));
> +    return Status;
> +  }
> +
> +  Status = AcpiNVDataUpdate (mPrivateData);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
> new file mode 100644
> index 000000000000..21a6188518fd
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/VfrStrings.uni
> @@ -0,0 +1,27 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US  "English"
> +
> +#string STR_ACPI_FORM                                #language en-US "ACPI Configuration"
> +#string STR_ACPI_FORM_HELP                           #language en-US "ACPI Configuration"
> +
> +#string STR_ACPI_FORM_SEPERATE_LINE                  #language en-US ""
> +#string STR_ACPI_COMMON_ENABLE                       #language en-US "Enabled"
> +#string STR_ACPI_COMMON_DISABLE                      #language en-US "Disabled"
> +#string STR_ACPI_UNSUPPORTED                         #language en-US "Unsupported"
> +
> +#string STR_ACPI_APEI_SUPPORT_PROMPT                 #language en-US "APEI Support"
> +#string STR_ACPI_APEI_SUPPORT_HELP                   #language en-US "Enable/Disable ACPI Platform Error Interface support"
> +
> +#string STR_ACPI_CPPC_PROMPT                         #language en-US "CPPC Support"
> +#string STR_ACPI_CPPC_HELP                           #language en-US "Enables or Disables System ability to CPPC (Collaborative Processor Performance Control)"
> +
> +#string STR_ACPI_LPI_PROMPT                          #language en-US "LPI Support"
> +#string STR_ACPI_LPI_HELP                            #language en-US "Enables or Disables System ability to LPI (Lower Power Idle)"
> +
> +#string STR_ACPI_TURBO_PROMPT                        #language en-US "Max Performance"
> +#string STR_ACPI_TURBO_HELP                          #language en-US "Enables or Disables System ability to Max Performance"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
@ 2021-06-07 23:22   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:22 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:18 +0700, Nhi Pham wrote:
> From: Quan Nguyen <quan@os.amperecomputing.com>
> 
> This supports user to enable/disable RAS components running the system
> firmware such as HEST, BERT,...
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
> ---
>  Platform/Ampere/JadePkg/Jade.dsc                                    |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                    |   1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf |  56 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h    |  46 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h   |  82 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr          | 105 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c   | 762 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni   |  38 +
>  8 files changed, 1091 insertions(+)
> 
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index e82b0cce691a..26cf8be001ab 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -182,3 +182,4 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index ddd601075f19..c0b71a4732fa 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -357,5 +357,6 @@ [FV.FvMain]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemInfoDxe/MemInfoDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
> new file mode 100644
> index 000000000000..7413b7474d7a
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
> @@ -0,0 +1,56 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001A
> +  BASE_NAME                      = RasConfigDxe
> +  FILE_GUID                      = 5b5ee6e3-3135-45f7-ad21-46a3f36813cc
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = RasConfigEntryPoint
> +
> +[Sources.common]
> +  NVDataStruc.h
> +  RasConfigDxe.c
> +  RasConfigDxe.h
> +  Vfr.vfr
> +  VfrStrings.uni
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AmpereCpuLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  DevicePathLib
> +  HiiLib
> +  MemoryAllocationLib
> +  NVParamLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Guids]
> +  gEfiIfrTianoGuid
> +  gPlatformManagerFormsetGuid
> +  gAcpiConfigFormSetGuid
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
> new file mode 100644
> index 000000000000..e87d1c97597c
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/NVDataStruc.h
> @@ -0,0 +1,46 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RAS_CONFIG_NVDATA_STRUC_H_
> +#define RAS_CONFIG_NVDATA_STRUC_H_
> +
> +#define RAS_CONFIG_VARSTORE_ID       0x1234
> +#define RAS_CONFIG_FORM_ID           0x1235
> +
> +#define RAS_VARSTORE_NAME        L"RasConfigNVData"
> +
> +#define RAS_CONFIG_FORMSET_GUID \
> +  { \
> +    0x96934cc6, 0xcb15, 0x4d8a, { 0xbe, 0x5f, 0x8e, 0x7d, 0x55, 0x0e, 0xc9, 0xc6 } \
> +  }
> +
> +//
> +// Labels definition
> +//
> +#define LABEL_UPDATE                 0x3234
> +#define LABEL_END                    0xffff
> +
> +#pragma pack(1)
> +
> +//
> +// Ras Configuration NV data structure definition
> +//
> +typedef struct {
> +  UINT32 RasHardwareEinj;
> +  UINT32 RasPcieAerFwFirstEnabled;
> +  UINT32 RasBertEnabled;
> +  UINT32 RasSdeiEnabled;
> +  UINT32 RasDdrCeThreshold;
> +  UINT32 Ras2pCeThreshold;
> +  UINT32 RasCpmCeThreshold;
> +  UINT32 RasLinkErrThreshold;
> +} RAS_CONFIG_VARSTORE_DATA;
> +
> +#pragma pack()
> +
> +#endif /* RAS_CONFIG_NVDATA_STRUC_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
> new file mode 100644
> index 000000000000..66e2ded8b701
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.h
> @@ -0,0 +1,82 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef RAS_CONFIG_DXE_H_
> +#define RAS_CONFIG_DXE_H_
> +
> +#include <Uefi.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Library/AmpereCpuLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <NVParamDef.h>
> +#include <PlatformInfoHob.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigRouting.h>

Are all of the above include files used by this .h?

> +
> +#include "NVDataStruc.h"
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +//
> +extern UINT8 VfrBin[];

RasConfigVfrBin?

/
    Leif

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +//
> +extern UINT8 RasConfigDxeStrings[];
> +
> +#define RAS_2P_CE_THRESHOLD_OFST  OFFSET_OF (RAS_CONFIG_VARSTORE_DATA, Ras2pCeThreshold)
> +
> +#define RAS_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('R', 'A', 'S', 'C')
> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE               DriverHandle;
> +  EFI_HII_HANDLE           HiiHandle;
> +  RAS_CONFIG_VARSTORE_DATA Configuration;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} RAS_CONFIG_PRIVATE_DATA;
> +
> +#define RAS_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, RAS_CONFIG_PRIVATE_DATA, ConfigAccess, RAS_CONFIG_PRIVATE_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +#endif /* RAS_CONFIG_DXE_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..3c2c4947a52b
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/Vfr.vfr
> @@ -0,0 +1,105 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "NVDataStruc.h"
> +
> +formset
> +  guid      = RAS_CONFIG_FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_RAS_FORM),
> +  help      = STRING_TOKEN(STR_RAS_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  //
> +  // Define a variable Storage
> +  //
> +  varstore RAS_CONFIG_VARSTORE_DATA,
> +    varid = RAS_CONFIG_VARSTORE_ID,
> +    name  = RasConfigNVData,
> +    guid  = RAS_CONFIG_FORMSET_GUID;
> +
> +  form formid = RAS_CONFIG_FORM_ID,
> +    title = STRING_TOKEN(STR_RAS_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_RAS_FORM);
> +
> +    oneof varid  = RasConfigNVData.RasHardwareEinj,
> +      prompt      = STRING_TOKEN(STR_RAS_HARDWARE_EINJ_PROMPT),
> +      help        = STRING_TOKEN(STR_RAS_HARDWARE_EINJ_HELP),
> +      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = 0;
> +
> +    endoneof;
> +
> +    oneof varid  = RasConfigNVData.RasPcieAerFwFirstEnabled,
> +      prompt      = STRING_TOKEN(STR_RAS_PCIE_AER_FW_FIRST_PROMPT),
> +      help        = STRING_TOKEN(STR_RAS_PCIE_AER_FW_FIRST_HELP),
> +      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = 0;
> +      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = DEFAULT;
> +
> +    endoneof;
> +
> +    oneof varid  = RasConfigNVData.RasBertEnabled,
> +      prompt      = STRING_TOKEN(STR_RAS_BERT_ENABLED_PROMPT),
> +      help        = STRING_TOKEN(STR_RAS_BERT_ENABLED_HELP),
> +      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = DEFAULT;
> +      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = 0;
> +
> +    endoneof;
> +
> +    oneof varid  = RasConfigNVData.RasSdeiEnabled,
> +      prompt      = STRING_TOKEN(STR_RAS_SDEI_ENABLED_PROMPT),
> +      help        = STRING_TOKEN(STR_RAS_SDEI_ENABLED_HELP),
> +      flags       = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      option text = STRING_TOKEN(STR_RAS_COMMON_ENABLE), value = 1, flags = 0;
> +      option text = STRING_TOKEN(STR_RAS_COMMON_DISABLE), value = 0, flags = DEFAULT;
> +
> +    endoneof;
> +
> +    numeric varid   = RasConfigNVData.RasDdrCeThreshold,
> +      prompt  = STRING_TOKEN(STR_RAS_DDR_CE_THRESHOLD_PROMPT),
> +      help    = STRING_TOKEN(STR_RAS_DDR_CE_THRESHOLD_HELP),
> +      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      minimum = 1,
> +      maximum = 8192,
> +      default = 1,
> +
> +    endnumeric;
> +
> +    label LABEL_UPDATE;
> +    //
> +    // This is where we will dynamically add other Action type op-code
> +    //
> +    label LABEL_END;
> +
> +    numeric varid   = RasConfigNVData.RasCpmCeThreshold,
> +      prompt  = STRING_TOKEN(STR_RAS_CPM_CE_THRESHOLD_PROMPT),
> +      help    = STRING_TOKEN(STR_RAS_CPM_CE_THRESHOLD_HELP),
> +      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      minimum = 1,
> +      maximum = 8192,
> +      default = 1,
> +
> +    endnumeric;
> +
> +    numeric varid   = RasConfigNVData.RasLinkErrThreshold,
> +      prompt  = STRING_TOKEN(STR_RAS_LINK_ERR_THRESHOLD_PROMPT),
> +      help    = STRING_TOKEN(STR_RAS_LINK_ERR_THRESHOLD_HELP),
> +      flags   = NUMERIC_SIZE_4 | RESET_REQUIRED,
> +      minimum = 1,
> +      maximum = 8192,
> +      default = 1,
> +
> +    endnumeric;
> +
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
> new file mode 100644
> index 000000000000..ca115764ed7a
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.c
> @@ -0,0 +1,762 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "RasConfigDxe.h"
> +
> +CHAR16 RasConfigVarstoreDataName[] = L"RasConfigNVData";
> +
> +EFI_HANDLE              mDriverHandle = NULL;
> +RAS_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
> +
> +EFI_GUID mRasConfigFormSetGuid = RAS_CONFIG_FORMSET_GUID;
> +
> +//
> +// Default RAS Settings
> +//
> +#define RAS_DEFAULT_HARDWARE_EINJ_SUPPORT     0
> +#define RAS_DEFAULT_PCIE_AER_FW_FIRST         0
> +#define RAS_DEFAULT_BERT_SUPPORT              1
> +#define RAS_DEFAULT_SDEI_SUPPORT              0
> +#define RAS_DEFAULT_DDR_CE_THRESHOLD          1
> +#define RAS_DEFAULT_2P_CE_THRESHOLD           1
> +#define RAS_DEFAULT_PROCESSOR_CE_THRESHOLD    1
> +#define RAS_DEFAULT_DDR_LINK_ERROR_THRESHOLD  1
> +
> +
> +HII_VENDOR_DEVICE_PATH mRasConfigHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    RAS_CONFIG_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +EFI_STATUS
> +RasConfigNvParamGet (
> +  OUT RAS_CONFIG_VARSTORE_DATA *Configuration
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_HARDWARE_EINJ,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_HARDWARE_EINJ_SUPPORT;
> +    Status = NVParamSet (
> +               NV_SI_HARDWARE_EINJ,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasHardwareEinj = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_RAS_PCIE_AER_FW_FIRST,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_PCIE_AER_FW_FIRST;
> +    Status = NVParamSet (
> +               NV_SI_RAS_PCIE_AER_FW_FIRST,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasPcieAerFwFirstEnabled = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_RAS_BERT_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_BERT_SUPPORT;
> +    Status = NVParamSet (
> +               NV_SI_RAS_BERT_ENABLED,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasBertEnabled = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_RAS_SDEI_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_SDEI_SUPPORT;
> +    Status = NVParamSet (
> +               NV_SI_RAS_SDEI_ENABLED,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasSdeiEnabled = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_DDR_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_DDR_CE_THRESHOLD;
> +    Status = NVParamSet (
> +               NV_SI_DDR_CE_RAS_THRESHOLD,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasDdrCeThreshold = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_2P_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_2P_CE_THRESHOLD;
> +    Status = NVParamSet (
> +               NV_SI_2P_CE_RAS_THRESHOLD,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->Ras2pCeThreshold = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_CPM_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_PROCESSOR_CE_THRESHOLD;
> +    Status = NVParamSet (
> +               NV_SI_CPM_CE_RAS_THRESHOLD,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasCpmCeThreshold = Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_LINK_ERR_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    Value = RAS_DEFAULT_DDR_LINK_ERROR_THRESHOLD;
> +    Status = NVParamSet (
> +               NV_SI_LINK_ERR_THRESHOLD,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               Value
> +               );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((DEBUG_ERROR, "%a:%d NVParamSet() failed!\n", __FUNCTION__, __LINE__));
> +      ASSERT_EFI_ERROR (Status);
> +      Value = 0;
> +    }
> +  }
> +  Configuration->RasLinkErrThreshold = Value;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +RasConfigNvParamSet (
> +  IN RAS_CONFIG_VARSTORE_DATA *Configuration
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  Status = NVParamSet (
> +             NV_SI_HARDWARE_EINJ,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasHardwareEinj
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_RAS_PCIE_AER_FW_FIRST,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasPcieAerFwFirstEnabled
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_RAS_BERT_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasBertEnabled
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_RAS_SDEI_ENABLED,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasSdeiEnabled
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_DDR_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasDdrCeThreshold
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_2P_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->Ras2pCeThreshold
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_CPM_CE_RAS_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasCpmCeThreshold
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  Status = NVParamSet (
> +             NV_SI_LINK_ERR_THRESHOLD,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             NV_PERM_BIOS | NV_PERM_MANU,
> +             Configuration->RasLinkErrThreshold
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RasConfigExtractConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Request,
> +  OUT      EFI_STRING                     *Progress,
> +  OUT      EFI_STRING                     *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  RAS_CONFIG_PRIVATE_DATA         *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  BOOLEAN                         AllocatedRequest;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mRasConfigFormSetGuid, RasConfigVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  PrivateData = RAS_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +
> +  //
> +  // Get current setting from NVParam.
> +  //
> +  Status = RasConfigNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  BufferSize = sizeof (RAS_CONFIG_VARSTORE_DATA);
> +  ConfigRequest = Request;
> +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> +    //
> +    // Request has no request element, construct full request string.
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (&mRasConfigFormSetGuid, RasConfigVarstoreDataName, PrivateData->DriverHandle);
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    if (ConfigRequest == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  Status = HiiConfigRouting->BlockToConfig (
> +                               HiiConfigRouting,
> +                               ConfigRequest,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               BufferSize,
> +                               Results,
> +                               Progress
> +                               );
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +    ConfigRequest = NULL;
> +  }
> +
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RasConfigRouteConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Configuration,
> +  OUT      EFI_STRING                     *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  RAS_CONFIG_PRIVATE_DATA         *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = RAS_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &mRasConfigFormSetGuid, RasConfigVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get configuration data from NVParam
> +  //
> +  Status = RasConfigNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (RAS_CONFIG_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store configuration data back to NVParam
> +  //
> +  Status = RasConfigNvParamSet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +
> +  @retval  EFI_SUCCESS           The callback successfully handled the action.
> +  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RasConfigCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  if (Action != EFI_BROWSER_ACTION_CHANGING) {
> +    //
> +    // Do nothing for other UEFI Action. Only do call back when data is changed.
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  if (((Value == NULL)
> +       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
> +       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
> +      || (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +UpdateRasConfigScreen (
> +  IN RAS_CONFIG_PRIVATE_DATA *PrivateData
> +  )
> +{
> +  EFI_STATUS         Status;
> +  VOID               *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +
> +  if (!IsSlaveSocketActive ()) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  if (StartLabel == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto FreeOpCodeBuffer;
> +  }
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  if (EndLabel == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto FreeOpCodeBuffer;
> +  }
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = LABEL_END;
> +
> +  //
> +  // Create the numeric for 2P CE threshold
> +  //
> +  HiiCreateNumericOpCode (
> +    StartOpCodeHandle,                             // Container for dynamic created opcodes
> +    0x8005,                                        // Question ID
> +    RAS_CONFIG_VARSTORE_ID,                        // VarStore ID
> +    (UINT16)RAS_2P_CE_THRESHOLD_OFST,              // Offset in Buffer Storage
> +    STRING_TOKEN (STR_RAS_2P_CE_THRESHOLD_PROMPT), // Question prompt text
> +    STRING_TOKEN (STR_RAS_2P_CE_THRESHOLD_HELP),
> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
> +    EFI_IFR_NUMERIC_SIZE_4,
> +    1,
> +    8192,
> +    1,
> +    NULL
> +    );
> +
> +  Status = HiiUpdateForm (
> +             PrivateData->HiiHandle,  // HII handle
> +             &mRasConfigFormSetGuid,  // Formset GUID
> +             RAS_CONFIG_FORM_ID,      // Form ID
> +             StartOpCodeHandle,       // Label for where to insert opcodes
> +             EndOpCodeHandle          // Insert data
> +             );
> +
> +FreeOpCodeBuffer:
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +RasConfigUnload (
> +  VOID
> +  )
> +{
> +  ASSERT (mPrivateData != NULL);
> +
> +  if (mDriverHandle != NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mRasConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    mDriverHandle = NULL;
> +  }
> +
> +  if (mPrivateData->HiiHandle != NULL) {
> +    HiiRemovePackages (mPrivateData->HiiHandle);
> +  }
> +
> +  FreePool (mPrivateData);
> +  mPrivateData = NULL;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +RasConfigEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (RAS_CONFIG_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = RAS_CONFIG_PRIVATE_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = RasConfigExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = RasConfigRouteConfig;
> +  mPrivateData->ConfigAccess.Callback = RasConfigCallback;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mDriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mRasConfigHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = mDriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &mRasConfigFormSetGuid,
> +                mDriverHandle,
> +                RasConfigDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mRasConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  Status = UpdateRasConfigScreen (mPrivateData);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a %d Fail to update Memory Configuration screen \n",
> +      __FUNCTION__,
> +      __LINE__
> +      ));
> +    RasConfigUnload ();
> +    ASSERT_EFI_ERROR (Status);
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
> new file mode 100644
> index 000000000000..c502093a2bbf
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/VfrStrings.uni
> @@ -0,0 +1,38 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US  "English"
> +
> +#string STR_RAS_FORM                                #language en-US "RAS Configuration"
> +#string STR_RAS_FORM_HELP                           #language en-US "RAS Configuration"
> +
> +#string STR_RAS_FORM_SEPERATE_LINE                  #language en-US ""
> +#string STR_RAS_COMMON_ENABLE                       #language en-US "Enabled"
> +#string STR_RAS_COMMON_DISABLE                      #language en-US "Disabled"
> +
> +#string STR_RAS_HARDWARE_EINJ_PROMPT                #language en-US "Hardware EINJ"
> +#string STR_RAS_HARDWARE_EINJ_HELP                  #language en-US "Enable hardware EINJ support, if disabled EINJ is software simulated"
> +
> +#string STR_RAS_PCIE_AER_FW_FIRST_PROMPT            #language en-US "PCIe AER Firmware First"
> +#string STR_RAS_PCIE_AER_FW_FIRST_HELP              #language en-US "Enable firmware to detect PCIe AER, if disabled OS detects AER"
> +
> +#string STR_RAS_BERT_ENABLED_PROMPT                 #language en-US "Enable BERT"
> +#string STR_RAS_BERT_ENABLED_HELP                   #language en-US "Enable Boot Error Record Table, if disabled BERT will not be populated"
> +
> +#string STR_RAS_SDEI_ENABLED_PROMPT                 #language en-US "Enable SDEI"
> +#string STR_RAS_SDEI_ENABLED_HELP                   #language en-US "Enable Software Delegated Exception Interface for NMI support"
> +
> +#string STR_RAS_DDR_CE_THRESHOLD_PROMPT             #language en-US "DDR CE Threshold"
> +#string STR_RAS_DDR_CE_THRESHOLD_HELP               #language en-US "Number of DDR CEs to occur before using SCI notification to OS rather than polled notification"
> +
> +#string STR_RAS_2P_CE_THRESHOLD_PROMPT              #language en-US "2P CE Threshold"
> +#string STR_RAS_2P_CE_THRESHOLD_HELP                #language en-US "Number of 2P CEs to occur before using SCI notification to OS rather than polled notification"
> +
> +#string STR_RAS_CPM_CE_THRESHOLD_PROMPT             #language en-US "Processor CE Threshold"
> +#string STR_RAS_CPM_CE_THRESHOLD_HELP               #language en-US "Number of processor CEs to occur before using SCI notification to OS rather than polled notification"
> +
> +#string STR_RAS_LINK_ERR_THRESHOLD_PROMPT           #language en-US "DDR Link Error Threshold"
> +#string STR_RAS_LINK_ERR_THRESHOLD_HELP             #language en-US "Number of DDR link errors before considering it fatal severity"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
@ 2021-06-07 23:24   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:24 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:19 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Provide menu options to configure Secure Watchdog and Non-Secure Watchdog
> timer.

Please give more description. Configure how?

> By default, the values of these options are 5 minutes.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                              |   3 +
>  Platform/Ampere/JadePkg/Jade.dsc                                              |   1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                              |   1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf |  50 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h         |  27 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h   |  82 ++++
>  Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h                |  19 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr               |  58 +++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c   | 460 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni        |  26 ++
>  10 files changed, 727 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index ede85d3a3421..53930869f4f6 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -56,6 +56,9 @@ [Guids]
>    # GUID for the ACPI HII configuration form
>    gAcpiConfigFormSetGuid = { 0x0ceb6764, 0xd415, 0x4b01, { 0xa8, 0x43, 0xd1, 0x01, 0xbc, 0xb0, 0xd8, 0x29 } }
>  
> +  # GUID for the Watchdog HII configuration form
> +  gWatchdogConfigFormSetGuid   = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } }
> +
>    ## NVParam MM GUID
>    gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
>  
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 26cf8be001ab..391ff75e237c 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -183,3 +183,4 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index c0b71a4732fa..431c9906e98e 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -358,5 +358,6 @@ [FV.FvMain]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/CpuConfigDxe/CpuConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
> new file mode 100644
> index 000000000000..530b7c3575f6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
> @@ -0,0 +1,50 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = WatchdogConfigDxe
> +  FILE_GUID                      = 135A0CA5-4851-4EF5-9E1A-C6E4610C39A9
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = WatchdogConfigInitialize
> +
> +[Sources.common]
> +  NVDataStruc.h
> +  Vfr.vfr
> +  VfrStrings.uni
> +  WatchdogConfigDxe.c
> +  WatchdogConfigDxe.h
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  DevicePathLib
> +  HiiLib
> +  NVParamLib
> +  PrintLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +
> +[Guids]
> +  gPlatformManagerFormsetGuid
> +  gWatchdogConfigFormSetGuid
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
> new file mode 100644
> index 000000000000..ad95c21e391f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/NVDataStruc.h
> @@ -0,0 +1,27 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef NVDATASTRUC_H_
> +#define NVDATASTRUC_H_
> +
> +#include <Guid/WatchdogConfigHii.h>
> +
> +#define WATCHDOG_CONFIG_VARSTORE_ID       0x1234
> +#define WATCHDOG_CONFIG_FORM_ID           0x1235
> +
> +#define NWDT_UEFI_DEFAULT_VALUE           300 // 5 minutes
> +#define SWDT_DEFAULT_VALUE                300 // 5 minutes
> +
> +#pragma pack(1)
> +typedef struct {
> +  UINT32 WatchdogTimerUEFITimeout;
> +  UINT32 SecureWatchdogTimerTimeout;
> +} WATCHDOG_CONFIG_VARSTORE_DATA;
> +#pragma pack()
> +
> +#endif
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
> new file mode 100644
> index 000000000000..fa2e5e062379
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.h
> @@ -0,0 +1,82 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef WATCHDOG_CONFIG_DXE_H_
> +#define WATCHDOG_CONFIG_DXE_H_
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/NVParamLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <NVParamDef.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigRouting.h>
> +
> +#include "NVDataStruc.h"
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +//
> +extern UINT8 VfrBin[];

WatchdogConfigVfrBin?

/
    Leif

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +//
> +extern UINT8 WatchdogConfigDxeStrings[];
> +
> +#define WATCHDOG_CONFIG_PRIVATE_SIGNATURE SIGNATURE_32 ('W', 'D', 'T', 'C')
> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE                    DriverHandle;
> +  EFI_HII_HANDLE                HiiHandle;
> +  WATCHDOG_CONFIG_VARSTORE_DATA Configuration;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} WATCHDOG_CONFIG_PRIVATE_DATA;
> +
> +#define WATCHDOG_CONFIG_PRIVATE_FROM_THIS(a)  CR (a, WATCHDOG_CONFIG_PRIVATE_DATA, ConfigAccess, WATCHDOG_CONFIG_PRIVATE_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +EFI_STATUS
> +WatchdogConfigNvParamSet (
> +  IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
> +  );
> +
> +EFI_STATUS
> +WatchdogConfigNvParamGet (
> +  OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
> +  );
> +
> +#endif /* WATCHDOG_CONFIG_DXE_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
> new file mode 100644
> index 000000000000..16319d61a759
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/WatchdogConfigHii.h
> @@ -0,0 +1,19 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef WATCHDOG_CONFIG_HII_H_
> +#define WATCHDOG_CONFIG_HII_H_
> +
> +#define WATCHDOG_CONFIG_FORMSET_GUID \
> +  { \
> +    0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } \
> +  }
> +
> +extern EFI_GUID gWatchdogConfigFormSetGuid;
> +
> +#endif /* WATCHDOG_CONFIG_HII_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..96b780ba9e7e
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/Vfr.vfr
> @@ -0,0 +1,58 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "NVDataStruc.h"
> +
> +formset
> +  guid      = WATCHDOG_CONFIG_FORMSET_GUID,
> +  title     = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM),
> +  help      = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  //
> +  // Define a variable Storage
> +  //
> +  varstore WATCHDOG_CONFIG_VARSTORE_DATA,
> +    varid   = WATCHDOG_CONFIG_VARSTORE_ID,
> +    name    = WatchdogConfigNVData,
> +    guid    = WATCHDOG_CONFIG_FORMSET_GUID;
> +
> +  form
> +    formid = WATCHDOG_CONFIG_FORM_ID,
> +    title  = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM);
> +    subtitle text = STRING_TOKEN(STR_WATCHDOG_CONFIG_FORM_HELP);
> +
> +    oneof varid = WatchdogConfigNVData.WatchdogTimerUEFITimeout,
> +      prompt      = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI),
> +      help        = STRING_TOKEN(STR_NWDT_TIMEOUT_UEFI_HELP),
> +      flags       = RESET_REQUIRED,
> +      option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
> +      default = NWDT_UEFI_DEFAULT_VALUE,
> +    endoneof;
> +
> +    oneof varid = WatchdogConfigNVData.SecureWatchdogTimerTimeout,
> +      prompt      = STRING_TOKEN(STR_SWDT_TIMEOUT),
> +      help        = STRING_TOKEN(STR_SWDT_TIMEOUT_HELP),
> +      flags       = RESET_REQUIRED,
> +      option text = STRING_TOKEN (STR_WDT_TIME_DISABLE), value = 0, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_5MIN), value = 300, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_6MIN), value = 360, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_10MIN), value = 600, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_15MIN), value = 900, flags = 0;
> +      option text = STRING_TOKEN (STR_WDT_TIME_20MIN), value = 1200, flags = 0;
> +      default = SWDT_DEFAULT_VALUE,
> +    endoneof;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
> new file mode 100644
> index 000000000000..98557b2fde8b
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.c
> @@ -0,0 +1,460 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include "WatchdogConfigDxe.h"
> +
> +CHAR16 WatchDogConfigVarstoreDataName[] = L"WatchdogConfigNVData";
> +
> +EFI_HANDLE                   mDriverHandle = NULL;
> +WATCHDOG_CONFIG_PRIVATE_DATA *mPrivateData = NULL;
> +
> +HII_VENDOR_DEVICE_PATH mWatchdogConfigHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    WATCHDOG_CONFIG_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +EFI_STATUS
> +WatchdogConfigNvParamGet (
> +  OUT WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +  BOOLEAN    SetDefault;
> +
> +  SetDefault = FALSE;
> +  Status = NVParamGet (
> +             NV_SI_WDT_BIOS_EXP_MINS,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->WatchdogTimerUEFITimeout = NWDT_UEFI_DEFAULT_VALUE;
> +    if (Status == EFI_NOT_FOUND) {
> +      SetDefault = TRUE;
> +    } else {
> +      ASSERT (FALSE);
> +    }
> +  } else {
> +    VarStoreConfig->WatchdogTimerUEFITimeout = Value * 60;
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_SEC_WDT_BIOS_EXP_MINS,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)) {
> +    VarStoreConfig->SecureWatchdogTimerTimeout = SWDT_DEFAULT_VALUE;
> +    if (Status == EFI_NOT_FOUND) {
> +      SetDefault = TRUE;
> +    } else {
> +      ASSERT (FALSE);
> +    }
> +  } else {
> +    VarStoreConfig->SecureWatchdogTimerTimeout = Value;
> +  }
> +
> +  if (SetDefault) {
> +    WatchdogConfigNvParamSet (VarStoreConfig);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +WatchdogConfigNvParamSet (
> +  IN WATCHDOG_CONFIG_VARSTORE_DATA *VarStoreConfig
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT32     Value;
> +
> +  Status = NVParamGet (
> +             NV_SI_WDT_BIOS_EXP_MINS,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)
> +      || Value != (VarStoreConfig->WatchdogTimerUEFITimeout / 60))
> +  {
> +    Status = NVParamSet (
> +               NV_SI_WDT_BIOS_EXP_MINS,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               (VarStoreConfig->WatchdogTimerUEFITimeout / 60)
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  Status = NVParamGet (
> +             NV_SI_SEC_WDT_BIOS_EXP_MINS,
> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +             &Value
> +             );
> +  if (EFI_ERROR (Status)
> +      || Value != VarStoreConfig->SecureWatchdogTimerTimeout)
> +  {
> +    Status = NVParamSet (
> +               NV_SI_SEC_WDT_BIOS_EXP_MINS,
> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
> +               NV_PERM_BIOS | NV_PERM_MANU,
> +               VarStoreConfig->SecureWatchdogTimerTimeout
> +               );
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This function allows a caller to extract the current configuration for one
> +  or more named elements from the target driver.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Request                A null-terminated Unicode string in
> +                                 <ConfigRequest> format.
> +  @param  Progress               On   return, points to a character in the Request
> +                                 string. Points to the string's null terminator if
> +                                 request was successful. Points to the most recent
> +                                 '&' before the first failing name/value pair (or
> +                                 the beginning of the string if the failure is in
> +                                 the first name/value pair) if the request was not
> +                                 successful.
> +  @param  Results                A null-terminated Unicode string in
> +                                 <ConfigAltResp> format which has all values filled
> +                                 in for the names in the Request string. String to
> +                                 be allocated by the called function.
> +
> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogConfigExtractConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Request,
> +  OUT      EFI_STRING                     *Progress,
> +  OUT      EFI_STRING                     *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  WATCHDOG_CONFIG_PRIVATE_DATA    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  BOOLEAN                         AllocatedRequest;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  PrivateData = WATCHDOG_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +
> +  //
> +  // Get current setting from NVParam.
> +  //
> +  Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
> +  ConfigRequest = Request;
> +  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> +    //
> +    // Request has no request element, construct full request string.
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (&gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName, PrivateData->DriverHandle);
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    if (ConfigRequest == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
> +    FreePool (ConfigRequestHdr);
> +  }
> +
> +  //
> +  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +  //
> +  Status = HiiConfigRouting->BlockToConfig (
> +                               HiiConfigRouting,
> +                               ConfigRequest,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               BufferSize,
> +                               Results,
> +                               Progress
> +                               );
> +
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +    ConfigRequest = NULL;
> +  }
> +
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogConfigRouteConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Configuration,
> +  OUT      EFI_STRING                     *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  WATCHDOG_CONFIG_PRIVATE_DATA    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = WATCHDOG_CONFIG_PRIVATE_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (Configuration, &gWatchdogConfigFormSetGuid, WatchDogConfigVarstoreDataName)) {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Get configuration data from NVParam
> +  //
> +  Status = WatchdogConfigNvParamGet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (WATCHDOG_CONFIG_VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)&PrivateData->Configuration,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //
> +  // Store configuration data back to NVParam
> +  //
> +  Status = WatchdogConfigNvParamSet (&PrivateData->Configuration);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +
> +  @retval  EFI_SUCCESS           The callback successfully handled the action.
> +  @retval  EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +WatchdogConfigCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  if (Action != EFI_BROWSER_ACTION_CHANGING) {
> +    //
> +    // Do nothing for other UEFI Action. Only do call back when data is changed.
> +    //
> +    return EFI_UNSUPPORTED;
> +  }
> +  if (((Value == NULL)
> +       && (Action != EFI_BROWSER_ACTION_FORM_OPEN)
> +       && (Action != EFI_BROWSER_ACTION_FORM_CLOSE))
> +      || (ActionRequest == NULL))
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +WatchdogConfigInitialize (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +
> +  //
> +  // Initialize driver private data
> +  //
> +  mPrivateData = AllocateZeroPool (sizeof (WATCHDOG_CONFIG_PRIVATE_DATA));
> +  if (mPrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->Signature = WATCHDOG_CONFIG_PRIVATE_SIGNATURE;
> +
> +  mPrivateData->ConfigAccess.ExtractConfig = WatchdogConfigExtractConfig;
> +  mPrivateData->ConfigAccess.RouteConfig = WatchdogConfigRouteConfig;
> +  mPrivateData->ConfigAccess.Callback = WatchdogConfigCallback;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&HiiConfigRouting);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &mDriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mWatchdogConfigHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &mPrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  mPrivateData->DriverHandle = mDriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gWatchdogConfigFormSetGuid,
> +                mDriverHandle,
> +                WatchdogConfigDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    gBS->UninstallMultipleProtocolInterfaces (
> +           mDriverHandle,
> +           &gEfiDevicePathProtocolGuid,
> +           &mWatchdogConfigHiiVendorDevicePath,
> +           &gEfiHiiConfigAccessProtocolGuid,
> +           &mPrivateData->ConfigAccess,
> +           NULL
> +           );
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  mPrivateData->HiiHandle = HiiHandle;
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
> new file mode 100644
> index 000000000000..1d0f820e456f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/VfrStrings.uni
> @@ -0,0 +1,26 @@
> +//
> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef en-US  "English"
> +
> +#string STR_WATCHDOG_CONFIG_FORM        #language en-US "Watchdog Configuration"
> +#string STR_WATCHDOG_CONFIG_FORM_HELP   #language en-US "Watchdog Configuration"
> +
> +#string STR_WDT_TIME_DISABLE            #language en-US  "Disabled"
> +#string STR_WDT_TIME_3MIN               #language en-US  "3 minutes"
> +#string STR_WDT_TIME_4MIN               #language en-US  "4 minutes"
> +#string STR_WDT_TIME_5MIN               #language en-US  "5 minutes"
> +#string STR_WDT_TIME_6MIN               #language en-US  "6 minutes"
> +#string STR_WDT_TIME_10MIN              #language en-US  "10 minutes"
> +#string STR_WDT_TIME_15MIN              #language en-US  "15 minutes"
> +#string STR_WDT_TIME_20MIN              #language en-US  "20 minutes"
> +
> +#string STR_NWDT_TIMEOUT_OS             #language en-US  "OS Watchdog Timeout"
> +#string STR_NWDT_TIMEOUT_OS_HELP        #language en-US  "Timeout when boot OS."
> +#string STR_NWDT_TIMEOUT_UEFI           #language en-US  "UEFI Watchdog Timeout"
> +#string STR_NWDT_TIMEOUT_UEFI_HELP      #language en-US  "Timeout when boot UEFI"
> +#string STR_SWDT_TIMEOUT                #language en-US  "Secure Watchdog Timeout"
> +#string STR_SWDT_TIMEOUT_HELP           #language en-US  "Timeout when SCP will reset system if it doesn't receive response from ARMv8."
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
@ 2021-06-07 23:34   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:34 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:20 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This screen provide menu options to configure Max Payload and Max Read
> Request size for each PCIe device under Root Port. PCIe devices which
> attach to external switch are not supported yet.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                  |    3 +
>  Platform/Ampere/JadePkg/Jade.dsc                                                  |    1 +
>  Platform/Ampere/JadePkg/Jade.fdf                                                  |    1 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf |   59 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h           |   56 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h   |   78 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h            |   58 ++
>  Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h                  |   19 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr                 |   50 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c   | 1046 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c            |  191 ++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni |   24 +
>  12 files changed, 1586 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> index 53930869f4f6..62e27c8b49b2 100644
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> @@ -59,6 +59,9 @@ [Guids]
>    # GUID for the Watchdog HII configuration form
>    gWatchdogConfigFormSetGuid   = { 0xC3F8EC6E, 0x95EE, 0x460C, { 0xA4, 0x8D, 0xEA, 0x54, 0x2F, 0xFF, 0x01, 0x61 } }
>  
> +  # GUID for the Pcie Device HII configuration form
> +  gPcieDeviceConfigFormSetGuid = { 0xEC7B1D21, 0x9167, 0x4B9D, { 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, 0x59 } }
> +
>    ## NVParam MM GUID
>    gNVParamMmGuid               = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } }
>  
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 391ff75e237c..9d787113e3b5 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -184,3 +184,4 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 431c9906e98e..b0c2894d00f8 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -359,5 +359,6 @@ [FV.FvMain]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/AcpiConfigDxe/AcpiConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>  
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
> new file mode 100644
> index 000000000000..a04c79661842
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
> @@ -0,0 +1,59 @@
> +## @file
> +#
> +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PcieDeviceConfigDxe
> +  FILE_GUID                      = 17E9369D-0A1B-45F4-A286-B1DED6D85D33
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = PcieDeviceConfigEntryPoint
> +
> +[Sources.common]
> +  NVDataStruc.h
> +  PcieDeviceConfigDxe.c
> +  PcieDeviceConfigDxe.h
> +  PcieDeviceConfigDxe.uni
> +  PcieHelper.c
> +  PcieHelper.h
> +  Vfr.vfr
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  HiiLib
> +  MemoryAllocationLib
> +  PrintLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Protocols]
> +  gEfiPciIoProtocolGuid
> +  gEfiDevicePathProtocolGuid                    ## CONSUMES
> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
> +  gEfiDevicePathToTextProtocolGuid
> +
> +[Guids]
> +  gEfiIfrTianoGuid
> +  gPcieDeviceConfigFormSetGuid
> +  gPlatformManagerFormsetGuid
> +  gPlatformManagerEntryEventGuid
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
> new file mode 100644
> index 000000000000..fb168e495670
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/NVDataStruc.h
> @@ -0,0 +1,56 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef NVDATASTRUC_H_
> +#define NVDATASTRUC_H_
> +
> +#include <Guid/PcieDeviceConfigHii.h>
> +
> +#define VARSTORE_NAME   L"PcieDeviceConfigNVData"
> +
> +#define MAIN_FORM_ID    0x01
> +#define DEVICE_FORM_ID  0x02
> +#define VARSTORE_ID     0x03
> +
> +#define MAIN_LABEL_UPDATE   0x21
> +#define MAIN_LABEL_END      0x22
> +#define DEVICE_LABEL_UPDATE 0x31
> +#define DEVICE_LABEL_END    0x32
> +
> +#define DEVICE_KEY          0x6000
> +#define MPS_ONE_OF_KEY      0x7000
> +#define MRR_ONE_OF_KEY      0x8000
> +
> +#define MAX_DEVICE          40
> +
> +#define DEFAULT_MPS         0x00 // Section 7.5.3.4
> +#define DEFAULT_MRR         0x02 // Section 7.5.3.4
> +
> +#define PCIE_ADD(Vid, Did, Seg, Bus, Dev) \
> +        (UINT64)(Vid) << 40 | (UINT64)(Did) << 24 | Seg << 16 | Bus << 8 | Dev;
> +
> +#pragma pack(1)
> +
> +typedef struct {
> +  UINT8  DEV;
> +  UINT8  BUS;
> +  UINT8  SEG;
> +  UINT16 DID;
> +  UINT16 VID;
> +  UINT8  SlotId;
> +} SLOT_INFO;
> +
> +typedef struct {
> +  UINT8  MPS[MAX_DEVICE];
> +  UINT8  MRR[MAX_DEVICE];
> +  UINT64 SlotInfo[MAX_DEVICE];
> +} VARSTORE_DATA;
> +
> +#pragma pack()
> +
> +#endif // NVDATASTRUC_H_
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
> new file mode 100644
> index 000000000000..40d7da1ef277
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.h
> @@ -0,0 +1,78 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_DEVICE_CONFIG_H_
> +#define PCIE_DEVICE_CONFIG_H_

Again, concern with claiming part of global PCIE namespace.

> +
> +#include <Uefi.h>
> +
> +#include <Library/HiiLib.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/HiiConfigKeyword.h>
> +#include <Protocol/HiiConfigRouting.h>
> +#include <Protocol/HiiDatabase.h>
> +#include <Protocol/HiiString.h>
> +
> +#include "NVDataStruc.h"
> +
> +#define MAX_STRING_SIZE              100
> +
> +#define PRIVATE_DATA_SIGNATURE        SIGNATURE_32 ('P', 'E', 'D', 'C')
> +#define PRIVATE_DATA_FROM_THIS(a)     \
> +             CR (a, PRIVATE_DATA, ConfigAccess, PRIVATE_DATA_SIGNATURE)
> +
> +#pragma pack(1)
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> +  VENDOR_DEVICE_PATH       VendorDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +#pragma pack()
> +
> +//
> +// This is the generated IFR binary data for each formset defined in VFR.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 VfrBin[];

PlatformPcieDeviceConfigVfrBin?

> +
> +//
> +// This is the generated String package data for all .UNI files.
> +// This data array is ready to be used as input of HiiAddPackages() to
> +// create a packagelist (which contains Form packages, String packages, etc).
> +//
> +extern UINT8 PcieDeviceConfigDxeStrings[];
> +
> +typedef struct {
> +  UINTN Signature;
> +
> +  EFI_HANDLE     DriverHandle;
> +  EFI_HII_HANDLE HiiHandle;
> +  VARSTORE_DATA  LastVarStoreConfig;
> +  VARSTORE_DATA  VarStoreConfig;
> +
> +  //
> +  // Consumed protocol
> +  //
> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
> +  EFI_HII_STRING_PROTOCOL             *HiiString;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
> +  EFI_FORM_BROWSER2_PROTOCOL          *FormBrowser2;
> +
> +  //
> +  // Produced protocol
> +  //
> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> +} PRIVATE_DATA;
> +
> +#endif // PCIE_DEVICE_CONFIG_H_
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
> new file mode 100644
> index 000000000000..32787865119d
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.h
> @@ -0,0 +1,58 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_HELPER_H_
> +#define PCIE_HELPER_H_
> +
> +#define PCIE_MAX_PAYLOAD_MASK         0x07
> +#define PCIE_CONTROL_MAX_PAYLOAD_OFF  5
> +#define PCIE_MAX_READ_REQUEST_MASK    0x07
> +#define PCIE_CONTROL_READ_REQUEST_OFF 12
> +
> +#define PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG 0x04
> +#define PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG      0x08
> +
> +#define FOR_EACH(Node, Tail, Type) \
> +        for (Node = Tail->Type; Node != NULL; Node = Node->Type)
> +
> +struct _PCIE_NODE {
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  UINT8               MaxMps;
> +  UINT8               PcieCapOffset;
> +  UINT16              Vid;
> +  UINT16              Did;
> +  UINT8               Seg;
> +  UINT8               Bus;
> +  UINT8               Dev;
> +  UINT8               Fun;
> +  struct _PCIE_NODE   *Parent;
> +  struct _PCIE_NODE   *Brother;
> +};
> +
> +typedef struct _PCIE_NODE PCIE_NODE;
> +
> +EFI_STATUS
> +WriteMps (
> +  PCIE_NODE *Node,
> +  UINT8     Value
> +  );
> +
> +EFI_STATUS
> +WriteMrr (
> +  PCIE_NODE *Node,
> +  UINT8     Value
> +  );
> +
> +EFI_STATUS
> +FindCapabilityPtr (
> +  IN  EFI_PCI_IO_PROTOCOL *PciIo,
> +  IN  UINT8               CapabilityId,
> +  OUT UINT8               *CapabilityPtr
> +  );
> +
> +#endif // PCIE_HELPER_H_
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
> new file mode 100644
> index 000000000000..04b950abd49e
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Guid/PcieDeviceConfigHii.h
> @@ -0,0 +1,19 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCIE_DEVICE_CONFIG_HII_H_
> +#define PCIE_DEVICE_CONFIG_HII_H_
> +
> +#define PCIE_DEVICE_CONFIG_FORMSET_GUID \
> +  { \
> +    0xEC7B1D21, 0x9167, 0x4B9D, { 0xF7, 0x94, 0xCD, 0x1A, 0xEB, 0xBC, 0xB7, 0x59 } \
> +  }
> +
> +extern EFI_GUID gPcieDeviceConfigFormSetGuid;
> +
> +#endif /* PCIE_DEVICE_CONFIG_HII_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
> new file mode 100644
> index 000000000000..b5b16802b23e
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/Vfr.vfr
> @@ -0,0 +1,50 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/PlatformManagerHii.h>
> +#include "NVDataStruc.h"
> +
> +formset
> +  guid    = PCIE_DEVICE_CONFIG_FORMSET_GUID,
> +  title   = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM),
> +  help    = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_HELP),
> +  classguid = gPlatformManagerFormsetGuid,
> +
> +  //
> +  // Define a variable Storage
> +  //
> +  varstore VARSTORE_DATA,
> +    varid   = VARSTORE_ID,
> +    name    = PcieDeviceConfigNVData,
> +    guid    = PCIE_DEVICE_CONFIG_FORMSET_GUID;
> +
> +  form
> +    formid = MAIN_FORM_ID,
> +    title = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_PCIE_DEVICE_CONFIG_FORM);
> +
> +    label MAIN_LABEL_UPDATE;
> +    // dynamic content here
> +    label MAIN_LABEL_END;
> +
> +  endform;
> +
> +  form
> +    formid = DEVICE_FORM_ID,
> +    title = STRING_TOKEN(STR_DEVICE_FORM);
> +
> +    subtitle text = STRING_TOKEN(STR_DEVICE_FORM);
> +
> +    label DEVICE_LABEL_UPDATE;
> +    // dynamic content here
> +    label DEVICE_LABEL_END;
> +
> +  endform;
> +
> +endformset;
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
> new file mode 100644
> index 000000000000..a04f789530c0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.c
> @@ -0,0 +1,1046 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/PcieDeviceConfigHii.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/PciIo.h>
> +
> +#include "PcieDeviceConfigDxe.h"
> +#include "PcieHelper.h"
> +
> +VOID          *mPciProtocolNotifyRegistration;
> +CHAR16        *mVariableName = VARSTORE_NAME;
> +PCIE_NODE     *mDeviceBuf[MAX_DEVICE] = {NULL};
> +
> +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
> +  {
> +    {
> +      HARDWARE_DEVICE_PATH,
> +      HW_VENDOR_DP,
> +      {
> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    PCIE_DEVICE_CONFIG_FORMSET_GUID
> +  },
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      (UINT8)(END_DEVICE_PATH_LENGTH),
> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
> +    }
> +  }
> +};
> +
> +VOID
> +FlushDeviceData (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_STATUS    Status;
> +  PCIE_NODE     *Node;
> +  PRIVATE_DATA  *PrivateData;
> +  UINT8         Index;
> +  VARSTORE_DATA *LastVarStoreConfig;
> +  VARSTORE_DATA *VarStoreConfig;
> +
> +  PrivateData = (PRIVATE_DATA *)Context;
> +  LastVarStoreConfig = &PrivateData->LastVarStoreConfig;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +
> +  //
> +  // If config has changed, update NVRAM
> +  //
> +  if (CompareMem (VarStoreConfig, LastVarStoreConfig, sizeof (VARSTORE_DATA)) != 0) {
> +    DEBUG ((DEBUG_INFO, "%a Update Device Config Variable\n", __FUNCTION__));
> +    Status = gRT->SetVariable (
> +                    mVariableName,
> +                    &gPcieDeviceConfigFormSetGuid,
> +                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
> +                    sizeof (VARSTORE_DATA),
> +                    VarStoreConfig
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "%a: Failed to set variable status %r",
> +        __FUNCTION__,
> +        Status
> +        ));
> +      return;
> +    }
> +  }
> +
> +  // Iterate through the list, then write corresponding MPS MRR
> +  for (Index = 0; Index < MAX_DEVICE; Index++) {
> +    if (mDeviceBuf[Index] == NULL) {
> +      continue;
> +    }
> +
> +    // Write MPS value
> +    WriteMps (mDeviceBuf[Index], VarStoreConfig->MPS[Index]);
> +
> +    FOR_EACH (Node, mDeviceBuf[Index], Parent) {
> +      WriteMps (Node, VarStoreConfig->MPS[Index]);
> +    }
> +
> +    FOR_EACH (Node, mDeviceBuf[Index], Brother) {
> +      WriteMps (Node, VarStoreConfig->MPS[Index]);
> +    }
> +
> +    // Write MRR value
> +    // FIXME: No need to update MRR of parent node

Please drop FIXME.

> +    WriteMrr (mDeviceBuf[Index], VarStoreConfig->MRR[Index]);
> +
> +    FOR_EACH (Node, mDeviceBuf[Index], Brother) {
> +      WriteMrr (Node, VarStoreConfig->MRR[Index]);
> +    }
> +  }
> +
> +  gBS->CloseEvent (Event);
> +}
> +
> +EFI_STATUS
> +UpdateDeviceForm (
> +  UINT8        Index,
> +  PRIVATE_DATA *PrivateData
> +  )
> +{
> +  CHAR16 Str[MAX_STRING_SIZE];
> +  UINT8  MaxMps;
> +
> +  VOID               *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +  VOID               *MpsOpCodeHandle;
> +  VOID               *MrrOpCodeHandle;
> +  PCIE_NODE          *Node;
> +
> +  if (mDeviceBuf[Index] == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  MaxMps = mDeviceBuf[Index]->MaxMps;
> +  FOR_EACH (Node, mDeviceBuf[Index], Parent) {
> +    if (Node->MaxMps < MaxMps) {
> +      MaxMps = Node->MaxMps;
> +    }
> +  }
> +
> +  UnicodeSPrint (
> +    Str,
> +    sizeof (Str),
> +    L"PCIe Device 0x%04x:0x%04x",
> +    mDeviceBuf[Index]->Vid,
> +    mDeviceBuf[Index]->Did
> +    );
> +
> +  HiiSetString (
> +    PrivateData->HiiHandle,
> +    STRING_TOKEN (STR_DEVICE_FORM),
> +    Str,
> +    NULL
> +    );
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = DEVICE_LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = DEVICE_LABEL_END;
> +
> +  // Create Option OpCode for MPS selection
> +  MpsOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (MpsOpCodeHandle != NULL);
> +
> +  switch (MaxMps) {
> +  case 5:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_4096),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      5
> +      );
> +
> +  case 4:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_2048),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      4
> +      );
> +
> +  case 3:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_1024),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      3
> +      );
> +
> +  case 2:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_512),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      2
> +      );
> +
> +  case 1:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_256),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      1
> +      );
> +
> +  case 0:
> +    HiiCreateOneOfOptionOpCode (
> +      MpsOpCodeHandle,
> +      STRING_TOKEN (STR_128),
> +      0,
> +      EFI_IFR_NUMERIC_SIZE_1,
> +      0
> +      );
> +  }
> +
> +  // Create MPS OneOf
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                // Container for dynamic created opcodes
> +    (MPS_ONE_OF_KEY + Index),         // Question ID (or call it "key")
> +    VARSTORE_ID,                      // VarStore ID
> +    Index,                            // Offset in Buffer Storage
> +    STRING_TOKEN (STR_PCIE_MPS),      // Question prompt text
> +    STRING_TOKEN (STR_PCIE_MPS_HELP), // Question help text
> +    EFI_IFR_FLAG_CALLBACK,            // Question flag
> +    EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
> +    MpsOpCodeHandle,                  // Option Opcode list
> +    NULL                              // Default Opcode is NULl
> +    );
> +
> +  // Create Option OpCode for MRR selection
> +  MrrOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (MrrOpCodeHandle != NULL);
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_4096),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    5
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_2048),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    4
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_1024),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    3
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_512),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    2
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_256),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    1
> +    );
> +
> +  HiiCreateOneOfOptionOpCode (
> +    MrrOpCodeHandle,
> +    STRING_TOKEN (STR_128),
> +    0,
> +    EFI_IFR_NUMERIC_SIZE_1,
> +    0
> +    );
> +
> +  // Create MRR OneOf
> +  HiiCreateOneOfOpCode (
> +    StartOpCodeHandle,                // Container for dynamic created opcodes
> +    (MRR_ONE_OF_KEY + Index),         // Question ID (or call it "key")
> +    VARSTORE_ID,                      // VarStore ID
> +    MAX_DEVICE + Index,               // Offset in Buffer Storage
> +    STRING_TOKEN (STR_PCIE_MRR),      // Question prompt text
> +    STRING_TOKEN (STR_PCIE_MRR_HELP), // Question help text
> +    EFI_IFR_FLAG_CALLBACK,            // Question flag
> +    EFI_IFR_NUMERIC_SIZE_1,           // Data type of Question Value
> +    MrrOpCodeHandle,                  // Option Opcode list
> +    NULL                              // Default Opcode is NULl
> +    );
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,        // HII handle
> +    &gPcieDeviceConfigFormSetGuid, // Formset GUID
> +    DEVICE_FORM_ID,                // Form ID
> +    StartOpCodeHandle,             // Label for where to insert opcodes
> +    EndOpCodeHandle                // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +  HiiFreeOpCodeHandle (MpsOpCodeHandle);
> +  HiiFreeOpCodeHandle (MrrOpCodeHandle);
> +  return EFI_SUCCESS;
> +}
> +
> +VOID
> +OnPciIoProtocolNotify (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  EFI_STATUS          Status;
> +  EFI_HANDLE          HandleBuffer;
> +  PCI_TYPE00          Pci;
> +
> +  UINTN BufferSize;
> +  UINTN PciBusNumber;
> +  UINTN PciDeviceNumber;
> +  UINTN PciFunctionNumber;
> +  UINTN PciSegment;
> +
> +  UINT8  Idx;
> +  UINT8  CapabilityPtr;
> +  UINT16 TmpValue;
> +  UINT64 SlotInfo;
> +
> +  PCIE_NODE        *Node;
> +  PRIVATE_DATA     *PrivateData;
> +  STATIC PCIE_NODE *LastNode;
> +  STATIC UINT8     Index;
> +  STATIC UINT8     LastBus;
> +
> +  VARSTORE_DATA    *LastVarStoreConfig;
> +  VARSTORE_DATA    *VarStoreConfig;
> +
> +  PrivateData = (PRIVATE_DATA *)Context;
> +  LastVarStoreConfig = &PrivateData->LastVarStoreConfig;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +
> +  while (TRUE) {
> +    BufferSize = sizeof (EFI_HANDLE);
> +    Status = gBS->LocateHandle (
> +                    ByRegisterNotify,
> +                    NULL,
> +                    mPciProtocolNotifyRegistration,
> +                    &BufferSize,
> +                    &HandleBuffer
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +
> +    Status = gBS->HandleProtocol (
> +                    HandleBuffer,
> +                    &gEfiPciIoProtocolGuid,
> +                    (VOID **)&PciIo
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +
> +    // Get device bus location
> +    Status = PciIo->GetLocation (
> +                      PciIo,
> +                      &PciSegment,
> +                      &PciBusNumber,
> +                      &PciDeviceNumber,
> +                      &PciFunctionNumber
> +                      );
> +    if (EFI_ERROR (Status) ||
> +        ((PciBusNumber == 0) && (PciDeviceNumber == 0)))
> +    {
> +      // Filter out Host Bridge
> +      DEBUG ((DEBUG_INFO, "Filter out Host Bridge %x\n", PciSegment));
> +      continue;
> +    }
> +
> +    DEBUG ((
> +      DEBUG_INFO,
> +      ">> Dev 0x%04x:0x%02x:0x%02x:0x%02x\n",
> +      PciSegment,
> +      PciBusNumber,
> +      PciDeviceNumber,
> +      PciFunctionNumber
> +      ));
> +
> +    Status = FindCapabilityPtr (PciIo, EFI_PCI_CAPABILITY_ID_PCIEXP, &CapabilityPtr);
> +    if (EFI_ERROR (Status)) {
> +      DEBUG ((
> +        DEBUG_ERROR,
> +        "%a: PCI Express Capability not found\n",
> +        __FUNCTION__
> +        ));
> +      continue;
> +    }
> +
> +    // Get Device's max MPS support
> +    Status = PciIo->Pci.Read (
> +                          PciIo,
> +                          EfiPciIoWidthUint16,
> +                          CapabilityPtr + PCI_EXPRESS_CAPABILITY_DEVICE_CAPABILITIES_REG,
> +                          1,
> +                          &TmpValue
> +                          );
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +
> +    // Read device's VID:PID
> +    Status = PciIo->Pci.Read (
> +                          PciIo,
> +                          EfiPciIoWidthUint32,
> +                          0,
> +                          sizeof (Pci) / sizeof (UINT32),
> +                          &Pci
> +                          );
> +    if (EFI_ERROR (Status)) {
> +      continue;
> +    }
> +    DEBUG ((
> +      DEBUG_INFO,
> +      "VendorId 0x%04x - DeviceId 0x%04x\n",
> +      Pci.Hdr.VendorId,
> +      Pci.Hdr.DeviceId
> +      ));
> +
> +    Node = AllocateZeroPool (sizeof (*Node));
> +    Node->MaxMps = TmpValue & PCIE_MAX_PAYLOAD_MASK;
> +    Node->PcieCapOffset = CapabilityPtr;
> +    Node->PciIo = PciIo;
> +    Node->Seg = PciSegment;
> +    Node->Bus = PciBusNumber;
> +    Node->Dev = PciDeviceNumber;
> +    Node->Fun = PciFunctionNumber;
> +    Node->Vid = Pci.Hdr.VendorId;
> +    Node->Did = Pci.Hdr.DeviceId;
> +    SlotInfo = PCIE_ADD (Node->Vid, Node->Did, Node->Seg, Node->Bus, Node->Dev);
> +
> +    // Presume child devices were registered follow root port
> +    if (PciBusNumber != 0) {
> +      if (LastBus == 0) {
> +        Node->Parent = LastNode;
> +        mDeviceBuf[Index] = Node;
> +
> +        VarStoreConfig->MPS[Index] = DEFAULT_MPS;
> +        VarStoreConfig->MRR[Index] = DEFAULT_MRR;
> +        VarStoreConfig->SlotInfo[Index] = SlotInfo;
> +
> +        // Retrieve setting from previous variable
> +        for (Idx = 0; Idx < MAX_DEVICE; Idx++) {
> +          if (SlotInfo == LastVarStoreConfig->SlotInfo[Idx]) {
> +            VarStoreConfig->MPS[Index] = LastVarStoreConfig->MPS[Idx];
> +            VarStoreConfig->MRR[Index] = LastVarStoreConfig->MRR[Idx];
> +            break;
> +          }
> +        }
> +
> +        Index++;
> +      } else if (PciBusNumber == LastBus) {
> +        LastNode->Brother = Node;
> +      } else {
> +        // Ignore devices don't stay under root port
> +        continue;
> +      }
> +    }
> +
> +    LastBus = PciBusNumber;
> +    LastNode = Node;
> +  }
> +}
> +
> +VOID
> +UpdateMainForm (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  UINTN              Index;
> +  EFI_STRING_ID      StrId;
> +  CHAR16             Str[MAX_STRING_SIZE];
> +  VOID               *StartOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *StartLabel;
> +  VOID               *EndOpCodeHandle;
> +  EFI_IFR_GUID_LABEL *EndLabel;
> +  PRIVATE_DATA       *PrivateData;
> +
> +  DEBUG ((DEBUG_INFO, "%a Entry ...\n", __FUNCTION__));
> +
> +  PrivateData = (PRIVATE_DATA *)Context;
> +
> +  //
> +  // Initialize the container for dynamic opcodes
> +  //
> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (StartOpCodeHandle != NULL);
> +
> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> +  ASSERT (EndOpCodeHandle != NULL);
> +
> +  //
> +  // Create Hii Extend Label OpCode as the start opcode
> +  //
> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                       StartOpCodeHandle,
> +                                       &gEfiIfrTianoGuid,
> +                                       NULL,
> +                                       sizeof (EFI_IFR_GUID_LABEL)
> +                                       );
> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  StartLabel->Number       = MAIN_LABEL_UPDATE;
> +
> +  //
> +  // Create Hii Extend Label OpCode as the end opcode
> +  //
> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
> +                                     EndOpCodeHandle,
> +                                     &gEfiIfrTianoGuid,
> +                                     NULL,
> +                                     sizeof (EFI_IFR_GUID_LABEL)
> +                                     );
> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +  EndLabel->Number       = MAIN_LABEL_END;
> +
> +  for (Index = 0; Index < MAX_DEVICE; Index++) {
> +    if (mDeviceBuf[Index] == NULL) {
> +      break;
> +    }
> +    DEBUG ((DEBUG_INFO, ">> Add item %d\n", Index));
> +
> +    // TODO: convert and store in SlotID ex:SystemSlot(seg, bus, dev)

Please drop TODO.

> +    UnicodeSPrint (
> +      Str,
> +      sizeof (Str),
> +      L"PCIe Device 0x%04x:0x%04x - %04x:%02x:%02x",
> +      mDeviceBuf[Index]->Vid,
> +      mDeviceBuf[Index]->Did,
> +      mDeviceBuf[Index]->Seg,
> +      mDeviceBuf[Index]->Bus,
> +      mDeviceBuf[Index]->Dev
> +      );
> +
> +    StrId = HiiSetString (PrivateData->HiiHandle, 0, Str, NULL);
> +
> +    //
> +    // Create a Goto OpCode to device configuration
> +    //
> +    HiiCreateGotoOpCode (
> +      StartOpCodeHandle,                   // Container for dynamic created opcodes
> +      DEVICE_FORM_ID,                      // Target Form ID
> +      StrId,                               // Prompt text
> +      STRING_TOKEN (STR_DEVICE_GOTO_HELP), // Help text
> +      EFI_IFR_FLAG_CALLBACK,               // Question flag
> +      (DEVICE_KEY + Index)                 // Question ID
> +      );
> +  }
> +
> +  HiiUpdateForm (
> +    PrivateData->HiiHandle,         // HII handle
> +    &gPcieDeviceConfigFormSetGuid,  // Formset GUID
> +    MAIN_FORM_ID,                   // Form ID
> +    StartOpCodeHandle,              // Label for where to insert opcodes
> +    EndOpCodeHandle                 // Insert data
> +    );
> +
> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
> +
> +  gBS->CloseEvent (Event);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +ExtractConfig (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN CONST EFI_STRING                     Request,
> +  OUT      EFI_STRING                     *Progress,
> +  OUT      EFI_STRING                     *Results
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  PRIVATE_DATA                    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_STRING                      ConfigRequest;
> +  EFI_STRING                      ConfigRequestHdr;
> +  UINTN                           Size;
> +  CHAR16                          *StrPointer;
> +  BOOLEAN                         AllocatedRequest;
> +  VARSTORE_DATA                   *VarStoreConfig;
> +
> +  if (Progress == NULL || Results == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  //
> +  // Initialize the local variables.
> +  //
> +  ConfigRequestHdr  = NULL;
> +  ConfigRequest     = NULL;
> +  Size              = 0;
> +  *Progress         = Request;
> +  AllocatedRequest  = FALSE;
> +
> +  PrivateData = PRIVATE_DATA_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  BufferSize = sizeof (VARSTORE_DATA);
> +
> +  if (Request == NULL) {
> +    //
> +    // Request is set to NULL, construct full request string.
> +    //
> +
> +    //
> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
> +    // Null-terminator
> +    //
> +    ConfigRequestHdr = HiiConstructConfigHdr (
> +                         &gPcieDeviceConfigFormSetGuid,
> +                         mVariableName,
> +                         PrivateData->DriverHandle
> +                         );
> +    if (ConfigRequestHdr == NULL) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> +    ConfigRequest = AllocateZeroPool (Size);
> +    ASSERT (ConfigRequest != NULL);
> +    AllocatedRequest = TRUE;
> +    UnicodeSPrint (
> +      ConfigRequest,
> +      Size,
> +      L"%s&OFFSET=0&WIDTH=%016LX",
> +      ConfigRequestHdr,
> +      (UINT64)BufferSize
> +      );
> +    FreePool (ConfigRequestHdr);
> +    ConfigRequestHdr = NULL;
> +  } else {
> +    //
> +    // Check routing data in <ConfigHdr>.
> +    // Note: if only one Storage is used, then this checking could be skipped.
> +    //
> +    if (!HiiIsConfigHdrMatch (Request, &gPcieDeviceConfigFormSetGuid, NULL)) {
> +      return EFI_NOT_FOUND;
> +    }
> +    //
> +    // Set Request to the unified request string.
> +    //
> +    ConfigRequest = Request;
> +
> +    //
> +    // Check whether Request includes Request Element.
> +    //
> +    if (StrStr (Request, L"OFFSET") == NULL) {
> +      //
> +      // Check Request Element does exist in Request String
> +      //
> +      StrPointer = StrStr (Request, L"PATH");
> +      if (StrPointer == NULL) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +      if (StrStr (StrPointer, L"&") == NULL) {
> +        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
> +        ConfigRequest    = AllocateZeroPool (Size);
> +        ASSERT (ConfigRequest != NULL);
> +        AllocatedRequest = TRUE;
> +        UnicodeSPrint (
> +          ConfigRequest,
> +          Size,
> +          L"%s&OFFSET=0&WIDTH=%016LX",
> +          Request,
> +          (UINT64)BufferSize
> +          );
> +      }
> +    }
> +  }
> +  //
> +  // Check if requesting Name/Value storage
> +  //
> +  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    Status = EFI_SUCCESS;
> +  } else {
> +    //
> +    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
> +    //
> +    Status = HiiConfigRouting->BlockToConfig (
> +                                 HiiConfigRouting,
> +                                 ConfigRequest,
> +                                 (UINT8 *)VarStoreConfig,
> +                                 BufferSize,
> +                                 Results,
> +                                 Progress
> +                                 );
> +  }
> +  //
> +  // Free the allocated config request string.
> +  //
> +  if (AllocatedRequest) {
> +    FreePool (ConfigRequest);
> +  }
> +  if (ConfigRequestHdr != NULL) {
> +    FreePool (ConfigRequestHdr);
> +  }
> +  //
> +  // Set Progress string to the original request string.
> +  //
> +  if (Request == NULL) {
> +    *Progress = NULL;
> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
> +    *Progress = Request + StrLen (Request);
> +  }
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
> +                                 format.
> +  @param  Progress               A pointer to a string filled in with the offset of
> +                                 the most recent '&' before the first failing
> +                                 name/value pair (or the beginning of the string if
> +                                 the failure is in the first name/value pair) or
> +                                 the terminating NULL if all was successful.
> +  @retval EFI_SUCCESS            The Results is processed successfully.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
> +                                 driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RouteConfig (
> +  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN  CONST EFI_STRING                     Configuration,
> +  OUT EFI_STRING                           *Progress
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           BufferSize;
> +  PRIVATE_DATA                    *PrivateData;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  VARSTORE_DATA                   *VarStoreConfig;
> +
> +  if (Configuration == NULL || Progress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  PrivateData = PRIVATE_DATA_FROM_THIS (This);
> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
> +  *Progress = Configuration;
> +  VarStoreConfig = &PrivateData->VarStoreConfig;
> +  ASSERT (VarStoreConfig != NULL);
> +
> +  //
> +  // Check routing data in <ConfigHdr>.
> +  // Note: if only one Storage is used, then this checking could be skipped.
> +  //
> +  if (!HiiIsConfigHdrMatch (
> +         Configuration,
> +         &gPcieDeviceConfigFormSetGuid,
> +         NULL
> +         ))
> +  {
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  //
> +  // Check if configuring Name/Value storage
> +  //
> +  if (StrStr (Configuration, L"OFFSET") == NULL) {
> +    //
> +    // Don't have any Name/Value storage names
> +    //
> +    return EFI_SUCCESS;
> +  }
> +  //
> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
> +  //
> +  BufferSize = sizeof (VARSTORE_DATA);
> +  Status = HiiConfigRouting->ConfigToBlock (
> +                               HiiConfigRouting,
> +                               Configuration,
> +                               (UINT8 *)VarStoreConfig,
> +                               &BufferSize,
> +                               Progress
> +                               );
> +
> +  return Status;
> +}
> +
> +/**
> +  This function processes the results of changes in configuration.
> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +  @param  Action                 Specifies the type of action taken by the browser.
> +  @param  QuestionId             A unique value which is sent to the original
> +                                 exporting driver so that it can identify the type
> +                                 of data to expect.
> +  @param  Type                   The type of value for the question.
> +  @param  Value                  A pointer to the data being sent to the original
> +                                 exporting driver.
> +  @param  ActionRequest          On return, points to the action requested by the
> +                                 callback function.
> +  @retval EFI_SUCCESS            The callback successfully handled the action.
> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
> +                                 callback.
> +**/
> +EFI_STATUS
> +EFIAPI
> +DriverCallback (
> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> +  IN       EFI_BROWSER_ACTION             Action,
> +  IN       EFI_QUESTION_ID                QuestionId,
> +  IN       UINT8                          Type,
> +  IN       EFI_IFR_TYPE_VALUE             *Value,
> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
> +  )
> +{
> +  EFI_STATUS   Status;
> +  PRIVATE_DATA *PrivateData;
> +
> +  if (((Value == NULL) &&
> +       (Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
> +       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
> +      (ActionRequest == NULL))
> +  {

{ on preceding line.

> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PrivateData = PRIVATE_DATA_FROM_THIS (This);
> +
> +  switch (Action) {
> +  case EFI_BROWSER_ACTION_CHANGING:
> +    if ((QuestionId >= DEVICE_KEY)
> +        & (QuestionId <= (DEVICE_KEY + MAX_DEVICE)))
> +    {

{ on preceding line.
More instances below - please fix throughout.

/
    Leif

> +      Status = UpdateDeviceForm (QuestionId - DEVICE_KEY, PrivateData);
> +      if (EFI_ERROR (Status)) {
> +        return Status;
> +      }
> +    }
> +    break;
> +
> +  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
> +  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
> +    if ((QuestionId >= MPS_ONE_OF_KEY)
> +        & (QuestionId <= (MPS_ONE_OF_KEY + MAX_DEVICE)))
> +    {
> +      Value->u8 = DEFAULT_MPS;
> +    }
> +
> +    if ((QuestionId >= MRR_ONE_OF_KEY)
> +        & (QuestionId <= (MRR_ONE_OF_KEY + MAX_DEVICE)))
> +    {
> +      Value->u8 = DEFAULT_MRR;
> +    }
> +    break;
> +
> +  case EFI_BROWSER_ACTION_SUBMITTED:
> +    break;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +PcieDeviceConfigEntryPoint (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_HANDLE                      DriverHandle;
> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
> +  EFI_HII_HANDLE                  HiiHandle;
> +  EFI_STATUS                      Status;
> +  EFI_EVENT                       PlatformUiEntryEvent;
> +  EFI_EVENT                       FlushDeviceEvent;
> +  EFI_EVENT                       PciProtocolNotifyEvent;
> +  PRIVATE_DATA                    *PrivateData;
> +  UINTN                           BufferSize;
> +
> +  DriverHandle = NULL;
> +  PrivateData = AllocateZeroPool (sizeof (*PrivateData));
> +  if (PrivateData == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  PrivateData->Signature = PRIVATE_DATA_SIGNATURE;
> +
> +  PrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
> +  PrivateData->ConfigAccess.RouteConfig = RouteConfig;
> +  PrivateData->ConfigAccess.Callback = DriverCallback;
> +
> +  //
> +  // Locate ConfigRouting protocol
> +  //
> +  Status = gBS->LocateProtocol (
> +                  &gEfiHiiConfigRoutingProtocolGuid,
> +                  NULL,
> +                  (VOID **)&HiiConfigRouting
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +  PrivateData->HiiConfigRouting = HiiConfigRouting;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &DriverHandle,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &mHiiVendorDevicePath,
> +                  &gEfiHiiConfigAccessProtocolGuid,
> +                  &PrivateData->ConfigAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +
> +  PrivateData->DriverHandle = DriverHandle;
> +
> +  //
> +  // Publish our HII data
> +  //
> +  HiiHandle = HiiAddPackages (
> +                &gPcieDeviceConfigFormSetGuid,
> +                DriverHandle,
> +                PcieDeviceConfigDxeStrings,
> +                VfrBin,
> +                NULL
> +                );
> +  if (HiiHandle == NULL) {
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +  PrivateData->HiiHandle = HiiHandle;
> +
> +  // Event to fixup screen
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  UpdateMainForm,
> +                  (VOID *)PrivateData,
> +                  &gPlatformManagerEntryEventGuid,
> +                  &PlatformUiEntryEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +
> +  // Event to collect PciIo
> +  PciProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
> +                             &gEfiPciIoProtocolGuid,
> +                             TPL_CALLBACK,
> +                             OnPciIoProtocolNotify,
> +                             (VOID *)PrivateData,
> +                             &mPciProtocolNotifyRegistration
> +                             );
> +  ASSERT (PciProtocolNotifyEvent != NULL);
> +
> +  // Event to flush device data
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,
> +                  TPL_CALLBACK,
> +                  FlushDeviceData,
> +                  (VOID *)PrivateData,
> +                  &gEfiEventReadyToBootGuid,
> +                  &FlushDeviceEvent
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +
> +  // Verify varstore
> +  BufferSize = sizeof (VARSTORE_DATA);
> +  Status = gRT->GetVariable (
> +                  mVariableName,
> +                  &gPcieDeviceConfigFormSetGuid,
> +                  NULL,
> +                  &BufferSize,
> +                  &PrivateData->LastVarStoreConfig
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Last config is not found\n", __FUNCTION__));
> +  }
> +
> +  return EFI_SUCCESS;
> +
> +Exit:
> +  FreePool (PrivateData);
> +  return Status;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
> new file mode 100644
> index 000000000000..b4e918e2b786
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieHelper.c
> @@ -0,0 +1,191 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Protocol/PciIo.h>
> +
> +#include "PcieDeviceConfigDxe.h"
> +#include "PcieHelper.h"
> +
> +EFI_STATUS
> +FindCapabilityPtr (
> +  IN  EFI_PCI_IO_PROTOCOL *PciIo,
> +  IN  UINT8               CapabilityId,
> +  OUT UINT8               *CapabilityPtr
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT8      NextPtr;
> +  UINT16     TmpValue;
> +
> +  ASSERT (PciIo != NULL);
> +
> +  //
> +  // Get pointer to first PCI Capability header
> +  //
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint8,
> +                        PCI_CAPBILITY_POINTER_OFFSET,
> +                        1,
> +                        &NextPtr
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +
> +  while (TRUE) {
> +    if (NextPtr == 0x00) {
> +      Status = EFI_NOT_FOUND;
> +      goto Exit;
> +    }
> +
> +    //
> +    // Retrieve PCI Capability header
> +    //
> +    Status = PciIo->Pci.Read (
> +                          PciIo,
> +                          EfiPciIoWidthUint16,
> +                          NextPtr,
> +                          1,
> +                          &TmpValue
> +                          );
> +    if (EFI_ERROR (Status)) {
> +      goto Exit;
> +    }
> +
> +    if ((TmpValue & 0xFF) == CapabilityId) {
> +      *CapabilityPtr = NextPtr;
> +      Status = EFI_SUCCESS;
> +      goto Exit;
> +    }
> +
> +    NextPtr = (TmpValue >> 8) & 0xFF;
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +WriteMps (
> +  PCIE_NODE *Node,
> +  UINT8     Value
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  EFI_STATUS          Status;
> +  UINT16              TmpValue;
> +  UINT8               PcieCapOffset;
> +
> +  if (Node == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PciIo = Node->PciIo;
> +  PcieCapOffset = Node->PcieCapOffset;
> +
> +  // Get current device control reg
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint16,
> +                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
> +                        1,
> +                        &TmpValue
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  // Update value and write to device
> +  TmpValue = (TmpValue & ~(PCIE_MAX_PAYLOAD_MASK << PCIE_CONTROL_MAX_PAYLOAD_OFF))
> +             | Value << PCIE_CONTROL_MAX_PAYLOAD_OFF;
> +  Status = PciIo->Pci.Write (
> +                        PciIo,
> +                        EfiPciIoWidthUint16,
> +                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
> +                        1,
> +                        &TmpValue
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "%a: Write MPS %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n",
> +    __FUNCTION__,
> +    Value,
> +    Node->Seg,
> +    Node->Bus,
> +    Node->Dev,
> +    Node->Fun
> +    ));
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +WriteMrr (
> +  PCIE_NODE *Node,
> +  UINT8     Value
> +  )
> +{
> +  EFI_PCI_IO_PROTOCOL *PciIo;
> +  EFI_STATUS          Status;
> +  UINT16              TmpValue;
> +  UINT8               PcieCapOffset;
> +
> +  if (Node == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PciIo = Node->PciIo;
> +  PcieCapOffset = Node->PcieCapOffset;
> +
> +  // Get current device control reg
> +  Status = PciIo->Pci.Read (
> +                        PciIo,
> +                        EfiPciIoWidthUint16,
> +                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
> +                        1,
> +                        &TmpValue
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  // Update value and write to device
> +  TmpValue = (TmpValue & ~(PCIE_MAX_READ_REQUEST_MASK << PCIE_CONTROL_READ_REQUEST_OFF))
> +             | Value << PCIE_CONTROL_READ_REQUEST_OFF;
> +  Status = PciIo->Pci.Write (
> +                        PciIo,
> +                        EfiPciIoWidthUint16,
> +                        PcieCapOffset + PCI_EXPRESS_CAPABILITY_DEVICE_CONTROL_REG,
> +                        1,
> +                        &TmpValue
> +                        );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +  DEBUG ((
> +    DEBUG_INFO,
> +    "%a: Write MRR %d to device 0x%04x:0x%02x:0x%02x:0x%02x\n",
> +    __FUNCTION__,
> +    Value,
> +    Node->Seg,
> +    Node->Bus,
> +    Node->Dev,
> +    Node->Fun
> +    ));
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
> new file mode 100644
> index 000000000000..f07b70c746a6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.uni
> @@ -0,0 +1,24 @@
> +//
> +// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#langdef   en-US "English"    // English
> +
> +#string STR_PCIE_DEVICE_CONFIG_FORM #language en-US "PCIE Device Configuration"
> +#string STR_PCIE_DEVICE_CONFIG_HELP #language en-US "PCIE Device Configuration"
> +
> +#string STR_DEVICE_FORM             #language en-US "PCIE Device Form"
> +#string STR_DEVICE_GOTO_HELP        #language en-US "PCIE Device Configuration"
> +
> +#string STR_PCIE_MPS            #language en-US "Max Payload Size"
> +#string STR_PCIE_MPS_HELP       #language en-US "Max Payload Size"
> +#string STR_PCIE_MRR            #language en-US "Max Read Request Size"
> +#string STR_PCIE_MRR_HELP       #language en-US "Max Read Request Size"
> +#string STR_128                 #language en-US "128 bytes"
> +#string STR_256                 #language en-US "256 bytes"
> +#string STR_512                 #language en-US "512 bytes"
> +#string STR_1024                #language en-US "1024 bytes"
> +#string STR_2048                #language en-US "2048 bytes"
> +#string STR_4096                #language en-US "4096 bytes"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
@ 2021-06-07 23:46   ` Leif Lindholm
  2021-06-15 16:52     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:46 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:21 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> Due to recent changes in EDK2, system without a valid boot options list
> in NVRAM will enter Platform Recovery mode. As ReadyToBoot event is not
> triggered in this mode, services like ACPI and PCIe won't be able to do
> some finalization settings and cause OS fails to boot.
> This change is to prevent the issue by recovery boot options list each
> time NVRAM is cleared.

Urgh.
Ultimately this is a bug in EDK2. And it should be fixed in edk2:
https://bugzilla.tianocore.org/show_bug.cgi?id=2831

But could you let me know which specific edk2 change broke this for
you, since it is not obvious to me?

/
    Leif

> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Platform/Ampere/JadePkg/Jade.dsc                                                  |  5 ++
>  Platform/Ampere/JadePkg/Jade.fdf                                                  |  5 ++
>  Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf | 39 +++++++++++++
>  Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c   | 58 ++++++++++++++++++++
>  4 files changed, 107 insertions(+)
> 
> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
> index 9d787113e3b5..023f2e898d7f 100755
> --- a/Platform/Ampere/JadePkg/Jade.dsc
> +++ b/Platform/Ampere/JadePkg/Jade.dsc
> @@ -185,3 +185,8 @@ [Components.common]
>    Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
> +
> +  #
> +  # Misc
> +  #
> +  Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index b0c2894d00f8..edbead046572 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -361,4 +361,9 @@ [FV.FvMain]
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>    INF Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>  
> +  #
> +  # Misc
> +  #
> +  INF Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
> +
>  !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
> new file mode 100644
> index 000000000000..624332339beb
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
> @@ -0,0 +1,39 @@
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = BootOptionsRecoveryDxe
> +  FILE_GUID                      = FDCDDC91-4F9E-400C-9BB4-1FE4BE9565B3
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = BootOptionsRecoveryDxeEntry
> +
> +[Sources]
> +  BootOptionsRecoveryDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  DebugLib
> +  PcdLib
> +  PrintLib
> +  UefiBootManagerLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Guids]
> +  gEfiEndOfDxeEventGroupGuid
> +
> +[Pcd]
> +  gAmpereTokenSpaceGuid.PcdNvramErased
> +
> +[Depex]
> +  gEfiFaultTolerantWriteProtocolGuid
> diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
> new file mode 100644
> index 000000000000..cd9637ec704e
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
> @@ -0,0 +1,58 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/DebugLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +
> +VOID
> +EFIAPI
> +RecoveryCallback (
> +  IN EFI_EVENT Event,
> +  IN VOID      *Context
> +  )
> +{
> +  DEBUG ((DEBUG_INFO, "%a: Do recover boot options\n", __FUNCTION__));
> +
> +  EfiBootManagerConnectAll ();
> +  EfiBootManagerRefreshAllBootOption ();
> +
> +  gBS->CloseEvent (Event);
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +BootOptionsRecoveryDxeEntry (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_EVENT  EndOfDxeEvent;
> +
> +  DEBUG ((DEBUG_INFO, "%a: NVRAM Clear is %d\n", PcdGetBool (PcdNvramErased), __FUNCTION__));
> +
> +  if (PcdGetBool (PcdNvramErased)) {
> +    DEBUG ((DEBUG_INFO, "%a: Register event to recover boot options\n", __FUNCTION__));
> +    Status = gBS->CreateEventEx (
> +                    EVT_NOTIFY_SIGNAL,
> +                    TPL_CALLBACK,
> +                    RecoveryCallback,
> +                    NULL,
> +                    &gEfiEndOfDxeEventGroupGuid,
> +                    &EndOfDxeEvent
> +                    );
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +
> +  return Status;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
@ 2021-06-07 23:50   ` Leif Lindholm
  2021-06-09 15:21     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:50 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:22 +0700, Nhi Pham wrote:
> The PlatformBootManagerLib library derived from
> ArmPkg/Library/PlatformBootManagerLib.
> 
> This implementation registers only a common GUID for LinuxBoot Payload
> ("D834A5AD-459C-4AED-B0D0-8CBCB28838D7") as a active boot option. This
> allows BDS to jump to the LinuxBoot Shell immediately without entering
> the UiApp Setup Screen or UEFI Shell.

This driver does not look spectacularly platform specific to me,
although the GUID handling could posibly do with some additional
engineering if this was to be shared with others.

Would you consider submitting it for ArmPkg for now? (Unless it's
something for MinPlatformPkg?)

/
    Leif

> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf |  54 ++++++
>  Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c               | 173 ++++++++++++++++++++
>  2 files changed, 227 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
> new file mode 100644
> index 000000000000..cb4ade210117
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
> @@ -0,0 +1,54 @@
> +## @file
> +#  Implementation for PlatformBootManagerLib library class interfaces.
> +#
> +#  Copyright (C) 2015-2016, Red Hat, Inc.
> +#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
> +#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x00010005
> +  BASE_NAME                      = LinuxBootBootManagerLib
> +  FILE_GUID                      = 1FA91547-DB23-4F6A-8AF8-3B9782A7F917
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the build tools.
> +#
> +#  VALID_ARCHITECTURES           = ARM AARCH64
> +#
> +
> +[Sources]
> +  LinuxBootBm.c
> +
> +[Packages]
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  ShellPkg/ShellPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  MemoryAllocationLib
> +  PrintLib
> +  UefiBootManagerLib
> +  UefiBootServicesTableLib
> +  UefiLib
> +  UefiRuntimeServicesTableLib
> +
> +[Pcd]
> +
> +[Guids]
> +  gEfiEndOfDxeEventGroupGuid
> +  gUefiShellFileGuid
> +
> +[Protocols]
> +  gEfiLoadedImageProtocolGuid
> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
> new file mode 100644
> index 000000000000..2d0f087477d6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
> @@ -0,0 +1,173 @@
> +/** @file
> +  Implementation for PlatformBootManagerLib library class interfaces.
> +
> +  Copyright (C) 2015-2016, Red Hat, Inc.
> +  Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.<BR>
> +  Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
> +  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Guid/EventGroup.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootManagerLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Protocol/LoadedImage.h>
> +#include <Protocol/PlatformBootManager.h>
> +
> +// This GUID must match the FILE_GUID in the LinuxBootPkg/LinuxBoot.inf file.
> +// GUID: D834A5AD-459C-4AED-B0D0-8CBCB28838D7
> +EFI_GUID mLinuxBootFileGuid = { 0xD834A5AD, 0x459C, 0x4AED, { 0xB0, 0xD0, 0x8C, 0xBC, 0xB2, 0x88, 0x38, 0xD7 } };
> +
> +STATIC
> +VOID
> +RegisterFvBootOption (
> +  CONST EFI_GUID *FileGuid,
> +  CHAR16         *Description,
> +  UINT32         Attributes
> +  )
> +{
> +  EFI_STATUS                        Status;
> +  INTN                              OptionIndex;
> +  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
> +  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
> +  UINTN                             BootOptionCount;
> +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
> +  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
> +  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
> +
> +  Status = gBS->HandleProtocol (
> +                  gImageHandle,
> +                  &gEfiLoadedImageProtocolGuid,
> +                  (VOID **)&LoadedImage
> +                  );
> +  ASSERT_EFI_ERROR (Status);
> +
> +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
> +  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
> +  ASSERT (DevicePath != NULL);
> +  DevicePath = AppendDevicePathNode (
> +                 DevicePath,
> +                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
> +                 );
> +  ASSERT (DevicePath != NULL);
> +
> +  Status = EfiBootManagerInitializeLoadOption (
> +             &NewOption,
> +             LoadOptionNumberUnassigned,
> +             LoadOptionTypeBoot,
> +             Attributes,
> +             Description,
> +             DevicePath,
> +             NULL,
> +             0
> +             );
> +  ASSERT_EFI_ERROR (Status);
> +  FreePool (DevicePath);
> +
> +  BootOptions = EfiBootManagerGetLoadOptions (
> +                  &BootOptionCount,
> +                  LoadOptionTypeBoot
> +                  );
> +
> +  OptionIndex = EfiBootManagerFindLoadOption (
> +                  &NewOption,
> +                  BootOptions,
> +                  BootOptionCount
> +                  );
> +
> +  if (OptionIndex == -1) {
> +    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
> +    ASSERT_EFI_ERROR (Status);
> +  }
> +  EfiBootManagerFreeLoadOption (&NewOption);
> +  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
> +}
> +
> +/**
> +  Do the platform specific action before the console is connected.
> +
> +  Such as:
> +    Update console variable;
> +    Register new Driver#### or Boot####;
> +    Signal ReadyToLock event.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerBeforeConsole (
> +  VOID
> +  )
> +{
> +  //
> +  // Signal EndOfDxe PI Event
> +  //
> +  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
> +}
> +
> +/**
> +  Do the platform specific action after the console is connected.
> +
> +  Such as:
> +    Dynamically switch output mode;
> +    Signal console ready platform customized event;
> +    Run diagnostics like memory testing;
> +    Connect certain devices;
> +    Dispatch additional option roms.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerAfterConsole (
> +  VOID
> +  )
> +{
> +  //
> +  // Register LinuxBoot
> +  //
> +  RegisterFvBootOption (
> +    &mLinuxBootFileGuid,
> +    L"LinuxBoot",
> +    LOAD_OPTION_ACTIVE
> +    );
> +}
> +
> +/**
> +  This function is called each second during the boot manager waits the
> +  timeout.
> +
> +  @param TimeoutRemain  The remaining timeout.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerWaitCallback (
> +  UINT16 TimeoutRemain
> +  )
> +{
> +  return;
> +}
> +
> +/**
> +  The function is called when no boot option could be launched,
> +  including platform recovery options and options pointing to applications
> +  built into firmware volumes.
> +
> +  If this function returns, BDS attempts to enter an infinite loop.
> +**/
> +VOID
> +EFIAPI
> +PlatformBootManagerUnableToBoot (
> +  VOID
> +  )
> +{
> +  return;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
@ 2021-06-07 23:51   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:51 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:23 +0700, Nhi Pham wrote:
> LinuxBoot is a firmware that replaces specific firmware functionality
> like the UEFI DXE phase with a Linux kernel and runtime. At the end of
> the DXE phase, UEFI will hand over the control to the LinuxBoot kernel.
> 
> This package contains the LinuxBoot binary (flashkernel) which is built
> and added manually by following the instructions in the Readme.md
> ("Platform/Ampere/LinuxBootPkg/AArch64/Readme.md").
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> ---
>  Platform/Ampere/LinuxBootPkg/LinuxBoot.inf     | 17 ++++++++++++
>  Platform/Ampere/LinuxBootPkg/AArch64/Readme.md | 29 ++++++++++++++++++++
>  2 files changed, 46 insertions(+)
> 
> diff --git a/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf b/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
> new file mode 100644
> index 000000000000..5e8f6f83dfb2
> --- /dev/null
> +++ b/Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
> @@ -0,0 +1,17 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                   = 0x0001001B
> +  BASE_NAME                     = LinuxBoot
> +  FILE_GUID                     = D834A5AD-459C-4AED-B0D0-8CBCB28838D7
> +  MODULE_TYPE                   = UEFI_APPLICATION
> +  VERSION_STRING                = 1.0
> +
> +[Binaries.AArch64]
> +  PE32|AArch64/flashkernel|*
> diff --git a/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md b/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
> new file mode 100644
> index 000000000000..92c6c3165eac
> --- /dev/null
> +++ b/Platform/Ampere/LinuxBootPkg/AArch64/Readme.md
> @@ -0,0 +1,29 @@
> +# flashkernel
> +
> +The LinuxBoot image, named flashkernel, is required to build the final EDK2 image with LinuxBoot support.
> +The flashkernel image consists of [Linux](https://kernel.org) kernel and initramfs generated using [u-root](https://github.com/u-root/u-root).
> +
> +## Overview
> +
> +LinuxBoot is a firmware that replaces specific firmware functionality
> +like the UEFI DXE phase with a Linux kernel and runtime. It is built-in
> +UEFI image like an application as it will be executed at the end of DXE phase.
> +
> +The flashkernel is built completely from the [linuxboot/mainboards](https://github.com/linuxboot/mainboards) repository.
> +
> +## How to build
> +
> +1. Clone the `linuxboot/mainboards` repository:
> +
> +    ```Bash
> +    git clone https://github.com/linuxboot/mainboards.git
> +    ```
> +
> +2. Build with the following command:
> +
> +    ```Bash
> +    cd ampere/jade
> +    make fetch flashkernel
> +    ```
> +
> +Once the build is done, copy the flashkernel into the edk2-platform under the `Platform/Ampere/LinuxBootPkg/AArch64` directory.
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
@ 2021-06-07 23:58   ` Leif Lindholm
  2021-06-09 15:20     ` Nhi Pham
  0 siblings, 1 reply; 87+ messages in thread
From: Leif Lindholm @ 2021-06-07 23:58 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:24 +0700, Nhi Pham wrote:
> Adds DSC and FDF files to support the LinuxBoot build. Some PEI/DXE
> drivers are not added into the target build as they are not required for
> booting to the LinuxBoot Shell.
> 
> Please note that we MUST have the LinuxBoot binary in the
> Platform/Ampere/LinuxBootPkg/AArch64 directory before compiling.

Hmm. So, this step feels a little bit weird to me.
I think a more common workflow would be to treat the LinuxBoot module
like an edk2-non-osi module.
I could go along with adding it like this for now, with an
understanding that we would need to figure out some better solution
medium-term.

/
    Leif

> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc | 550 ++++++++++++++++++++
>  Platform/Ampere/JadePkg/JadeLinuxBoot.dsc                     |  90 ++++
>  Platform/Ampere/JadePkg/JadeLinuxBoot.fdf                     | 201 +++++++
>  3 files changed, 841 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
> new file mode 100755
> index 000000000000..06b2bb928fe8
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
> @@ -0,0 +1,550 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
> +  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000
> +
> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
> +  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
> +
> +[BuildOptions]
> +  GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
> +
> +[LibraryClasses.common]
> +!if $(TARGET) == RELEASE
> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
> +!else
> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
> +!endif
> +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
> +
> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
> +  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
> +  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
> +  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
> +
> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
> +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
> +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
> +  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
> +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
> +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
> +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
> +
> +  #
> +  # Allow dynamic PCDs
> +  #
> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
> +
> +  #
> +  # ARM Architectural Libraries
> +  #
> +  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
> +  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
> +  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
> +  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
> +  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
> +  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
> +  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
> +  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
> +  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
> +  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
> +  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
> +  ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
> +  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
> +
> +  #
> +  # Ampere Altra specific Libraries
> +  #
> +  ArmPlatformLib|Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
> +  PlatformPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
> +  NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
> +  MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
> +  SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
> +  PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf
> +  PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
> +  AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
> +  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
> +  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
> +  MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
> +
> +  #
> +  # ARM PL011 UART Driver
> +  #
> +  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
> +  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
> +  PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
> +
> +  #
> +  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
> +  # in the debugger will show load and unload commands for symbols. You can cut and paste this
> +  # into the command window to load symbols. We should be able to use a script to do this, but
> +  # the version of RVD I have does not support scripts accessing system memory.
> +  #
> +  #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
> +  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
> +  #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
> +
> +  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
> +  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
> +
> +  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
> +
> +  #
> +  # BDS Libraries
> +  #
> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
> +  PlatformBootManagerLib|Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
> +
> +  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
> +  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
> +
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> +  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
> +
> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
> +
> +[LibraryClasses.common.SEC]
> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
> +
> +!ifdef $(EDK2_SKIP_PEICORE)
> +  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
> +  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
> +  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
> +  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
> +  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
> +!endif
> +
> +  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
> +
> +[LibraryClasses.common.PEI_CORE]
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
> +  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +
> +  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +
> +[LibraryClasses.common.PEIM]
> +  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
> +  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
> +  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
> +
> +[LibraryClasses.common.SEC, LibraryClasses.common.PEIM]
> +  MemoryInitPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
> +
> +[LibraryClasses.common.DXE_CORE]
> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> +  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
> +
> +[LibraryClasses.common.DXE_DRIVER]
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
> +
> +[LibraryClasses.common.UEFI_APPLICATION]
> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +
> +[LibraryClasses.common.UEFI_DRIVER]
> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +
> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
> +  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
> +!if $(TARGET) != RELEASE
> +  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
> +!endif
> +  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
> +
> +  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
> +  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
> +
> +[LibraryClasses.ARM,LibraryClasses.AARCH64]
> +  #
> +  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
> +  # This library provides the instrinsic functions generate by a given compiler.
> +  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
> +  #
> +  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
> +
> +  #
> +  # Add support for GCC stack protector
> +  #
> +  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
> +
> +################################################################################
> +#
> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
> +#
> +################################################################################
> +
> +[PcdsFeatureFlag.common]
> +  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
> +  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
> +  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
> +
> +  #
> +  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
> +  #
> +  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
> +
> +  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
> +
> +  #
> +  # If TRUE, Graphics Output Protocol will be installed on virtual handle
> +  # created by ConsplitterDxe. It could be set FALSE to save size.
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
> +
> +[PcdsFixedAtBuild.common]
> +!ifdef $(FIRMWARE_VER)
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
> +!endif
> +
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
> +  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
> +  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
> +  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
> +
> +  # DEBUG_ASSERT_ENABLED       0x01
> +  # DEBUG_PRINT_ENABLED        0x02
> +  # DEBUG_CODE_ENABLED         0x04
> +  # CLEAR_MEMORY_ENABLED       0x08
> +  # ASSERT_BREAKPOINT_ENABLED  0x10
> +  # ASSERT_DEADLOOP_ENABLED    0x20
> +!if $(TARGET) == RELEASE
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
> +!else
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2A
> +!endif
> +
> +  #
> +  # SBSA Watchdog Count
> +  #
> +!ifndef DISABLE_SBSA_WATCHDOG
> +  gArmPlatformTokenSpaceGuid.PcdWatchdogCount|1
> +!endif
> +
> +  #  DEBUG_INIT      0x00000001  // Initialization
> +  #  DEBUG_WARN      0x00000002  // Warnings
> +  #  DEBUG_LOAD      0x00000004  // Load events
> +  #  DEBUG_FS        0x00000008  // EFI File system
> +  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
> +  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
> +  #  DEBUG_INFO      0x00000040  // Informational debug messages
> +  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
> +  #  DEBUG_VARIABLE  0x00000100  // Variable
> +  #  DEBUG_BM        0x00000400  // Boot Manager
> +  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
> +  #  DEBUG_NET       0x00004000  // SNP Driver
> +  #  DEBUG_UNDI      0x00010000  // UNDI Driver
> +  #  DEBUG_LOADFILE  0x00020000  // LoadFile
> +  #  DEBUG_EVENT     0x00080000  // Event messages
> +  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
> +  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
> +  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
> +  #                              // significantly impact boot performance
> +  #  DEBUG_ERROR     0x80000000  // Error
> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
> +
> +  #
> +  # Optional feature to help prevent EFI memory map fragments
> +  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
> +  # Values are in EFI Pages (4K). DXE Core will make sure that
> +  # at least this much of each type of memory can be allocated
> +  # from a single memory range. This way you only end up with
> +  # maximum of two fragements for each type in the memory map
> +  # (the memory used, and the free memory that was prereserved
> +  # but not used).
> +  #
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
> +
> +  gArmTokenSpaceGuid.PcdVFPEnabled|1
> +
> +  gArmTokenSpaceGuid.PcdArmPrimaryCore|0x0
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
> +
> +  #
> +  # Stacks for MPCores in Normal World
> +  #
> +  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x91100000
> +  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x20000
> +  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000
> +
> +  #
> +  # System Memory Base
> +  #
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x90000000
> +
> +  #
> +  # UEFI region size
> +  #
> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000
> +
> +  #
> +  # Ampere Altra Core-Cluster profile
> +  #
> +  gArmPlatformTokenSpaceGuid.PcdCoreCount|80
> +  gArmPlatformTokenSpaceGuid.PcdClusterCount|40
> +
> +  #
> +  # PL011 - Serial Terminal
> +  # Ampere Altra UART0
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x100002600000
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|32
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
> +
> +  gArmPlatformTokenSpaceGuid.PL011UartClkInHz|1843200
> +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt|0x62
> +
> +  #
> +  # PL011 - Serial Debug UART
> +  # Ampere Altra UART2
> +  #
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|0x100002620000
> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|115200
> +
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
> +
> +  #
> +  # ARM SBSA Watchdog
> +  #
> +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x1000027c0000
> +  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x1000027d0000
> +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|92
> +
> +  #
> +  # ARM Generic Interrupt Controller
> +  #
> +  gArmTokenSpaceGuid.PcdGicDistributorBase|0x100100000000
> +  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x100100140000
> +
> +  #
> +  # ARM Architectural Timer Frequency
> +  #
> +  # Set it to 0 so that the code will read frequence from register
> +  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
> +  gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
> +
> +  #
> +  # use the TTY terminal type
> +  #
> +  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
> +
> +  #
> +  # GUID of the UI app
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
> +
> +  #
> +  # ACPI table
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
> +
> +  #
> +  # Enable strict image permissions for all images. (This applies
> +  # only to images that were built with >= 4 KB section alignment.)
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
> +
> +  #
> +  # Enable NX memory protection for all non-code regions, including OEM and OS
> +  # reserved ones, with the exception of LoaderData regions, of which OS loaders
> +  # (i.e., GRUB) may assume that its contents are executable.
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1
> +
> +  #
> +  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
> +  #
> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
> +
> +  #
> +  # MmCommunication
> +  #
> +  gArmTokenSpaceGuid.PcdMmBufferBase|0x88300000
> +  gArmTokenSpaceGuid.PcdMmBufferSize|0x100000
> +
> +[PcdsDynamicHii.common.DEFAULT]
> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
> +
> +[PcdsDynamicDefault.common]
> +  #
> +  # Fist DRAM Memory region under 4GB address range
> +  #
> +  gArmTokenSpaceGuid.PcdSystemMemorySize|0x70000000
> +
> +################################################################################
> +#
> +# Component Section - list of all EDK II Component Entries defined by this Platform
> +#
> +################################################################################
> +
> +[Components.common]
> +  #
> +  # PEI Phase modules
> +  #
> +  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
> +  MdeModulePkg/Core/Pei/PeiMain.inf
> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
> +  ArmPkg/Drivers/CpuPei/CpuPei.inf
> +  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
> +  }
> +
> +  #
> +  # DXE Phase modules
> +  #
> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
> +    <LibraryClasses>
> +      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
> +  }
> +
> +  #
> +  # PCD
> +  #
> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
> +    <LibraryClasses>
> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> +  }
> +
> +  #
> +  # Architectural Protocols
> +  #
> +  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
> +  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
> +  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
> +
> +  #
> +  # Environment Variables Protocol
> +  #
> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
> +    <PcdsFixedAtBuild>
> +      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
> +    <LibraryClasses>
> +      AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
> +      TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
> +      VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
> +  }
> +
> +  #
> +  # Timer
> +  #
> +  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
> +
> +  #
> +  # ARM GIC Dxe
> +  #
> +  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
> +
> +  #
> +  # Console
> +  #
> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> +  #
> +  # Hii Database
> +  #
> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +
> +  #
> +  # PCIe Support
> +  #
> +  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
> +  #
> +  # Bds
> +  #
> +  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
> new file mode 100755
> index 000000000000..d3c7328fb7ed
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
> @@ -0,0 +1,90 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# Defines Section - statements that will be processed to create a Makefile.
> +#
> +################################################################################
> +[Defines]
> +  PLATFORM_NAME                  = Jade
> +  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
> +  PLATFORM_VERSION               = 0.1
> +  DSC_SPECIFICATION              = 0x0001001B
> +  OUTPUT_DIRECTORY               = Build/Jade
> +  SUPPORTED_ARCHITECTURES        = AARCH64
> +  BUILD_TARGETS                  = DEBUG|RELEASE
> +  SKUID_IDENTIFIER               = DEFAULT
> +  FLASH_DEFINITION               = Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
> +
> +  #
> +  # Defines for default states.  These can be changed on the command line.
> +  # -D FLAG=VALUE
> +  #
> +  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
> +  DEFINE FIRMWARE_VER            = 0.01.001
> +  DEFINE EDK2_SKIP_PEICORE       = TRUE
> +
> +# Include default Ampere Platform DSC file
> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
> +
> +#
> +# Specific Platform Library
> +#
> +[LibraryClasses.common]
> +  #
> +  # RTC Library: Common RTC
> +  #
> +  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
> +
> +  #
> +  # Library for FailSafe support
> +  #
> +  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
> +
> +  #
> +  # ACPI Libraries
> +  #
> +  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
> +  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
> +  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
> +
> +  #
> +  # Pcie Board
> +  #
> +  PcieBoardLib|Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
> +
> +[PcdsDynamicDefault.common.DEFAULT]
> +  # SMBIOS Type 0 - BIOS Information
> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
> +
> +#
> +# Specific Platform Component
> +#
> +[Components.common]
> +
> +  #
> +  # ACPI
> +  #
> +  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> +  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> +
> +  #
> +  # SMBIOS
> +  #
> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> +  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> +
> +  #
> +  # FailSafeDxe added to prevent watchdog from resetting the system
> +  #
> +  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
> new file mode 100755
> index 000000000000..aa5817ec6f4a
> --- /dev/null
> +++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
> @@ -0,0 +1,201 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +################################################################################
> +#
> +# FD Section
> +# The [FD] Section is made up of the definition statements and a
> +# description of what goes into  the Flash Device Image.  Each FD section
> +# defines one flash "device" image.  A flash device image may be one of
> +# the following: Removable media bootable image (like a boot floppy
> +# image,) an Option ROM image (that would be "flashed" into an add-in
> +# card,) a System "Flash"  image (that would be burned into a system's
> +# flash) or an Update ("Capsule") image that will be used to update and
> +# existing system flash.
> +#
> +################################################################################
> +
> +[FD.BL33_JADE_UEFI]
> +BaseAddress   = 0x92000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
> +Size          = 0x00AC0000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
> +ErasePolarity = 1
> +
> +# This one is tricky, it must be: BlockSize * NumBlocks = Size
> +BlockSize     = 0x10000
> +NumBlocks     = 0xAC
> +
> +################################################################################
> +#
> +# Following are lists of FD Region layout which correspond to the locations of different
> +# images within the flash device.
> +#
> +# Regions must be defined in ascending order and may not overlap.
> +#
> +# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
> +# the pipe "|" character, followed by the size of the region, also in hex with the leading
> +# "0x" characters. Like:
> +# Offset|Size
> +# PcdOffsetCName|PcdSizeCName
> +# RegionType <FV, DATA, or FILE>
> +#
> +################################################################################
> +
> +0x00000000|0x00AC0000
> +gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
> +FV = FVMAIN_COMPACT
> +
> +################################################################################
> +#
> +# FV Section
> +#
> +# [FV] section is used to define what components or modules are placed within a flash
> +# device file.  This section also defines order the components and modules are positioned
> +# within the image.  The [FV] section consists of define statements, set statements and
> +# module statements.
> +#
> +################################################################################
> +
> +[FV.FvMain]
> +BlockSize          = 0x10000
> +NumBlocks          = 0         # This FV gets compressed so make it just big enough
> +FvAlignment        = 16        # FV alignment and FV attributes setting.
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +FvNameGuid         = 5C60F367-A505-419A-859E-2A4FF6CA6FE5
> +
> +APRIORI DXE {
> +  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +}
> +
> +  INF MdeModulePkg/Core/Dxe/DxeMain.inf
> +  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
> +
> +  #
> +  # PI DXE Drivers producing Architectural Protocols (EFI Services)
> +  #
> +  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
> +  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
> +  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
> +  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
> +  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
> +  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
> +  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
> +  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
> +  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
> +
> +  #
> +  # Environment Variables Protocol
> +  #
> +  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
> +
> +  #
> +  # Multiple Console IO support
> +  #
> +  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
> +  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
> +
> +  #
> +  # Timer
> +  #
> +  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
> +
> +  #
> +  # ARM GIC Dxe
> +  #
> +  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
> +
> +  #
> +  # PCIe Support
> +  #
> +  INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> +
> +  #
> +  # Linuxboot in Flash Support
> +  #
> +  INF Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
> +
> +  #
> +  # Bds
> +  #
> +  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> +
> +  #
> +  # Driver to handle HW Watchdog
> +  #
> +  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
> +
> +  #
> +  # ACPI
> +  #
> +  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
> +  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
> +  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
> +
> +  #
> +  # SMBIOS
> +  #
> +  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
> +
> +[FV.FVMAIN_COMPACT]
> +FvAlignment        = 16
> +ERASE_POLARITY     = 1
> +MEMORY_MAPPED      = TRUE
> +STICKY_WRITE       = TRUE
> +LOCK_CAP           = TRUE
> +LOCK_STATUS        = TRUE
> +WRITE_DISABLED_CAP = TRUE
> +WRITE_ENABLED_CAP  = TRUE
> +WRITE_STATUS       = TRUE
> +WRITE_LOCK_CAP     = TRUE
> +WRITE_LOCK_STATUS  = TRUE
> +READ_DISABLED_CAP  = TRUE
> +READ_ENABLED_CAP   = TRUE
> +READ_STATUS        = TRUE
> +READ_LOCK_CAP      = TRUE
> +READ_LOCK_STATUS   = TRUE
> +
> +APRIORI PEI {
> +  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +}
> +
> +  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
> +  INF MdeModulePkg/Core/Pei/PeiMain.inf
> +  INF UefiCpuPkg/CpuIoPei/CpuIoPei.inf
> +  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
> +  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
> +  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
> +  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
> +
> +  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
> +
> +  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
> +    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
> +      SECTION FV_IMAGE = FVMAIN
> +    }
> +  }
> +
> +!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
@ 2021-06-08 11:13   ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-08 11:13 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, May 26, 2021 at 17:07:11 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> This change is to produce RNG protocol which is required by several
> modules.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc         |   5 +
>  Platform/Ampere/JadePkg/Jade.fdf                             |   5 +
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf      |  43 +++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c        | 164 ++++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni      |  10 ++
>  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni |   9 ++
>  6 files changed, 236 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> index 33f5fe7af544..930bbb5d385b 100755
> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
> @@ -682,6 +682,11 @@ [Components.common]
>    MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
>    Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>  
> +  #
> +  # Random Number Generator Support
> +  #
> +  Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
> +
>    #
>    # Bds
>    #
> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
> index 6820a197568b..ef24e6f1f8e0 100755
> --- a/Platform/Ampere/JadePkg/Jade.fdf
> +++ b/Platform/Ampere/JadePkg/Jade.fdf
> @@ -304,6 +304,11 @@ [FV.FvMain]
>    #
>    INF Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
>  
> +  #
> +  # Random Number Generator Support
> +  #
> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
> +
>    #
>    # UEFI application (Shell Embedded Boot Loader)
>    #
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
> new file mode 100644
> index 000000000000..d3d2c20436a0
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.inf
> @@ -0,0 +1,43 @@
> +## @file
> +#
> +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = RngDxe
> +  FILE_GUID                      = 4FCC006E-C740-4027-BC97-787907C8D286
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = RngDriverEntry
> +  MODULE_UNI_FILE                = RngDxe.uni
> +
> +[Sources.common]
> +  RngDxe.c
> +
> +[Packages]
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +
> +[LibraryClasses]
> +  BaseLib
> +  DebugLib
> +  TrngLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Guids]
> +  gEfiRngAlgorithmRaw                 ## SOMETIMES_PRODUCES    ## GUID        # Unique ID of the algorithm for RNG
> +
> +[Protocols]
> +  gEfiRngProtocolGuid                ## PRODUCES
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> +  RngDxeExtra.uni
> +
> +[Depex]
> +  TRUE
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
> new file mode 100644
> index 000000000000..bb8140cfeb2f
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.c
> @@ -0,0 +1,164 @@
> +/** @file
> +
> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Uefi.h>
> +
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/TrngLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Protocol/Rng.h>
> +
> +/**
> +  Returns information about the random number generation implementation.
> +
> +  @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL instance.
> +  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of RNGAlgorithmList.
> +                                      On output with a return code of EFI_SUCCESS, the size
> +                                      in bytes of the data returned in RNGAlgorithmList. On output
> +                                      with a return code of EFI_BUFFER_TOO_SMALL,
> +                                      the size of RNGAlgorithmList required to obtain the list.
> +  @param[out] RNGAlgorithmList        A caller-allocated memory buffer filled by the driver
> +                                      with one EFI_RNG_ALGORITHM element for each supported
> +                                      RNG algorithm. The list must not change across multiple
> +                                      calls to the same driver. The first algorithm in the list
> +                                      is the default algorithm for the driver.
> +
> +  @retval EFI_SUCCESS                 The RNG algorithm list was returned successfully.
> +  @retval EFI_INVALID_PARAMETER       One or more of the parameters are incorrect.
> +  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too small to hold the result.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetInfo (
> +  IN     EFI_RNG_PROTOCOL  *This,
> +  IN OUT UINTN             *RNGAlgorithmListSize,
> +  OUT    EFI_RNG_ALGORITHM *RNGAlgorithmList
> +  )
> +{
> +  if (This == NULL || RNGAlgorithmListSize == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
> +    *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
> +    return EFI_BUFFER_TOO_SMALL;
> +  }
> +
> +  if (RNGAlgorithmList == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
> +  CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Produces and returns an RNG value using either the default or specified RNG algorithm.
> +
> +  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL instance.
> +  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that identifies the RNG
> +                                      algorithm to use. May be NULL in which case the function will
> +                                      use its default RNG algorithm.
> +  @param[in]  RNGValueLength          The length in bytes of the memory buffer pointed to by
> +                                      RNGValue. The driver shall return exactly this numbers of bytes.
> +  @param[out] RNGValue                A caller-allocated memory buffer filled by the driver with the
> +                                      resulting RNG value.
> +
> +  @retval EFI_SUCCESS                 The RNG value was returned successfully.
> +  @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm is not supported by
> +                                      this driver.
> +  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due to a hardware or
> +                                      firmware error.
> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is zero.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngGetRNG (
> +  IN  EFI_RNG_PROTOCOL  *This,
> +  IN  EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
> +  IN  UINTN             RNGValueLength,
> +  OUT UINT8             *RNGValue
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // We only support the raw algorithm, so reject requests for anything else
> +  //
> +  if (RNGAlgorithm != NULL &&
> +      !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw))
> +  {

{ on preceding line.

With that:
Reviewed-by: Leif Lindholm <leif@nuviainc.com>

/
    Leif

> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  Status = GenerateRandomNumbers (RNGValue, RNGValueLength);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((
> +      DEBUG_ERROR,
> +      "%a:%d Failed to generate a random number. \n",
> +      __FUNCTION__,
> +      __LINE__
> +      ));
> +    return Status;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/*
> + * The Random Number Generator (RNG) protocol
> + */
> +EFI_RNG_PROTOCOL mRng = {
> +  RngGetInfo,
> +  RngGetRNG
> +};
> +
> +/**
> +  The user Entry Point for the Random Number Generator (RNG) driver.
> +
> +  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
> +  @param[in] SystemTable    A pointer to the EFI System Table.
> +
> +  @retval EFI_SUCCESS       The entry point is executed successfully.
> +  @retval EFI_NOT_SUPPORTED Platform does not support RNG.
> +  @retval Other             Some error occurs when executing this entry point.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RngDriverEntry (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  EFI_STATUS Status;
> +  EFI_HANDLE Handle;
> +
> +  //
> +  // Install UEFI RNG (Random Number Generator) Protocol
> +  //
> +  Handle = NULL;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &Handle,
> +                  &gEfiRngProtocolGuid,
> +                  &mRng,
> +                  NULL
> +                  );
> +
> +  return Status;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
> new file mode 100644
> index 000000000000..cd9dde97a236
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxe.uni
> @@ -0,0 +1,10 @@
> +//
> +// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +
> +#string STR_MODULE_ABSTRACT             #language en-US "Produces UEFI Random Number Generator protocol"
> +
> +#string STR_MODULE_DESCRIPTION          #language en-US "This module will produce UEFI Random Number Generator protocol."
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
> new file mode 100644
> index 000000000000..9a3696b25442
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/RngDxe/RngDxeExtra.uni
> @@ -0,0 +1,9 @@
> +//
> +// Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> +//
> +// SPDX-License-Identifier: BSD-2-Clause-Patent
> +//
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"Ampere UEFI Random Number Generator DXE"
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
@ 2021-06-08 22:26   ` Leif Lindholm
  2021-06-09  5:29   ` Ard Biesheuvel
  1 sibling, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-08 22:26 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Hi Nhi,

This is the only patch in the series I have not yet reviewed. And it's
because it's massive.
I can't usefully review whether this is correct or not, but I presume
it has been well tested.
I do have some concerns again with regards to driver-local constructs
being given names that identify them as part of an industry standard.

I have no further comments on this set, and look forward to v3.

Best Regards,

Leif

On Wed, May 26, 2021 at 17:07:08 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> 
> The roles of this driver:
> * Consume PcieCoreLib to initialize all enable PCIe controllers.
> * Produce neccessary protocols like RootBridgeIo an ResourceAllocation
>   which will be used later by PciBus.
> 
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> 
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> ---
>  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf |   56 +
>  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h      |  451 ++++++
>  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h    |  554 +++++++
>  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c      | 1419 ++++++++++++++++++
>  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c    | 1582 ++++++++++++++++++++
>  5 files changed, 4062 insertions(+)
> 
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> new file mode 100755
> index 000000000000..5b67d61926c7
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
> @@ -0,0 +1,56 @@
> +## @file
> +#
> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +#
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
> +#
> +##
> +
> +[Defines]
> +  INF_VERSION                    = 0x0001001B
> +  BASE_NAME                      = PciHostBridgeDxe
> +  FILE_GUID                      = D7ABBD62-2E03-11E8-B467-0ED5F89F718B
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = InitializePciHostBridge
> +
> +[Sources]
> +  PciHostBridge.c
> +  PciHostBridge.h
> +  PciRootBridgeIo.c
> +  PciRootBridgeIo.h
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
> +
> +[LibraryClasses]
> +  AcpiHelperLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  DevicePathLib
> +  DxeServicesTableLib
> +  IoLib
> +  MemoryAllocationLib
> +  PcdLib
> +  PcieCoreLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiPciHostBridgeResourceAllocationProtocolGuid
> +  gEfiPciRootBridgeIoProtocolGuid
> +  gEfiMetronomeArchProtocolGuid
> +  gEfiDevicePathProtocolGuid
> +
> +[FixedPcd]
> +  gArmTokenSpaceGuid.PcdSystemMemoryBase
> +
> +[Depex]
> +  gEfiMetronomeArchProtocolGuid
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
> new file mode 100644
> index 000000000000..ab62ebf3c3ef
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
> @@ -0,0 +1,451 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCI_HOST_BRIDGE_H_
> +#define PCI_HOST_BRIDGE_H_
> +
> +#include <IndustryStandard/Acpi.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/DxeServicesTableLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiLib.h>
> +#include <Protocol/DevicePath.h>
> +#include <Protocol/Metronome.h>
> +#include <Protocol/PciHostBridgeResourceAllocation.h>
> +#include <Protocol/PciRootBridgeIo.h>
> +
> +#undef PCIE_PLATFORM_DEBUG
> +#undef PCIE_MMIO_DEBUG
> +
> +#ifdef PCIE_PLATFORM_DEBUG
> +#define PCIE_DEBUG(arg...)       DEBUG((DEBUG_INFO,"PCIHostBridge: "));DEBUG((DEBUG_INFO,## arg))
> +#else
> +#define PCIE_DEBUG(arg...)
> +#endif
> +
> +#ifdef PCIE_MMIO_DEBUG
> +#define PCIE_MMIO_DEBUG(arg...)       DEBUG((DEBUG_INFO,"PCIRootBridge: "));DEBUG((DEBUG_INFO,## arg))
> +#else
> +#define PCIE_MMIO_DEBUG(arg...)
> +#endif
> +
> +#define PCIE_WARN(arg...)        DEBUG((DEBUG_WARN,"PCIHostBridge (WARN): "));DEBUG((DEBUG_WARN,## arg))
> +#define PCIE_ERR(arg...)         DEBUG((DEBUG_ERROR,"PCIHostBridge (ERROR): "));DEBUG((DEBUG_ERROR,## arg))
> +
> +#define PCI_HOST_BRIDGE_SIGNATURE  SIGNATURE_32('e', 'h', 's', 't')
> +#define PCI_ROOT_BRIDGE_SIGNATURE  SIGNATURE_32('e', '2', 'p', 'b')
> +
> +#define PCI_HOST_BRIDGE_FROM_THIS(a) \
> +  CR (a, PCI_HOST_BRIDGE_INSTANCE, ResAlloc, PCI_HOST_BRIDGE_SIGNATURE)
> +
> +#define PCI_RESOURCE_LESS         0xFFFFFFFFFFFFFFFEULL
> +
> +//
> +// Driver Instance Data Macros
> +//
> +#define ROOT_BRIDGE_FROM_THIS(a) \
> +  CR (a, PCI_ROOT_BRIDGE_INSTANCE, RbIo, PCI_ROOT_BRIDGE_SIGNATURE)
> +
> +#define ROOT_BRIDGE_FROM_LINK(a) \
> +  CR (a, PCI_ROOT_BRIDGE_INSTANCE, Link, PCI_ROOT_BRIDGE_SIGNATURE)
> +
> +//
> +// PCI Resource Type
> +//
> +typedef enum {
> +  TypeIo    = 0,
> +  TypeMem32,
> +  TypePMem32,
> +  TypeMem64,
> +  TypePMem64,
> +  TypeBus,
> +  TypeMax
> +} PCI_RESOURCE_TYPE;
> +
> +//
> +// Type of Resource status
> +//
> +typedef enum {
> +  ResNone = 0,
> +  ResSubmitted,
> +  ResAllocated,
> +  ResStatusMax
> +} RES_STATUS;
> +
> +//
> +// Struct of Resource Node
> +//
> +typedef struct {
> +  PCI_RESOURCE_TYPE  Type;
> +  UINT64             Base;
> +  UINT64             Length;
> +  UINT64             Alignment;
> +  RES_STATUS         Status;
> +} PCI_RES_NODE;
> +
> +//
> +// Type of PCIE operation
> +//
> +typedef enum {
> +  IoOperation,
> +  MemOperation,
> +  PciOperation
> +} OPERATION_TYPE;
> +
> +//
> +// Struct of Device Mapping
> +//
> +typedef struct {
> +  ACPI_HID_DEVICE_PATH     AcpiDevicePath;
> +  EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
> +} EFI_PCI_ROOT_BRIDGE_DEVICE_PATH;
> +
> +//
> +// Struct of Root Bridge Instance
> +//
> +typedef struct {
> +  UINT32                          Signature;
> +  LIST_ENTRY                      Link;
> +  EFI_HANDLE                      RootBridgeHandle;
> +  UINT64                          RootBridgeAttrib;
> +  VOID                            *ConfigBuffer;
> +  PCI_RES_NODE                    ResAllocNode[TypeMax];
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL RbIo;
> +  PCI_ROOT_BRIDGE                 RootBridge;
> +} PCI_ROOT_BRIDGE_INSTANCE;
> +
> +//
> +// Struct of Mapping Info
> +//
> +typedef struct {
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation;
> +  UINTN                                     NumberOfBytes;
> +  UINTN                                     NumberOfPages;
> +  EFI_PHYSICAL_ADDRESS                      HostAddress;
> +  EFI_PHYSICAL_ADDRESS                      MappedHostAddress;
> +} MAP_INFO;
> +
> +//
> +// Struct of Host Bridge Instance
> +//
> +typedef struct {
> +  UINTN                                            Signature;
> +  EFI_HANDLE                                       HostBridgeHandle;
> +  UINTN                                            RootBridgeNumber;
> +  LIST_ENTRY                                       Head;
> +  BOOLEAN                                          ResourceSubmited;
> +  BOOLEAN                                          CanRestarted;
> +  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL ResAlloc;
> +} PCI_HOST_BRIDGE_INSTANCE;
> +
> +/**
> +   These are the notifications from the PCI bus driver that it is about to enter a certain
> +   phase of the PCI enumeration process.
> +
> +   This member function can be used to notify the host bridge driver to perform specific actions,
> +   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
> +   Eight notification points are defined at this time. See belows:
> +   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
> +                                          structures. The PCI enumerator should issue this notification
> +                                          before starting a fresh enumeration process. Enumeration cannot
> +                                          be restarted after sending any other notification such as
> +                                          EfiPciHostBridgeBeginBusAllocation.
> +   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
> +                                          required here. This notification can be used to perform any
> +                                          chipset-specific programming.
> +   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
> +                                          specific action is required here. This notification can be used to
> +                                          perform any chipset-specific programming.
> +   EfiPciHostBridgeBeginResourceAllocation
> +                                          The resource allocation phase is about to begin. No specific
> +                                          action is required here. This notification can be used to perform
> +                                          any chipset-specific programming.
> +   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
> +                                          root bridges. These resource settings are returned on the next call to
> +                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
> +                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
> +                                          for gathering I/O and memory requests for
> +                                          all the PCI root bridges and submitting these requests using
> +                                          SubmitResources(). This function pads the resource amount
> +                                          to suit the root bridge hardware, takes care of dependencies between
> +                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
> +                                          with the allocation request. In the case of padding, the allocated range
> +                                          could be bigger than what was requested.
> +   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
> +                                          resources (proposed resources) for all the PCI root bridges. After the
> +                                          hardware is programmed, reassigning resources will not be supported.
> +                                          The bus settings are not affected.
> +   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
> +                                          root bridges and resets the I/O and memory apertures to their initial
> +                                          state. The bus settings are not affected. If the request to allocate
> +                                          resources fails, the PCI enumerator can use this notification to
> +                                          deallocate previous resources, adjust the requests, and retry
> +                                          allocation.
> +   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
> +                                          required here. This notification can be used to perform any chipsetspecific
> +                                          programming.
> +
> +   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in] Phase               The phase during enumeration
> +
> +   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
> +                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
> +                                  SubmitResources() has not been called for one or more
> +                                  PCI root bridges before this call
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
> +                                  for a Phase of EfiPciHostBridgeSetResources.
> +   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
> +                                  previously submitted resource requests cannot be fulfilled or
> +                                  were only partially fulfilled.
> +   @retval EFI_SUCCESS            The notification was accepted without any errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NotifyPhase (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
> +  );
> +
> +/**
> +   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
> +
> +   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
> +   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
> +   root bridges. On each call, the handle that was returned by the previous call is passed into the
> +   interface, and on output the interface returns the device handle of the next PCI root bridge. The
> +   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +   for that root bridge. When there are no more PCI root bridges to report, the interface returns
> +   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
> +   are returned by this function.
> +   For D945 implementation, there is only one root bridge in PCI host bridge.
> +
> +   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
> +
> +   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
> +                                  specific Host bridge and return EFI_SUCCESS.
> +   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
> +                                  returned on a previous call to GetNextRootBridge().
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetNextRootBridge (
> +  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN OUT EFI_HANDLE                                       *RootBridgeHandle
> +  );
> +
> +/**
> +   Returns the allocation attributes of a PCI root bridge.
> +
> +   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
> +   from one PCI root bridge to another. These attributes are different from the decode-related
> +   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
> +   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
> +   handles of all the root bridges that are associated with this host bridge must be obtained by calling
> +   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
> +   after the enumeration process. The hardware may provide mechanisms to change the attributes on
> +   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
> +   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
> +   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
> +   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
> +   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
> +   prefetchable memory.
> +      Attribute                                 Description
> +   ------------------------------------         ----------------------------------------------------------------------
> +   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
> +                                                windows for nonprefetchable and prefetchable memory. A PCI bus
> +                                                driver needs to include requests for prefetchable memory in the
> +                                                nonprefetchable memory pool.
> +
> +   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
> +                                                windows. If this bit is not set, the PCI bus driver needs to include
> +                                                requests for a 64-bit memory address in the corresponding 32-bit
> +                                                memory pool.
> +
> +   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
> +                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
> +
> +   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
> +   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
> +   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetAttributes (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT UINT64                                           *Attributes
> +  );
> +
> +/**
> +   Sets up the specified PCI root bridge for the bus enumeration process.
> +
> +   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
> +   over which the search should be performed in ACPI 2.0 resource descriptor format.
> +
> +   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
> +   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
> +   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
> +
> +   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
> +   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
> +   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +StartBusEnumeration (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT VOID                                             **Configuration
> +  );
> +
> +/**
> +   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
> +
> +   This member function programs the specified PCI root bridge to decode the bus range that is
> +   specified by the input parameter Configuration.
> +   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
> +
> +   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
> +   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
> +   @param[in] Configuration     The pointer to the PCI bus resource descriptor
> +
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
> +                                  bus descriptors.
> +   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
> +   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetBusNumbers (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN VOID                                             *Configuration
> +  );
> +
> +/**
> +   Submits the I/O and memory resource requirements for the specified PCI root bridge.
> +
> +   This function is used to submit all the I/O and memory resources that are required by the specified
> +   PCI root bridge. The input parameter Configuration is used to specify the following:
> +   - The various types of resources that are required
> +   - The associated lengths in terms of ACPI 2.0 resource descriptor format
> +
> +   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
> +   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
> +
> +   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
> +                                  not supported by this PCI root bridge. This error will happen if the caller
> +                                  did not combine resources according to Attributes that were returned by
> +                                  GetAllocAttributes().
> +   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SubmitResources (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN VOID                                             *Configuration
> +  );
> +
> +/**
> +   Returns the proposed resource settings for the specified PCI root bridge.
> +
> +   This member function returns the proposed resource settings for the specified PCI root bridge. The
> +   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
> +   EfiPciHostBridgeAllocateResources. The output parameter Configuration
> +   specifies the following:
> +   - The various types of resources, excluding bus resources, that are allocated
> +   - The associated lengths in terms of ACPI 2.0 resource descriptor format
> +
> +   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
> +
> +   @retval EFI_SUCCESS            The requested parameters were returned.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetProposedResources (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT VOID                                             **Configuration
> +  );
> +
> +/**
> +   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
> +   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
> +   PCI controllers before enumeration.
> +
> +   This function is called during the PCI enumeration process. No specific action is expected from this
> +   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
> +   enumeration.
> +
> +   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
> +                            InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
> +                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
> +                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
> +                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
> +   @param Phase             The phase of the PCI device enumeration.
> +
> +   @retval EFI_SUCCESS              The requested parameters were returned.
> +   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
> +                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
> +   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
> +                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
> +                                    bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PreprocessController (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS      PciAddress,
> +  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase
> +  );
> +
> +#endif /* PCI_HOST_BRIDGE_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
> new file mode 100644
> index 000000000000..9f09e8f4d7bc
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.h
> @@ -0,0 +1,554 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#ifndef PCI_ROOT_BRIDGE_IO_H_
> +#define PCI_ROOT_BRIDGE_IO_H_
> +
> +#include <IndustryStandard/Pci.h>
> +#include <Library/PciLib.h>
> +
> +/**
> +   Polls an address in memory mapped I/O space until an exit condition is met, or
> +   a timeout occurs.
> +
> +   This function provides a standard way to poll a PCI memory location. A PCI memory read
> +   operation is performed at the PCI memory address specified by Address for the width specified
> +   by Width. The result of this PCI memory read operation is stored in Result. This PCI memory
> +   read operation is repeated until either a timeout of Delay 100 ns units has expired, or (Result &
> +   Mask) is equal to Value.
> +
> +   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width     Signifies the width of the memory operations.
> +   @param[in]   Address   The base address of the memory operations. The caller is
> +   responsible for aligning Address if required.
> +   @param[in]   Mask      Mask used for the polling criteria. Bytes above Width in Mask
> +   are ignored. The bits in the bytes below Width which are zero in
> +   Mask are ignored when polling the memory address.
> +   @param[in]   Value     The comparison value used for the polling exit criteria.
> +   @param[in]   Delay     The number of 100 ns units to poll. Note that timer available may
> +   be of poorer granularity.
> +   @param[out]  Result    Pointer to the last value read from the memory location.
> +
> +   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid.
> +   @retval EFI_INVALID_PARAMETER  Result is NULL.
> +   @retval EFI_TIMEOUT            Delay expired before a match occurred.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPollMem (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINT64                                Mask,
> +  IN  UINT64                                Value,
> +  IN  UINT64                                Delay,
> +  OUT UINT64                                *Result
> +  );
> +
> +/**
> +   Reads from the I/O space of a PCI Root Bridge. Returns when either the polling exit criteria is
> +   satisfied or after a defined duration.
> +
> +   This function provides a standard way to poll a PCI I/O location. A PCI I/O read operation is
> +   performed at the PCI I/O address specified by Address for the width specified by Width.
> +   The result of this PCI I/O read operation is stored in Result. This PCI I/O read operation is
> +   repeated until either a timeout of Delay 100 ns units has expired, or (Result & Mask) is equal
> +   to Value.
> +
> +   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in] Width     Signifies the width of the I/O operations.
> +   @param[in] Address   The base address of the I/O operations. The caller is responsible
> +   for aligning Address if required.
> +   @param[in] Mask      Mask used for the polling criteria. Bytes above Width in Mask
> +   are ignored. The bits in the bytes below Width which are zero in
> +   Mask are ignored when polling the I/O address.
> +   @param[in] Value     The comparison value used for the polling exit criteria.
> +   @param[in] Delay     The number of 100 ns units to poll. Note that timer available may
> +   be of poorer granularity.
> +   @param[out] Result   Pointer to the last value read from the memory location.
> +
> +   @retval EFI_SUCCESS            The last data returned from the access matched the poll exit criteria.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid.
> +   @retval EFI_INVALID_PARAMETER  Result is NULL.
> +   @retval EFI_TIMEOUT            Delay expired before a match occurred.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPollIo (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINT64                                Mask,
> +  IN  UINT64                                Value,
> +  IN  UINT64                                Delay,
> +  OUT UINT64                                *Result
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
> +
> +   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
> +   registers in the PCI root bridge memory space.
> +   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
> +   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
> +
> +   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width     Signifies the width of the memory operation.
> +   @param[in]   Address   The base address of the memory operation. The caller is
> +   responsible for aligning the Address if required.
> +   @param[in]   Count     The number of memory operations to perform. Bytes moved is
> +   Width size * Count, starting at Address.
> +   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMemRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *Buffer
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in the PCI root bridge memory space.
> +
> +   The Mem.Read(), and Mem.Write() functions enable a driver to access PCI controller
> +   registers in the PCI root bridge memory space.
> +   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
> +   any alignment and memory width restrictions that a PCI Root Bridge on a platform might require.
> +
> +   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width     Signifies the width of the memory operation.
> +   @param[in]   Address   The base address of the memory operation. The caller is
> +   responsible for aligning the Address if required.
> +   @param[in]   Count     The number of memory operations to perform. Bytes moved is
> +   Width size * Count, starting at Address.
> +   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMemWrite (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                Address,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *Buffer
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
> +
> +   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width       Signifies the width of the memory operations.
> +   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
> +   aligning the Address if required.
> +   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
> +   size * Count, starting at Address.
> +   @param[out]  UserBuffer  For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoIoRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                UserAddress,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *UserBuffer
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in the PCI root bridge I/O space.
> +
> +   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width       Signifies the width of the memory operations.
> +   @param[in]   UserAddress The base address of the I/O operation. The caller is responsible for
> +   aligning the Address if required.
> +   @param[in]   Count       The number of I/O operations to perform. Bytes moved is Width
> +   size * Count, starting at Address.
> +   @param[in]   UserBuffer  For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS              The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER    Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoIoWrite (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                UserAddress,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *UserBuffer
> +  );
> +
> +/**
> +   Enables a PCI driver to copy one region of PCI root bridge memory space to another region of PCI
> +   root bridge memory space.
> +
> +   The CopyMem() function enables a PCI driver to copy one region of PCI root bridge memory
> +   space to another region of PCI root bridge memory space. This is especially useful for video scroll
> +   operation on a memory mapped video buffer.
> +   The memory operations are carried out exactly as requested. The caller is responsible for satisfying
> +   any alignment and memory width restrictions that a PCI root bridge on a platform might require.
> +
> +   @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL instance.
> +   @param[in] Width       Signifies the width of the memory operations.
> +   @param[in] DestAddress The destination address of the memory operation. The caller is
> +   responsible for aligning the DestAddress if required.
> +   @param[in] SrcAddress  The source address of the memory operation. The caller is
> +   responsible for aligning the SrcAddress if required.
> +   @param[in] Count       The number of memory operations to perform. Bytes moved is
> +   Width size * Count, starting at DestAddress and SrcAddress.
> +
> +   @retval  EFI_SUCCESS             The data was copied from one memory region to another memory region.
> +   @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
> +   @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoCopyMem (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                DestAddress,
> +  IN UINT64                                SrcAddress,
> +  IN UINTN                                 Count
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
> +
> +   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
> +   registers for a PCI controller.
> +   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
> +   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
> +   require.
> +
> +   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width     Signifies the width of the memory operations.
> +   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
> +   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
> +   moved is Width size * Count, starting at Address.
> +   @param[out]  Buffer    For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPciRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *Buffer
> +  );
> +
> +/**
> +   Enables a PCI driver to access PCI controller registers in a PCI root bridge's configuration space.
> +
> +   The Pci.Read() and Pci.Write() functions enable a driver to access PCI configuration
> +   registers for a PCI controller.
> +   The PCI Configuration operations are carried out exactly as requested. The caller is responsible for
> +   any alignment and PCI configuration width issues that a PCI Root Bridge on a platform might
> +   require.
> +
> +   @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Width     Signifies the width of the memory operations.
> +   @param[in]   Address   The address within the PCI configuration space for the PCI controller.
> +   @param[in]   Count     The number of PCI configuration operations to perform. Bytes
> +   moved is Width size * Count, starting at Address.
> +   @param[in]   Buffer    For read operations, the destination buffer to store the results. For
> +   write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPciWrite (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                Address,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *Buffer
> +  );
> +
> +/**
> +   Provides the PCI controller-specific addresses required to access system memory from a
> +   DMA bus master.
> +
> +   The Map() function provides the PCI controller specific addresses needed to access system
> +   memory. This function is used to map system memory for PCI bus master DMA accesses.
> +
> +   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]       Operation       Indicates if the bus master is going to read or write to system memory.
> +   @param[in]       HostAddress     The system memory address to map to the PCI controller.
> +   @param[in, out]  NumberOfBytes   On input the number of bytes to map. On output the number of bytes that were mapped.
> +   @param[out]      DeviceAddress   The resulting map address for the bus master PCI controller to use
> +   to access the system memory's HostAddress.
> +   @param[out]      Mapping         The value to pass to Unmap() when the bus master DMA operation is complete.
> +
> +   @retval EFI_SUCCESS            The range was mapped for the returned NumberOfBytes.
> +   @retval EFI_INVALID_PARAMETER  Operation is invalid.
> +   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
> +   @retval EFI_INVALID_PARAMETER  NumberOfBytes is NULL.
> +   @retval EFI_INVALID_PARAMETER  DeviceAddress is NULL.
> +   @retval EFI_INVALID_PARAMETER  Mapping is NULL.
> +   @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
> +   @retval EFI_DEVICE_ERROR       The system hardware could not map the requested address.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMap (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
> +  IN     VOID                                      *HostAddress,
> +  IN OUT UINTN                                     *NumberOfBytes,
> +  OUT    EFI_PHYSICAL_ADDRESS                      *DeviceAddress,
> +  OUT    VOID                                      **Mapping
> +  );
> +
> +/**
> +   Completes the Map() operation and releases any corresponding resources.
> +
> +   The Unmap() function completes the Map() operation and releases any corresponding resources.
> +   If the operation was an EfiPciOperationBusMasterWrite or
> +   EfiPciOperationBusMasterWrite64, the data is committed to the target system memory.
> +   Any resources used for the mapping are freed.
> +
> +   @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in] Mapping   The mapping value returned from Map().
> +
> +   @retval EFI_SUCCESS            The range was unmapped.
> +   @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
> +   @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoUnmap (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN VOID                            *Mapping
> +  );
> +
> +/**
> +   Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer or
> +   EfiPciOperationBusMasterCommonBuffer64 mapping.
> +
> +   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param Type        This parameter is not used and must be ignored.
> +   @param MemoryType  The type of memory to allocate, EfiBootServicesData or EfiRuntimeServicesData.
> +   @param Pages       The number of pages to allocate.
> +   @param HostAddress A pointer to store the base system memory address of the allocated range.
> +   @param Attributes  The requested bit mask of attributes for the allocated range. Only
> +   the attributes EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE, EFI_PCI_ATTRIBUTE_MEMORY_CACHED,
> +   and EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this function.
> +
> +   @retval EFI_SUCCESS            The requested memory pages were allocated.
> +   @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
> +   @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
> +   @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal attribute bits are
> +   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
> +   @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoAllocateBuffer (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN  EFI_ALLOCATE_TYPE               Type,
> +  IN  EFI_MEMORY_TYPE                 MemoryType,
> +  IN  UINTN                           Pages,
> +  OUT VOID                            **HostAddress,
> +  IN  UINT64                          Attributes
> +  );
> +
> +/**
> +   Frees memory that was allocated with AllocateBuffer().
> +
> +   The FreeBuffer() function frees memory that was allocated with AllocateBuffer().
> +
> +   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param Pages       The number of pages to free.
> +   @param HostAddress The base system memory address of the allocated range.
> +
> +   @retval EFI_SUCCESS            The requested memory pages were freed.
> +   @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and Pages
> +   was not allocated with AllocateBuffer().
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoFreeBuffer (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN  UINTN                           Pages,
> +  OUT VOID                            *HostAddress
> +  );
> +
> +/**
> +   Flushes all PCI posted write transactions from a PCI host bridge to system memory.
> +
> +   The Flush() function flushes any PCI posted write transactions from a PCI host bridge to system
> +   memory. Posted write transactions are generated by PCI bus masters when they perform write
> +   transactions to target addresses in system memory.
> +   This function does not flush posted write transactions from any PCI bridges. A PCI controller
> +   specific action must be taken to guarantee that the posted write transactions have been flushed from
> +   the PCI controller and from all the PCI bridges into the PCI host bridge. This is typically done with
> +   a PCI read transaction from the PCI controller prior to calling Flush().
> +
> +   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +
> +   @retval EFI_SUCCESS        The PCI posted write transactions were flushed from the PCI host
> +   bridge to system memory.
> +   @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed from the PCI
> +   host bridge due to a hardware error.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoFlush (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
> +  );
> +
> +/**
> +   Gets the attributes that a PCI root bridge supports setting with SetAttributes(), and the
> +   attributes that a PCI root bridge is currently using.
> +
> +   The GetAttributes() function returns the mask of attributes that this PCI root bridge supports
> +   and the mask of attributes that the PCI root bridge is currently using.
> +
> +   @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param Supported   A pointer to the mask of attributes that this PCI root bridge
> +   supports setting with SetAttributes().
> +   @param Attributes  A pointer to the mask of attributes that this PCI root bridge is
> +   currently using.
> +
> +   @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes that the PCI root
> +   bridge supports is returned in Supports. If Attributes is
> +   not NULL, then the attributes that the PCI root bridge is currently
> +   using is returned in Attributes.
> +   @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoGetAttributes (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  OUT UINT64                          *Supported,
> +  OUT UINT64                          *Attributes
> +  );
> +
> +/**
> +   Sets attributes for a resource range on a PCI root bridge.
> +
> +   The SetAttributes() function sets the attributes specified in Attributes for the PCI root
> +   bridge on the resource range specified by ResourceBase and ResourceLength. Since the
> +   granularity of setting these attributes may vary from resource type to resource type, and from
> +   platform to platform, the actual resource range and the one passed in by the caller may differ. As a
> +   result, this function may set the attributes specified by Attributes on a larger resource range
> +   than the caller requested. The actual range is returned in ResourceBase and
> +   ResourceLength. The caller is responsible for verifying that the actual range for which the
> +   attributes were set is acceptable.
> +
> +   @param[in]       This            A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]       Attributes      The mask of attributes to set. If the attribute bit
> +   MEMORY_WRITE_COMBINE, MEMORY_CACHED, or
> +   MEMORY_DISABLE is set, then the resource range is specified by
> +   ResourceBase and ResourceLength. If
> +   MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
> +   MEMORY_DISABLE are not set, then ResourceBase and
> +   ResourceLength are ignored, and may be NULL.
> +   @param[in, out]  ResourceBase    A pointer to the base address of the resource range to be modified
> +   by the attributes specified by Attributes.
> +   @param[in, out]  ResourceLength  A pointer to the length of the resource range to be modified by the
> +   attributes specified by Attributes.
> +
> +   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
> +   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
> +   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoSetAttributes (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN     UINT64                          Attributes,
> +  IN OUT UINT64                          *ResourceBase,
> +  IN OUT UINT64                          *ResourceLength
> +  );
> +
> +/**
> +   Retrieves the current resource settings of this PCI root bridge in the form of a set of ACPI 2.0
> +   resource descriptors.
> +
> +   There are only two resource descriptor types from the ACPI Specification that may be used to
> +   describe the current resources allocated to a PCI root bridge. These are the QWORD Address
> +   Space Descriptor (ACPI 2.0 Section 6.4.3.5.1), and the End Tag (ACPI 2.0 Section 6.4.2.8). The
> +   QWORD Address Space Descriptor can describe memory, I/O, and bus number ranges for dynamic
> +   or fixed resources. The configuration of a PCI root bridge is described with one or more QWORD
> +   Address Space Descriptors followed by an End Tag.
> +
> +   @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[out]  Resources   A pointer to the ACPI 2.0 resource descriptors that describe the
> +   current configuration of this PCI root bridge. The storage for the
> +   ACPI 2.0 resource descriptors is allocated by this function. The
> +   caller must treat the return buffer as read-only data, and the buffer
> +   must not be freed by the caller.
> +
> +   @retval  EFI_SUCCESS     The current configuration of this PCI root bridge was returned in Resources.
> +   @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge could not be retrieved.
> +   @retval  EFI_INVALID_PARAMETER Invalid pointer of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoConfiguration (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  OUT VOID                            **Resources
> +  );
> +
> +#endif /* PCI_ROOT_BRIDGE_IO_H_ */
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
> new file mode 100644
> index 000000000000..2e0876128158
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
> @@ -0,0 +1,1419 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <Guid/EventGroup.h>
> +#include <IndustryStandard/Pci.h>
> +#include <Library/AcpiHelperLib.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcieCoreLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/PrintLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include "PciHostBridge.h"
> +#include "PciRootBridgeIo.h"
> +
> +EFI_HANDLE mDriverImageHandle;
> +
> +PCI_HOST_BRIDGE_INSTANCE mPciHostBridgeInstanceTemplate = {
> +  PCI_HOST_BRIDGE_SIGNATURE,  // Signature
> +  NULL,                       // HostBridgeHandle
> +  0,                          // RootBridgeNumber
> +  {NULL, NULL},               // Head
> +  FALSE,                      // ResourceSubiteed
> +  TRUE,                       // CanRestarted
> +  {
> +    NotifyPhase,
> +    GetNextRootBridge,
> +    GetAttributes,
> +    StartBusEnumeration,
> +    SetBusNumbers,
> +    SubmitResources,
> +    GetProposedResources,
> +    PreprocessController
> +  }
> +};
> +
> +EFI_PCI_ROOT_BRIDGE_DEVICE_PATH mPciDevicePathTemplate =
> +{
> +  {
> +    {
> +      ACPI_DEVICE_PATH,
> +      ACPI_DP,
> +      {
> +        (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),
> +        (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)
> +      }
> +    },
> +    EISA_PNP_ID (0x0A08),
> +    0
> +  },
> +
> +  {
> +    END_DEVICE_PATH_TYPE,
> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
> +    {
> +      END_DEVICE_PATH_LENGTH,
> +      0
> +    }
> +  }
> +};
> +
> +STATIC
> +EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *
> +EFIAPI
> +GenerateRootBridgeDevicePath (
> +  UINTN HostBridgeIdx,
> +  UINTN RootBridgeIdx
> +  )
> +{
> +
> +  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *RootBridgeDevPath = NULL;
> +
> +  RootBridgeDevPath = AllocateCopyPool (
> +                        sizeof (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH),
> +                        (VOID *)&mPciDevicePathTemplate
> +                        );
> +  if (RootBridgeDevPath == NULL) {
> +    return NULL;
> +  }
> +
> +  /* We don't expect to have more than 65536 root ports on the same root bridge */
> +  RootBridgeDevPath->AcpiDevicePath.UID = (UINT32)((HostBridgeIdx << 16) + RootBridgeIdx);
> +
> +  return RootBridgeDevPath;
> +}
> +
> +/**
> +  This function will be called when ReadyToBoot event will be signaled.
> +
> +  @param Event signaled event
> +  @param Context calling context
> +
> +  @retval VOID
> +**/
> +VOID
> +EFIAPI
> +PciHostBridgeReadyToBootEvent (
> +  EFI_EVENT Event,
> +  VOID      *Context
> +  )
> +{
> +  UINTN Idx1, Idx2, Count = 0;
> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
> +
> +  for (Idx1 = 0; Idx1 < Ac01PcieGetTotalHBs (); Idx1++) {
> +    for (Idx2 = 0; Idx2 < Ac01PcieGetTotalRBsPerHB (Idx1); Idx2++) {
> +      AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._STA", Count);
> +      if (Ac01PcieCheckRootBridgeDisabled (Idx1, Idx2)) {
> +        AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
> +      } else {
> +        AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
> +      }
> +      Count++;
> +    }
> +  }
> +
> +  //
> +  // Close the event, so it will not be signalled again.
> +  //
> +  gBS->CloseEvent (Event);
> +}
> +
> +/**
> +   Construct the Pci Root Bridge Io protocol
> +
> +   @param Protocol         Point to protocol instance
> +   @param HostBridgeHandle Handle of host bridge
> +   @param Attri            Attribute of host bridge
> +   @param ResAppeture      ResourceAppeture for host bridge
> +
> +   @retval EFI_SUCCESS Success to initialize the Pci Root Bridge.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +RootBridgeConstructor (
> +  IN PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance,
> +  IN EFI_HANDLE               HostBridgeHandle,
> +  IN UINT64                   Attri,
> +  IN UINT32                   Seg
> +  )
> +{
> +  PCI_RESOURCE_TYPE Index;
> +
> +  //
> +  // The host to pci bridge, the host memory and io addresses are
> +  // integrated as PCIe controller subsystem resource. We move forward to mark
> +  // resource as ResAllocated.
> +  //
> +  for (Index = TypeIo; Index < TypeMax; Index++) {
> +    RootBridgeInstance->ResAllocNode[Index].Type      = Index;
> +    RootBridgeInstance->ResAllocNode[Index].Base      = 0;
> +    RootBridgeInstance->ResAllocNode[Index].Length    = 0;
> +    RootBridgeInstance->ResAllocNode[Index].Status    = ResNone;
> +  }
> +
> +  RootBridgeInstance->RootBridgeAttrib                 = Attri;
> +  RootBridgeInstance->RootBridge.Supports              = EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
> +  // Support Extended (4096-byte) Configuration Space
> +  RootBridgeInstance->RootBridge.NoExtendedConfigSpace = FALSE;
> +  RootBridgeInstance->RootBridge.Attributes            = RootBridgeInstance->RootBridge.Supports;
> +
> +  RootBridgeInstance->RbIo.ParentHandle   = HostBridgeHandle;
> +
> +  RootBridgeInstance->RbIo.PollMem        = RootBridgeIoPollMem;
> +  RootBridgeInstance->RbIo.PollIo         = RootBridgeIoPollIo;
> +
> +  RootBridgeInstance->RbIo.Mem.Read       = RootBridgeIoMemRead;
> +  RootBridgeInstance->RbIo.Mem.Write      = RootBridgeIoMemWrite;
> +
> +  RootBridgeInstance->RbIo.Io.Read        = RootBridgeIoIoRead;
> +  RootBridgeInstance->RbIo.Io.Write       = RootBridgeIoIoWrite;
> +
> +  RootBridgeInstance->RbIo.CopyMem        = RootBridgeIoCopyMem;
> +
> +  RootBridgeInstance->RbIo.Pci.Read       = RootBridgeIoPciRead;
> +  RootBridgeInstance->RbIo.Pci.Write      = RootBridgeIoPciWrite;
> +
> +  RootBridgeInstance->RbIo.Map            = RootBridgeIoMap;
> +  RootBridgeInstance->RbIo.Unmap          = RootBridgeIoUnmap;
> +
> +  RootBridgeInstance->RbIo.AllocateBuffer = RootBridgeIoAllocateBuffer;
> +  RootBridgeInstance->RbIo.FreeBuffer     = RootBridgeIoFreeBuffer;
> +
> +  RootBridgeInstance->RbIo.Flush          = RootBridgeIoFlush;
> +
> +  RootBridgeInstance->RbIo.GetAttributes  = RootBridgeIoGetAttributes;
> +  RootBridgeInstance->RbIo.SetAttributes  = RootBridgeIoSetAttributes;
> +
> +  RootBridgeInstance->RbIo.Configuration  = RootBridgeIoConfiguration;
> +
> +  RootBridgeInstance->RbIo.SegmentNumber  = Seg;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Entry point of this driver
> +
> +   @param ImageHandle     Handle of driver image
> +   @param SystemTable     Point to EFI_SYSTEM_TABLE
> +
> +   @retval EFI_OUT_OF_RESOURCES  Can not allocate memory resource
> +   @retval EFI_DEVICE_ERROR      Can not install the protocol instance
> +   @retval EFI_SUCCESS           Success to initialize the Pci host bridge.
> +**/
> +EFI_STATUS
> +EFIAPI
> +InitializePciHostBridge (
> +  IN EFI_HANDLE       ImageHandle,
> +  IN EFI_SYSTEM_TABLE *SystemTable
> +  )
> +{
> +  STATIC EFI_GUID          guidReadyToBoot = EFI_EVENT_GROUP_READY_TO_BOOT;
> +  EFI_EVENT                EvtReadyToBoot;
> +  EFI_STATUS               Status;
> +  UINTN                    Idx1;
> +  UINTN                    Idx2;
> +  UINTN                    Count = 0;
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance = NULL;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance = NULL;
> +  UINTN                    NumberRootPortInstalled = FALSE;
> +  LIST_ENTRY               *List;
> +  UINTN                    SegmentNumber;
> +
> +  if (( Ac01PcieCheckRootBridgeDisabled == NULL)
> +      || (Ac01PcieSetup == NULL)
> +      || (Ac01PcieEnd == NULL)
> +      || (Ac01PcieSetupHostBridge == NULL)
> +      || (Ac01PcieSetupRootBridge == NULL)
> +      || (Ac01PcieConfigRW == NULL)
> +      || (Ac01PcieGetTotalHBs == NULL)
> +      || (Ac01PcieGetTotalRBsPerHB == NULL)
> +      || (Ac01PcieGetRootBridgeAttribute == NULL ))
> +  {
> +    PCIE_ERR ("PciHostBridge: Invalid Parameters\n");
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PCIE_DEBUG ("%a: START\n", __FUNCTION__);
> +
> +  mDriverImageHandle = ImageHandle;
> +
> +  // Inform Pcie Core BSP Driver to start setup phase
> +  Status = Ac01PcieSetup (ImageHandle, SystemTable);
> +  if (EFI_ERROR (Status)) {
> +    PCIE_ERR ("  PCIe Core Setup failed!\n");
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  //
> +  // Create Host Bridge Device Handle
> +  //
> +  for (Idx1 = 0; Idx1 < Ac01PcieGetTotalHBs (); Idx1++) {
> +    HostBridgeInstance = AllocateCopyPool (
> +                           sizeof (PCI_HOST_BRIDGE_INSTANCE),
> +                           (VOID *)&mPciHostBridgeInstanceTemplate
> +                           );
> +    if (HostBridgeInstance == NULL) {
> +      PCIE_ERR ("  HB%d allocation failed!\n", Idx1);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    Status = Ac01PcieSetupHostBridge (Idx1);
> +    if (EFI_ERROR (Status)) {
> +      FreePool (HostBridgeInstance);
> +      PCIE_ERR ("  HB%d setup failed!\n", Idx1);
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +
> +    HostBridgeInstance->RootBridgeNumber = Ac01PcieGetTotalRBsPerHB (Idx1);
> +
> +    InitializeListHead (&HostBridgeInstance->Head);
> +
> +    Status = gBS->InstallMultipleProtocolInterfaces (
> +                    &HostBridgeInstance->HostBridgeHandle,
> +                    &gEfiPciHostBridgeResourceAllocationProtocolGuid,
> +                    &HostBridgeInstance->ResAlloc,
> +                    NULL
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      FreePool (HostBridgeInstance);
> +      PCIE_ERR ("  HB%d instance installation failed\n", Idx1);
> +      return EFI_DEVICE_ERROR;
> +    }
> +
> +    NumberRootPortInstalled = 0;
> +
> +    //
> +    // Create Root Bridge Device Handle in this Host Bridge
> +    //
> +    for (Idx2 = 0; Idx2 < HostBridgeInstance->RootBridgeNumber; Idx2++, Count++) {
> +      RootBridgeInstance = AllocateZeroPool (sizeof (PCI_ROOT_BRIDGE_INSTANCE));
> +      if (RootBridgeInstance == NULL) {
> +        gBS->UninstallMultipleProtocolInterfaces (
> +               HostBridgeInstance->HostBridgeHandle,
> +               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
> +               &HostBridgeInstance->ResAlloc,
> +               NULL
> +               );
> +        PCIE_ERR ("    HB%d-RB%d allocation failed!\n", Idx1, Idx2);
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +
> +      // Initialize Hardware
> +      Status = Ac01PcieSetupRootBridge (Idx1, Idx2, (VOID *)&RootBridgeInstance->RootBridge);
> +      if (EFI_ERROR (Status)) {
> +        FreePool (RootBridgeInstance);
> +        PCIE_ERR ("    HB%d-RB%d setup failed!\n", Idx1, Idx2);
> +        continue;
> +      }
> +
> +      NumberRootPortInstalled++;
> +
> +      RootBridgeInstance->ConfigBuffer = AllocateZeroPool (
> +                                           TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR)
> +                                           + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
> +                                           );
> +      if (RootBridgeInstance->ConfigBuffer == NULL) {
> +        gBS->UninstallMultipleProtocolInterfaces (
> +               HostBridgeInstance->HostBridgeHandle,
> +               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
> +               &HostBridgeInstance->ResAlloc,
> +               NULL
> +               );
> +        FreePool (RootBridgeInstance);
> +        PCIE_ERR ("    HB%d-RB%d Descriptor allocation failed!\n", Idx1, Idx2);
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +
> +      RootBridgeInstance->Signature = PCI_ROOT_BRIDGE_SIGNATURE;
> +      RootBridgeInstance->RootBridge.DevicePath =
> +        (EFI_DEVICE_PATH_PROTOCOL *)GenerateRootBridgeDevicePath (Idx1, Idx2);
> +
> +      SegmentNumber = Count;
> +      if (Ac01PcieGetRootBridgeSegmentNumber) {
> +        SegmentNumber = Ac01PcieGetRootBridgeSegmentNumber (Idx1, Idx2);
> +      }
> +
> +      RootBridgeConstructor (
> +        RootBridgeInstance,
> +        HostBridgeInstance->HostBridgeHandle,
> +        Ac01PcieGetRootBridgeAttribute (Idx1, Idx2),
> +        SegmentNumber
> +        );
> +
> +      Status = gBS->InstallMultipleProtocolInterfaces (
> +                      &RootBridgeInstance->RootBridgeHandle,
> +                      &gEfiDevicePathProtocolGuid,
> +                      RootBridgeInstance->RootBridge.DevicePath,
> +                      &gEfiPciRootBridgeIoProtocolGuid,
> +                      &RootBridgeInstance->RbIo,
> +                      NULL
> +                      );
> +      if (EFI_ERROR (Status)) {
> +        // Uninstall all root ports of this bridge
> +        List = HostBridgeInstance->Head.ForwardLink;
> +        while (List != &HostBridgeInstance->Head) {
> +          RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +          gBS->UninstallMultipleProtocolInterfaces (
> +                 RootBridgeInstance->RootBridgeHandle,
> +                 &gEfiDevicePathProtocolGuid,
> +                 RootBridgeInstance->RootBridge.DevicePath,
> +                 &gEfiPciRootBridgeIoProtocolGuid,
> +                 &RootBridgeInstance->RbIo,
> +                 NULL
> +                 );
> +          FreePool (RootBridgeInstance->ConfigBuffer);
> +          FreePool (RootBridgeInstance);
> +          List = List->ForwardLink;
> +        }
> +
> +        gBS->UninstallMultipleProtocolInterfaces (
> +               HostBridgeInstance->HostBridgeHandle,
> +               &gEfiPciHostBridgeResourceAllocationProtocolGuid,
> +               &HostBridgeInstance->ResAlloc,
> +               NULL
> +               );
> +        FreePool (HostBridgeInstance);
> +        PCIE_ERR ("    HB%d-RB%d instance installation failed\n", Idx1, Idx2);
> +        return EFI_DEVICE_ERROR;
> +      }
> +
> +      InsertTailList (&HostBridgeInstance->Head, &RootBridgeInstance->Link);
> +    }
> +
> +    if (NumberRootPortInstalled == 0) {
> +      PCIE_WARN ("  No Root Port! Uninstalling HB%d\n", Idx1);
> +      gBS->UninstallMultipleProtocolInterfaces (
> +             HostBridgeInstance->HostBridgeHandle,
> +             &gEfiPciHostBridgeResourceAllocationProtocolGuid,
> +             &HostBridgeInstance->ResAlloc,
> +             NULL
> +             );
> +      FreePool (HostBridgeInstance);
> +    }
> +  }
> +
> +  // Inform BSP Pcie Driver to end setup phase
> +  Ac01PcieEnd ();
> +
> +  /* Event for ACPI Menu configuration */
> +  Status = gBS->CreateEventEx (
> +                  EVT_NOTIFY_SIGNAL,                 // Type,
> +                  TPL_NOTIFY,                        // NotifyTpl
> +                  PciHostBridgeReadyToBootEvent,     // NotifyFunction
> +                  NULL,                              // NotifyContext
> +                  &guidReadyToBoot,                  // EventGroup
> +                  &EvtReadyToBoot                    // Event
> +                  );
> +
> +  PCIE_DEBUG ("%a: END\n", __FUNCTION__);
> +
> +  return Status;
> +}
> +
> +/**
> +   These are the notifications from the PCI bus driver that it is about to enter a certain
> +   phase of the PCI enumeration process.
> +
> +   This member function can be used to notify the host bridge driver to perform specific actions,
> +   including any chipset-specific initialization, so that the chipset is ready to enter the next phase.
> +   Eight notification points are defined at this time. See belows:
> +   EfiPciHostBridgeBeginEnumeration       Resets the host bridge PCI apertures and internal data
> +                                          structures. The PCI enumerator should issue this notification
> +                                          before starting a fresh enumeration process. Enumeration cannot
> +                                          be restarted after sending any other notification such as
> +                                          EfiPciHostBridgeBeginBusAllocation.
> +   EfiPciHostBridgeBeginBusAllocation     The bus allocation phase is about to begin. No specific action is
> +                                          required here. This notification can be used to perform any
> +                                          chipset-specific programming.
> +   EfiPciHostBridgeEndBusAllocation       The bus allocation and bus programming phase is complete. No
> +                                          specific action is required here. This notification can be used to
> +                                          perform any chipset-specific programming.
> +   EfiPciHostBridgeBeginResourceAllocation
> +                                          The resource allocation phase is about to begin. No specific
> +                                          action is required here. This notification can be used to perform
> +                                          any chipset-specific programming.
> +   EfiPciHostBridgeAllocateResources      Allocates resources per previously submitted requests for all the PCI
> +                                          root bridges. These resource settings are returned on the next call to
> +                                          GetProposedResources(). Before calling NotifyPhase() with a Phase of
> +                                          EfiPciHostBridgeAllocateResource, the PCI bus enumerator is responsible
> +                                          for gathering I/O and memory requests for
> +                                          all the PCI root bridges and submitting these requests using
> +                                          SubmitResources(). This function pads the resource amount
> +                                          to suit the root bridge hardware, takes care of dependencies between
> +                                          the PCI root bridges, and calls the Global Coherency Domain (GCD)
> +                                          with the allocation request. In the case of padding, the allocated range
> +                                          could be bigger than what was requested.
> +   EfiPciHostBridgeSetResources           Programs the host bridge hardware to decode previously allocated
> +                                          resources (proposed resources) for all the PCI root bridges. After the
> +                                          hardware is programmed, reassigning resources will not be supported.
> +                                          The bus settings are not affected.
> +   EfiPciHostBridgeFreeResources          Deallocates resources that were previously allocated for all the PCI
> +                                          root bridges and resets the I/O and memory apertures to their initial
> +                                          state. The bus settings are not affected. If the request to allocate
> +                                          resources fails, the PCI enumerator can use this notification to
> +                                          deallocate previous resources, adjust the requests, and retry
> +                                          allocation.
> +   EfiPciHostBridgeEndResourceAllocation  The resource allocation phase is completed. No specific action is
> +                                          required here. This notification can be used to perform any chipsetspecific
> +                                          programming.
> +
> +   @param[in] This                The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in] Phase               The phase during enumeration
> +
> +   @retval EFI_NOT_READY          This phase cannot be entered at this time. For example, this error
> +                                  is valid for a Phase of EfiPciHostBridgeAllocateResources if
> +                                  SubmitResources() has not been called for one or more
> +                                  PCI root bridges before this call
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error. This error is valid
> +                                  for a Phase of EfiPciHostBridgeSetResources.
> +   @retval EFI_INVALID_PARAMETER  Invalid phase parameter
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +                                  This error is valid for a Phase of EfiPciHostBridgeAllocateResources if the
> +                                  previously submitted resource requests cannot be fulfilled or
> +                                  were only partially fulfilled.
> +   @retval EFI_SUCCESS            The notification was accepted without any errors.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +NotifyPhase (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE    Phase
> +  )
> +{
> +  PCI_HOST_BRIDGE_INSTANCE        *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE        *RootBridgeInstance;
> +  PCI_RESOURCE_TYPE               Index;
> +  PCI_RES_NODE                    *ResNode;
> +  LIST_ENTRY                      *List;
> +  EFI_PHYSICAL_ADDRESS            AddrBase;
> +  EFI_PHYSICAL_ADDRESS            AddrLimit;
> +  UINT64                          AddrLen;
> +  UINTN                           BitsOfAlignment;
> +  EFI_STATUS                      Status;
> +  EFI_STATUS                      ReturnStatus;
> +  EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *DevPath;
> +  UINTN                           HostBridgeIdx, RootBridgeIdx;
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  ReturnStatus = EFI_SUCCESS;
> +
> +  switch (Phase) {
> +
> +  case EfiPciHostBridgeBeginEnumeration:
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginEnumeration)\n");
> +
> +    if (!HostBridgeInstance->CanRestarted) {
> +      return EFI_NOT_READY;
> +    }
> +
> +    //
> +    // Reset each Root Bridge
> +    //
> +    List = HostBridgeInstance->Head.ForwardLink;
> +    while (List != &HostBridgeInstance->Head) {
> +      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +      for (Index = TypeIo; Index < TypeMax; Index++) {
> +        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
> +
> +        ResNode->Type      = Index;
> +        ResNode->Base      = 0;
> +        ResNode->Length    = 0;
> +        ResNode->Status    = ResNone;
> +      }
> +
> +      List = List->ForwardLink;
> +    }
> +
> +    HostBridgeInstance->ResourceSubmited = FALSE;
> +    HostBridgeInstance->CanRestarted     = TRUE;
> +    break;
> +
> +  case EfiPciHostBridgeEndEnumeration:
> +    //
> +    // The Host Bridge Enumeration is completed. No specific action is required here.
> +    // This notification can be used to perform any chipset specific programming.
> +    //
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndEnumeration)\n");
> +    break;
> +
> +  case EfiPciHostBridgeBeginBusAllocation:
> +    // No specific action is required here, can perform any chipset specific programing
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginBusAllocation)\n");
> +    HostBridgeInstance->CanRestarted = FALSE;
> +    break;
> +
> +  case EfiPciHostBridgeEndBusAllocation:
> +    // No specific action is required here, can perform any chipset specific programing
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndBusAllocation)\n");
> +    break;
> +
> +  case EfiPciHostBridgeBeginResourceAllocation:
> +    // No specific action is required here, can perform any chipset specific programing
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (BeginResourceAllocation)\n");
> +    break;
> +
> +  case EfiPciHostBridgeAllocateResources:
> +
> +    // Make sure the resource for all root bridges has been submitted.
> +    if (!HostBridgeInstance->ResourceSubmited) {
> +      return EFI_NOT_READY;
> +    }
> +
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (AllocateResources)\n");
> +
> +    //
> +    // Take care of the resource dependencies between the root bridges
> +    //
> +    List = HostBridgeInstance->Head.ForwardLink;
> +    while (List != &HostBridgeInstance->Head) {
> +
> +      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +      for (Index = TypeIo; Index < TypeMax; Index++) {
> +        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
> +
> +        if (ResNode->Status == ResNone) {
> +          continue;
> +        }
> +
> +        switch (Index) {
> +        case TypeIo:
> +          AddrBase = RootBridgeInstance->RootBridge.Io.Base;
> +          AddrLimit = RootBridgeInstance->RootBridge.Io.Limit;
> +          break;
> +
> +        case TypeMem32:
> +          AddrBase = RootBridgeInstance->RootBridge.Mem.Base;
> +          AddrLimit = RootBridgeInstance->RootBridge.Mem.Limit;
> +          break;
> +
> +        case TypePMem32:
> +          AddrBase = RootBridgeInstance->RootBridge.PMem.Base;
> +          AddrLimit = RootBridgeInstance->RootBridge.PMem.Limit;
> +          break;
> +
> +        case TypeMem64:
> +          AddrBase = RootBridgeInstance->RootBridge.MemAbove4G.Base;
> +          AddrLimit = RootBridgeInstance->RootBridge.MemAbove4G.Limit;
> +          break;
> +
> +        case TypePMem64:
> +          AddrBase = RootBridgeInstance->RootBridge.PMemAbove4G.Base;
> +          AddrLimit = RootBridgeInstance->RootBridge.PMemAbove4G.Limit;
> +          break;
> +
> +        default:
> +          continue;
> +        } // end switch (Index)
> +
> +        AddrLen = ResNode->Length;
> +
> +        if ((AddrBase + AddrLen - 1) > AddrLimit) {
> +          ReturnStatus = EFI_OUT_OF_RESOURCES;
> +          ResNode->Length = 0;
> +        } else {
> +          // Get the number of '1' in Alignment.
> +          BitsOfAlignment = (UINTN)(HighBitSet64 (ResNode->Alignment) + 1);
> +
> +          Status = gDS->AllocateMemorySpace (
> +                          EfiGcdAllocateAddress,
> +                          EfiGcdMemoryTypeMemoryMappedIo,
> +                          BitsOfAlignment,
> +                          AddrLen,
> +                          &AddrBase,
> +                          mDriverImageHandle,
> +                          NULL
> +                          );
> +
> +          if (!EFI_ERROR (Status)) {
> +            ResNode->Base   = (UINTN)AddrBase;
> +            ResNode->Status = ResAllocated;
> +          } else {
> +            ReturnStatus = EFI_OUT_OF_RESOURCES;
> +            ResNode->Length = 0;
> +          }
> +        }
> +      } // end for
> +      List = List->ForwardLink;
> +    } // end while
> +
> +    break;
> +
> +  case EfiPciHostBridgeSetResources:
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (SetResources)\n");
> +    break;
> +
> +  case EfiPciHostBridgeFreeResources:
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (FreeResources)\n");
> +
> +    List = HostBridgeInstance->Head.ForwardLink;
> +
> +    while (List != &HostBridgeInstance->Head) {
> +      RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +      for (Index = TypeIo; Index < TypeMax; Index++) {
> +        ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
> +
> +        if (ResNode->Status == ResAllocated) {
> +          AddrLen = ResNode->Length;
> +          AddrBase = ResNode->Base;
> +
> +          switch (Index) {
> +          case TypeIo:
> +          case TypeMem32:
> +          case TypePMem32:
> +          case TypeMem64:
> +          case TypePMem64:
> +            Status = gDS->FreeMemorySpace (AddrBase, AddrLen);
> +            if (EFI_ERROR (Status)) {
> +              ReturnStatus = Status;
> +            }
> +            break;
> +
> +          default:
> +            continue;
> +          } // end switch (Index)
> +
> +          ResNode->Type      = Index;
> +          ResNode->Base      = 0;
> +          ResNode->Length    = 0;
> +          ResNode->Status    = ResNone;
> +        }
> +      }
> +
> +      List = List->ForwardLink;
> +    }
> +
> +    HostBridgeInstance->ResourceSubmited = FALSE;
> +    HostBridgeInstance->CanRestarted     = TRUE;
> +    break;
> +
> +  case EfiPciHostBridgeEndResourceAllocation:
> +    //
> +    // The resource allocation phase is completed.  No specific action is required
> +    // here. This notification can be used to perform any chipset specific programming.
> +    //
> +    PCIE_DEBUG ("PciHostBridge: NotifyPhase (EndResourceAllocation)\n");
> +    HostBridgeInstance->CanRestarted = FALSE;
> +    break;
> +
> +  default:
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  // Notify BSP Driver the phase we are being
> +  List = HostBridgeInstance->Head.ForwardLink;
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +    // Retrieve the HostBridgeIdx and RootBridgeIdx from UID
> +    // UID = (UINT32)((HostBridgeIdx << 16) + RootBridgeIdx);
> +    DevPath = (EFI_PCI_ROOT_BRIDGE_DEVICE_PATH *)RootBridgeInstance->RootBridge.DevicePath;
> +    HostBridgeIdx = DevPath->AcpiDevicePath.UID / (1<<16);
> +    RootBridgeIdx = DevPath->AcpiDevicePath.UID % (1<<16);
> +
> +    // Notify BSP Driver
> +    if (Ac01PcieHostBridgeNotifyPhase != NULL) {
> +      Ac01PcieHostBridgeNotifyPhase (HostBridgeIdx, RootBridgeIdx, Phase);
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  return ReturnStatus;
> +}
> +
> +/**
> +   Return the device handle of the next PCI root bridge that is associated with this Host Bridge.
> +
> +   This function is called multiple times to retrieve the device handles of all the PCI root bridges that
> +   are associated with this PCI host bridge. Each PCI host bridge is associated with one or more PCI
> +   root bridges. On each call, the handle that was returned by the previous call is passed into the
> +   interface, and on output the interface returns the device handle of the next PCI root bridge. The
> +   caller can use the handle to obtain the instance of the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +   for that root bridge. When there are no more PCI root bridges to report, the interface returns
> +   EFI_NOT_FOUND. A PCI enumerator must enumerate the PCI root bridges in the order that they
> +   are returned by this function.
> +   For D945 implementation, there is only one root bridge in PCI host bridge.
> +
> +   @param[in]       This              The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in, out]  RootBridgeHandle  Returns the device handle of the next PCI root bridge.
> +
> +   @retval EFI_SUCCESS            If parameter RootBridgeHandle = NULL, then return the first Rootbridge handle of the
> +                                  specific Host bridge and return EFI_SUCCESS.
> +   @retval EFI_NOT_FOUND          Can not find the any more root bridge in specific host bridge.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not an EFI_HANDLE that was
> +                                  returned on a previous call to GetNextRootBridge().
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetNextRootBridge (
> +  IN     EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN OUT EFI_HANDLE                                       *RootBridgeHandle
> +  )
> +{
> +  BOOLEAN                  NoRootBridge;
> +  LIST_ENTRY               *List;
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +
> +  NoRootBridge = TRUE;
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  while (List != &HostBridgeInstance->Head) {
> +    NoRootBridge = FALSE;
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +    if (*RootBridgeHandle == NULL) {
> +      //
> +      // Return the first Root Bridge Handle of the Host Bridge
> +      //
> +      *RootBridgeHandle = RootBridgeInstance->RootBridgeHandle;
> +
> +      return EFI_SUCCESS;
> +    } else {
> +      if (*RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +        //
> +        // Get next if have
> +        //
> +        List = List->ForwardLink;
> +
> +        if (List != &HostBridgeInstance->Head) {
> +          RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +          *RootBridgeHandle = RootBridgeInstance->RootBridgeHandle;
> +
> +          return EFI_SUCCESS;
> +        }
> +
> +        return EFI_NOT_FOUND;
> +      }
> +    }
> +
> +    List = List->ForwardLink;
> +  } // end while
> +
> +  return NoRootBridge ? EFI_NOT_FOUND : EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> +   Returns the allocation attributes of a PCI root bridge.
> +
> +   The function returns the allocation attributes of a specific PCI root bridge. The attributes can vary
> +   from one PCI root bridge to another. These attributes are different from the decode-related
> +   attributes that are returned by the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.GetAttributes() member function. The
> +   RootBridgeHandle parameter is used to specify the instance of the PCI root bridge. The device
> +   handles of all the root bridges that are associated with this host bridge must be obtained by calling
> +   GetNextRootBridge(). The attributes are static in the sense that they do not change during or
> +   after the enumeration process. The hardware may provide mechanisms to change the attributes on
> +   the fly, but such changes must be completed before EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL is
> +   installed. The permitted values of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTES are defined in
> +   "Related Definitions" below. The caller uses these attributes to combine multiple resource requests.
> +   For example, if the flag EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM is set, the PCI bus enumerator needs to
> +   include requests for the prefetchable memory in the nonprefetchable memory pool and not request any
> +   prefetchable memory.
> +      Attribute                                 Description
> +   ------------------------------------         ----------------------------------------------------------------------
> +   EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM         If this bit is set, then the PCI root bridge does not support separate
> +                                                windows for nonprefetchable and prefetchable memory. A PCI bus
> +                                                driver needs to include requests for prefetchable memory in the
> +                                                nonprefetchable memory pool.
> +
> +   EFI_PCI_HOST_BRIDGE_MEM64_DECODE             If this bit is set, then the PCI root bridge supports 64-bit memory
> +                                                windows. If this bit is not set, the PCI bus driver needs to include
> +                                                requests for a 64-bit memory address in the corresponding 32-bit
> +                                                memory pool.
> +
> +   @param[in]   This               The instance pointer of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
> +   @param[in]   RootBridgeHandle   The device handle of the PCI root bridge in which the caller is interested. Type
> +                                   EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param[out]  Attributes         The pointer to attribte of root bridge, it is output parameter
> +
> +   @retval EFI_INVALID_PARAMETER   Attribute pointer is NULL
> +   @retval EFI_INVALID_PARAMETER   RootBridgehandle is invalid.
> +   @retval EFI_SUCCESS             Success to get attribute of interested root bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetAttributes (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT UINT64                                           *Attributes
> +  )
> +{
> +  LIST_ENTRY               *List;
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +
> +  if (Attributes == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      *Attributes = RootBridgeInstance->RootBridgeAttrib;
> +
> +      return EFI_SUCCESS;
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  //
> +  // RootBridgeHandle is not an EFI_HANDLE
> +  // that was returned on a previous call to GetNextRootBridge()
> +  //
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> +   Sets up the specified PCI root bridge for the bus enumeration process.
> +
> +   This member function sets up the root bridge for bus enumeration and returns the PCI bus range
> +   over which the search should be performed in ACPI 2.0 resource descriptor format.
> +
> +   @param[in]   This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance.
> +   @param[in]   RootBridgeHandle  The PCI Root Bridge to be set up.
> +   @param[out]  Configuration     Pointer to the pointer to the PCI bus resource descriptor.
> +
> +   @retval EFI_INVALID_PARAMETER Invalid Root bridge's handle
> +   @retval EFI_OUT_OF_RESOURCES  Fail to allocate ACPI resource descriptor tag.
> +   @retval EFI_SUCCESS           Sucess to allocate ACPI resource descriptor.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +StartBusEnumeration (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT VOID                                             **Configuration
> +  )
> +{
> +  LIST_ENTRY               *List;
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +  VOID                     *Buffer;
> +  UINT8                    *Temp;
> +  UINT64                   BusStart;
> +  UINT64                   BusEnd;
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      //
> +      // Set up the Root Bridge for Bus Enumeration
> +      //
> +      BusStart = RootBridgeInstance->RootBridge.Bus.Base;
> +      BusEnd   = RootBridgeInstance->RootBridge.Bus.Limit;
> +
> +      Buffer = AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR));
> +      if (Buffer == NULL) {
> +        return EFI_OUT_OF_RESOURCES;
> +      }
> +
> +      Temp = (UINT8 *)Buffer;
> +
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->Len  = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->GenFlag = 0;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->SpecificFlag = 0;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrSpaceGranularity = 0;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMin = BusStart;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrRangeMax = BusEnd;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrTranslationOffset = 0;
> +      ((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp)->AddrLen = BusEnd - BusStart + 1;
> +
> +      Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
> +      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Desc = ACPI_END_TAG_DESCRIPTOR;
> +      ((EFI_ACPI_END_TAG_DESCRIPTOR *)Temp)->Checksum = 0x0;
> +
> +      *Configuration = Buffer;
> +
> +      return EFI_SUCCESS;
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> +   Programs the PCI root bridge hardware so that it decodes the specified PCI bus range.
> +
> +   This member function programs the specified PCI root bridge to decode the bus range that is
> +   specified by the input parameter Configuration.
> +   The bus range information is specified in terms of the ACPI 2.0 resource descriptor format.
> +
> +   @param[in] This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_ PROTOCOL instance
> +   @param[in] RootBridgeHandle  The PCI Root Bridge whose bus range is to be programmed
> +   @param[in] Configuration     The pointer to the PCI bus resource descriptor
> +
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not include a valid ACPI 2.0 bus resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration includes valid ACPI 2.0 resource descriptors other than
> +                                  bus descriptors.
> +   @retval EFI_INVALID_PARAMETER  Configuration contains one or more invalid ACPI resource descriptors.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Minimum" is invalid for this root bridge.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this root bridge.
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
> +   @retval EFI_SUCCESS            The bus range for the PCI root bridge was programmed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SetBusNumbers (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN VOID                                             *Configuration
> +  )
> +{
> +  LIST_ENTRY               *List;
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +  PCI_RES_NODE             *ResNode;
> +  UINT8                    *Ptr;
> +  UINTN                    BusStart;
> +  UINTN                    BusEnd;
> +  UINTN                    BusLen;
> +
> +  if (Configuration == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Ptr = Configuration;
> +
> +  //
> +  // Check the Configuration is valid
> +  //
> +  if (*Ptr != ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->ResType != ACPI_ADDRESS_SPACE_TYPE_BUS) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Ptr += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
> +  if (*Ptr != ACPI_END_TAG_DESCRIPTOR) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  Ptr = Configuration;
> +
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      BusStart = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrRangeMin;
> +      BusLen = (UINTN)((EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Ptr)->AddrLen;
> +      BusEnd = BusStart + BusLen - 1;
> +
> +      if (BusStart > BusEnd) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      if ((BusStart < RootBridgeInstance->RootBridge.Bus.Base) ||
> +          (BusEnd > RootBridgeInstance->RootBridge.Bus.Limit))
> +      {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      //
> +      // Update the Bus Range
> +      //
> +      ResNode = &(RootBridgeInstance->ResAllocNode[TypeBus]);
> +      ResNode->Base   = BusStart;
> +      ResNode->Length = BusLen;
> +      ResNode->Status = ResAllocated;
> +
> +      return EFI_SUCCESS;
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  return EFI_INVALID_PARAMETER;
> +}
> +
> +/**
> +   Submits the I/O and memory resource requirements for the specified PCI root bridge.
> +
> +   This function is used to submit all the I/O and memory resources that are required by the specified
> +   PCI root bridge. The input parameter Configuration is used to specify the following:
> +   - The various types of resources that are required
> +   - The associated lengths in terms of ACPI 2.0 resource descriptor format
> +
> +   @param[in] This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param[in] RootBridgeHandle  The PCI root bridge whose I/O and memory resource requirements are being submitted.
> +   @param[in] Configuration     The pointer to the PCI I/O and PCI memory resource descriptor.
> +
> +   @retval EFI_SUCCESS            The I/O and memory resource requests for a PCI root bridge were accepted.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER  Configuration is NULL.
> +   @retval EFI_INVALID_PARAMETER  Configuration does not point to a valid ACPI 2.0 resource descriptor.
> +   @retval EFI_INVALID_PARAMETER  Configuration includes requests for one or more resource types that are
> +                                  not supported by this PCI root bridge. This error will happen if the caller
> +                                  did not combine resources according to Attributes that were returned by
> +                                  GetAllocAttributes().
> +   @retval EFI_INVALID_PARAMETER  Address Range Maximum" is invalid.
> +   @retval EFI_INVALID_PARAMETER  "Address Range Length" is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  "Address Space Granularity" is invalid for this PCI root bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +SubmitResources (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN VOID                                             *Configuration
> +  )
> +{
> +  LIST_ENTRY                        *List;
> +  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance = NULL;
> +  PCI_RES_NODE                      *ResNode;
> +  UINT8                             *Temp;
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;
> +  UINTN                             Index = 0;
> +  UINTN                             AddrSpaceCnt = 0;
> +  UINTN                             i;
> +
> +  //
> +  // Check the input parameter: Configuration
> +  //
> +  if (Configuration == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  //
> +  // Input resource descriptor must end properly
> +  //
> +  Temp = (UINT8 *)Configuration;
> +  AddrSpaceCnt = 0;
> +  while (*Temp == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
> +    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
> +    AddrSpaceCnt++;
> +  }
> +  if (*Temp != ACPI_END_TAG_DESCRIPTOR) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Get the corresponding Root Bridge Instance
> +  //
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      break;
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  if (RootBridgeHandle != RootBridgeInstance->RootBridgeHandle) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PCIE_DEBUG ("%a: \n", __FUNCTION__);
> +
> +  Temp = (UINT8 *)Configuration;
> +  for (i = 0; i < AddrSpaceCnt; i++) {
> +    Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Temp;
> +
> +    PCIE_DEBUG ("Ptr->ResType:%d\n", Ptr->ResType);
> +    PCIE_DEBUG ("Ptr->Addrlen:0x%llx\n", Ptr->AddrLen);
> +    PCIE_DEBUG ("Ptr->AddrRangeMax:0x%llx\n", Ptr->AddrRangeMax);
> +    PCIE_DEBUG ("Ptr->AddrRangeMin:0x%llx\n", Ptr->AddrRangeMin);
> +    PCIE_DEBUG ("Ptr->SpecificFlag:0x%llx\n", Ptr->SpecificFlag);
> +    PCIE_DEBUG ("Ptr->AddrSpaceGranularity:%d\n", Ptr->AddrSpaceGranularity);
> +    PCIE_DEBUG ("RootBridgeInstance->RootBridgeAttrib:0x%llx\n", RootBridgeInstance->RootBridgeAttrib);
> +
> +    switch (Ptr->ResType) {
> +    case ACPI_ADDRESS_SPACE_TYPE_MEM:
> +
> +      if (Ptr->AddrSpaceGranularity != 32 && Ptr->AddrSpaceGranularity != 64) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      if (Ptr->AddrSpaceGranularity == 32) {
> +        if (Ptr->AddrLen >= SIZE_4GB) {
> +          return EFI_INVALID_PARAMETER;
> +        }
> +
> +        Index = (Ptr->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) ?
> +                TypePMem32 : TypeMem32;
> +      }
> +
> +      if (Ptr->AddrSpaceGranularity == 64) {
> +        Index = (Ptr->SpecificFlag & EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) ?
> +                TypePMem64 : TypeMem64;
> +      }
> +
> +      break;
> +
> +    case ACPI_ADDRESS_SPACE_TYPE_IO:
> +      //
> +      // Check address range alignment
> +      //
> +      if (Ptr->AddrRangeMax != (GetPowerOfTwo64 (Ptr->AddrRangeMax + 1) - 1)) {
> +        return EFI_INVALID_PARAMETER;
> +      }
> +
> +      Index = TypeIo;
> +      break;
> +
> +    case ACPI_ADDRESS_SPACE_TYPE_BUS:
> +    default:
> +      ASSERT (FALSE);
> +      break;
> +    }
> +
> +    ResNode = &(RootBridgeInstance->ResAllocNode[Index]);
> +    ResNode->Length  = Ptr->AddrLen;
> +    ResNode->Alignment = Ptr->AddrRangeMax;
> +    ResNode->Status  = ResSubmitted;
> +
> +    Temp += sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR);
> +  }
> +
> +  HostBridgeInstance->ResourceSubmited = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Returns the proposed resource settings for the specified PCI root bridge.
> +
> +   This member function returns the proposed resource settings for the specified PCI root bridge. The
> +   proposed resource settings are prepared when NotifyPhase() is called with a Phase of
> +   EfiPciHostBridgeAllocateResources. The output parameter Configuration
> +   specifies the following:
> +   - The various types of resources, excluding bus resources, that are allocated
> +   - The associated lengths in terms of ACPI 2.0 resource descriptor format
> +
> +   @param[in]  This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param[in]  RootBridgeHandle  The PCI root bridge handle. Type EFI_HANDLE is defined in InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param[out] Configuration     The pointer to the pointer to the PCI I/O and memory resource descriptor.
> +
> +   @retval EFI_SUCCESS            The requested parameters were returned.
> +   @retval EFI_INVALID_PARAMETER  RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_DEVICE_ERROR       Programming failed due to a hardware error.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetProposedResources (
> +  IN  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN  EFI_HANDLE                                       RootBridgeHandle,
> +  OUT VOID                                             **Configuration
> +  )
> +{
> +  LIST_ENTRY                        *List = NULL;
> +  PCI_HOST_BRIDGE_INSTANCE          *HostBridgeInstance = NULL;
> +  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance = NULL;
> +  UINTN                             Index = 0;
> +  VOID                              *Buffer = NULL;
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor = NULL;
> +  EFI_ACPI_END_TAG_DESCRIPTOR       *End = NULL;
> +  UINT64                            ResStatus;
> +
> +  Buffer = NULL;
> +
> +  PCIE_DEBUG ("%a: \n", __FUNCTION__);
> +
> +  //
> +  // Get the Host Bridge Instance from the resource allocation protocol
> +  //
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  //
> +  // Get the corresponding Root Bridge Instance
> +  //
> +  while (List != &HostBridgeInstance->Head) {
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      break;
> +    }
> +
> +    List = List->ForwardLink;
> +  }
> +
> +  if (RootBridgeHandle != RootBridgeInstance->RootBridgeHandle) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Buffer = AllocateZeroPool (
> +             (TypeMax - 1) * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) +
> +             sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
> +             );
> +  if (Buffer == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Buffer;
> +  for (Index = TypeIo; Index < TypeMax; Index++) {
> +    ResStatus = RootBridgeInstance->ResAllocNode[Index].Status;
> +
> +    switch (Index) {
> +    case TypeIo:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_IO;
> +      Descriptor->SpecificFlag         = 0;
> +      Descriptor->AddrSpaceGranularity = 32;
> +      break;
> +
> +    case TypeMem32:
> +    case TypePMem32:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->SpecificFlag         = (Index == TypeMem32) ? 0 :
> +                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrSpaceGranularity = 32;
> +      break;
> +
> +    case TypeMem64:
> +    case TypePMem64:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->SpecificFlag         = (Index == TypeMem64) ? 0 :
> +                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrSpaceGranularity = 64;
> +      break;
> +
> +    default:
> +      continue;
> +    }
> +
> +    Descriptor->Desc                  = ACPI_ADDRESS_SPACE_DESCRIPTOR;
> +    Descriptor->Len                   = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
> +    Descriptor->GenFlag               = 0;
> +    Descriptor->AddrRangeMin          = RootBridgeInstance->ResAllocNode[Index].Base;
> +    Descriptor->AddrLen               = RootBridgeInstance->ResAllocNode[Index].Length;
> +    Descriptor->AddrRangeMax          = Descriptor->AddrRangeMin + Descriptor->AddrLen - 1;
> +    Descriptor->AddrTranslationOffset = (ResStatus == ResAllocated) ? EFI_RESOURCE_SATISFIED : PCI_RESOURCE_LESS;
> +
> +    PCIE_DEBUG ("Descriptor->ResType:%d\n", Descriptor->ResType);
> +    PCIE_DEBUG ("Descriptor->Addrlen:%llx\n", Descriptor->AddrLen);
> +    PCIE_DEBUG ("Descriptor->AddrRangeMax:%llx\n", Descriptor->AddrRangeMax);
> +    PCIE_DEBUG ("Descriptor->AddrRangeMin:%llx\n", Descriptor->AddrRangeMin);
> +    PCIE_DEBUG ("Descriptor->SpecificFlag:%llx\n", Descriptor->SpecificFlag);
> +    PCIE_DEBUG ("Descriptor->AddrTranslationOffset:%d\n", Descriptor->AddrTranslationOffset);
> +    PCIE_DEBUG ("Descriptor->AddrSpaceGranularity:%d\n", Descriptor->AddrSpaceGranularity);
> +
> +    Descriptor++;
> +  }
> +
> +  //
> +  // Terminate the entries.
> +  //
> +  End = (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor;
> +  End->Desc      = ACPI_END_TAG_DESCRIPTOR;
> +  End->Checksum  = 0x0;
> +
> +  *Configuration = Buffer;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Provides the hooks from the PCI bus driver to every PCI controller (device/function) at various
> +   stages of the PCI enumeration process that allow the host bridge driver to preinitialize individual
> +   PCI controllers before enumeration.
> +
> +   This function is called during the PCI enumeration process. No specific action is expected from this
> +   member function. It allows the host bridge driver to preinitialize individual PCI controllers before
> +   enumeration.
> +
> +   @param This              Pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
> +   @param RootBridgeHandle  The associated PCI root bridge handle. Type EFI_HANDLE is defined in
> +                            InstallProtocolInterface() in the UEFI 2.0 Specification.
> +   @param PciAddress        The address of the PCI device on the PCI bus. This address can be passed to the
> +                            EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL member functions to access the PCI
> +                            configuration space of the device. See Table 12-1 in the UEFI 2.0 Specification for
> +                            the definition of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS.
> +   @param Phase             The phase of the PCI device enumeration.
> +
> +   @retval EFI_SUCCESS              The requested parameters were returned.
> +   @retval EFI_INVALID_PARAMETER    RootBridgeHandle is not a valid root bridge handle.
> +   @retval EFI_INVALID_PARAMETER    Phase is not a valid phase that is defined in
> +                                    EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE.
> +   @retval EFI_DEVICE_ERROR         Programming failed due to a hardware error. The PCI enumerator should
> +                                    not enumerate this device, including its child devices if it is a PCI-to-PCI
> +                                    bridge.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +PreprocessController (
> +  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
> +  IN EFI_HANDLE                                       RootBridgeHandle,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS      PciAddress,
> +  IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE     Phase
> +  )
> +{
> +  PCI_HOST_BRIDGE_INSTANCE *HostBridgeInstance;
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +  LIST_ENTRY               *List;
> +
> +  HostBridgeInstance = PCI_HOST_BRIDGE_FROM_THIS (This);
> +  List = HostBridgeInstance->Head.ForwardLink;
> +
> +  //
> +  // Enumerate the root bridges in this host bridge
> +  //
> +  while (List != &HostBridgeInstance->Head) {
> +
> +    RootBridgeInstance = ROOT_BRIDGE_FROM_LINK (List);
> +    if (RootBridgeHandle == RootBridgeInstance->RootBridgeHandle) {
> +      break;
> +    }
> +    List = List->ForwardLink;
> +  }
> +
> +  if (List == &HostBridgeInstance->Head) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if ((UINT32)Phase > EfiPciBeforeResourceCollection) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> new file mode 100644
> index 000000000000..552a5f6de4c6
> --- /dev/null
> +++ b/Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciRootBridgeIo.c
> @@ -0,0 +1,1582 @@
> +/** @file
> +
> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
> +
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +
> +#include <IndustryStandard/Pci.h>
> +#include <Library/ArmLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/PcieCoreLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/PciHostBridgeLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/TimerLib.h>
> +#include <Library/UefiLib.h>
> +
> +#include "PciHostBridge.h"
> +#include "PciRootBridgeIo.h"
> +
> +//
> +// Memory Controller Pci Root Bridge Io Module Variables
> +//
> +EFI_METRONOME_ARCH_PROTOCOL *mMetronome = NULL;
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +UINT8 mInStride[] = {
> +  1, // EfiPciWidthUint8
> +  2, // EfiPciWidthUint16
> +  4, // EfiPciWidthUint32
> +  8, // EfiPciWidthUint64
> +  0, // EfiPciWidthFifoUint8
> +  0, // EfiPciWidthFifoUint16
> +  0, // EfiPciWidthFifoUint32
> +  0, // EfiPciWidthFifoUint64
> +  1, // EfiPciWidthFillUint8
> +  2, // EfiPciWidthFillUint16
> +  4, // EfiPciWidthFillUint32
> +  8  // EfiPciWidthFillUint64
> +};
> +
> +//
> +// Lookup table for increment values based on transfer widths
> +//
> +UINT8 mOutStride[] = {
> +  1, // EfiPciWidthUint8
> +  2, // EfiPciWidthUint16
> +  4, // EfiPciWidthUint32
> +  8, // EfiPciWidthUint64
> +  1, // EfiPciWidthFifoUint8
> +  2, // EfiPciWidthFifoUint16
> +  4, // EfiPciWidthFifoUint32
> +  8, // EfiPciWidthFifoUint64
> +  0, // EfiPciWidthFillUint8
> +  0, // EfiPciWidthFillUint16
> +  0, // EfiPciWidthFillUint32
> +  0  // EfiPciWidthFillUint64
> +};
> +
> +/**
> +  Check parameters for IO, MMIO, PCI read/write services of PCI Root Bridge IO.
> +
> +  The I/O operations are carried out exactly as requested. The caller is
> +  responsible for satisfying any alignment and I/O width restrictions that a PI
> +  System on a platform might require. For example on some platforms, width
> +  requests of EfiCpuIoWidthUint64 do not work. Misaligned buffers, on the other
> +  hand, will be handled by the driver.
> +
> +  @param[in] This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +
> +  @param[in] OperationType  I/O operation type: IO/MMIO/PCI.
> +
> +  @param[in] Width          Signifies the width of the I/O or Memory operation.
> +
> +  @param[in] Address        The base address of the I/O operation.
> +
> +  @param[in] Count          The number of I/O operations to perform. The number
> +                            of bytes moved is Width size * Count, starting at
> +                            Address.
> +
> +  @param[in] Buffer         For read operations, the destination buffer to
> +                            store the results. For write operations, the source
> +                            buffer from which to write data.
> +
> +  @retval EFI_SUCCESS            The parameters for this request pass the
> +                                 checks.
> +
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PI system.
> +
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +
> +  @retval EFI_UNSUPPORTED        The Buffer is not aligned for the given Width.
> +
> +  @retval EFI_UNSUPPORTED        The address range specified by Address, Width,
> +                                 and Count is not valid for this PI system.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoCheckParameter (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN OPERATION_TYPE                        OperationType,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                Address,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *Buffer
> +  )
> +{
> +  PCI_ROOT_BRIDGE_INSTANCE                    *RootBridgeInstance;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
> +  UINT64                                      MaxCount;
> +  UINT64                                      Base = 0;
> +  UINT64                                      Limit = 0;
> +  UINT32                                      Size;
> +
> +  //
> +  // Check to see if Buffer is NULL
> +  //
> +  if (Buffer == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Check to see if Width is in the valid range
> +  //
> +  if ((UINT32)Width >= EfiPciWidthMaximum) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // For FIFO type, the target address won't increase during the access,
> +  // so treat Count as 1
> +  //
> +  if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) {
> +    Count = 1;
> +  }
> +
> +  //
> +  // Check to see if Width is in the valid range for I/O Port operations
> +  //
> +  Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
> +  Size  = 1 << Width;
> +
> +  //
> +  // Config space accessing does not support 64-bit width
> +  //
> +  if ((OperationType == PciOperation) && (Width == EfiPciWidthUint64)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  //
> +  // Check to see if any address associated with this transfer exceeds the
> +  // maximum allowed address.  The maximum address implied by the parameters
> +  // passed in is Address + Size * Count.  If the following condition is met,
> +  // then the transfer is not supported.
> +  //
> +  //    Address + Size * Count > Limit + 1
> +  //
> +  // Since Limit can be the maximum integer value supported by the CPU and
> +  // Count can also be the maximum integer value supported by the CPU, this
> +  // range check must be adjusted to avoid all oveflow conditions.
> +  //
> +  if (OperationType == IoOperation) {
> +    if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.Io.Limit + 1) {
> +      Base = RootBridgeInstance->RootBridge.Io.Base;
> +      Limit = RootBridgeInstance->RootBridge.Io.Limit;
> +    }
> +  } else if (OperationType == MemOperation) {
> +    if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.Mem.Limit + 1) {
> +      Base = RootBridgeInstance->RootBridge.Mem.Base;
> +      Limit = RootBridgeInstance->RootBridge.Mem.Limit;
> +    } else if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.PMem.Limit + 1) {
> +      Base = RootBridgeInstance->RootBridge.PMem.Base;
> +      Limit = RootBridgeInstance->RootBridge.PMem.Limit;
> +    } else if (Address + MultU64x32 (Count, Size) <= RootBridgeInstance->RootBridge.MemAbove4G.Limit + 1) {
> +      Base = RootBridgeInstance->RootBridge.MemAbove4G.Base;
> +      Limit = RootBridgeInstance->RootBridge.MemAbove4G.Limit;
> +    } else {
> +      Base = RootBridgeInstance->RootBridge.PMemAbove4G.Base;
> +      Limit = RootBridgeInstance->RootBridge.PMemAbove4G.Limit;
> +    }
> +  } else {
> +    PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;
> +    if (PciRbAddr->Bus < RootBridgeInstance->RootBridge.Bus.Base ||
> +        PciRbAddr->Bus > RootBridgeInstance->RootBridge.Bus.Limit)
> +    {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    if (PciRbAddr->Device > PCI_MAX_DEVICE ||
> +        PciRbAddr->Function > PCI_MAX_FUNC)
> +    {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +
> +    Address = (PciRbAddr->ExtendedRegister != 0) ?
> +              PciRbAddr->ExtendedRegister :
> +              PciRbAddr->Register;
> +
> +    Base = 0;
> +    Limit = RootBridgeInstance->RootBridge.NoExtendedConfigSpace ? 0xFF : 0xFFF;
> +  }
> +
> +  //
> +  // Check to see if Address is aligned
> +  // ( Address is derived from  Extended register/Register.
> +  //   Now we can safely check the alignments )
> +  //
> +  if ((Address & (UINT64)(mInStride[Width] - 1)) != 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  if (Address < Base) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (Count == 0) {
> +    if (Address > Limit) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  } else {
> +    MaxCount = RShiftU64 (Limit, Width);
> +    if (MaxCount < (Count - 1)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +    if (Address > LShiftU64 (MaxCount - Count + 1, Width)) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Internal help function for read and write memory space.
> +
> +   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Write         Switch value for Read or Write.
> +   @param[in]   Width         Signifies the width of the memory operations.
> +   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
> +   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
> +                              moved is Width size * Count, starting at Address.
> +   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
> +                              write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMemRW (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN     BOOLEAN                               Write,
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN     UINT64                                Address,
> +  IN     UINTN                                 Count,
> +  IN OUT VOID                                  *Buffer
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  UINT8                                 InStride;
> +  UINT8                                 OutStride;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
> +  UINT8                                 *Uint8Buffer;
> +
> +  PCIE_MMIO_DEBUG (
> +    "%a: W: %d, Width: %d, Addr: 0x%lx, Count: %d\n",
> +    __FUNCTION__,
> +    Write,
> +    Width,
> +    Address,
> +    Count
> +    );
> +
> +  Status = RootBridgeIoCheckParameter (This, MemOperation, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
> +
> +  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (Write) {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> +        break;
> +
> +      case EfiPciWidthUint64:
> +        MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    } else {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        *Uint8Buffer = MmioRead8 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint64:
> +        *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Internal help function for read and write IO space.
> +
> +   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Write         Switch value for Read or Write.
> +   @param[in]   Width         Signifies the width of the memory operations.
> +   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
> +   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
> +                              moved is Width size * Count, starting at Address.
> +   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
> +                              write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoIoRW (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN     BOOLEAN                               Write,
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN     UINT64                                Address,
> +  IN     UINTN                                 Count,
> +  IN OUT VOID                                  *Buffer
> +  )
> +{
> +  EFI_STATUS                            Status;
> +  UINT8                                 InStride;
> +  UINT8                                 OutStride;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH OperationWidth;
> +  UINT8                                 *Uint8Buffer;
> +
> +  PCIE_MMIO_DEBUG (
> +    "%a: W: %d, Width: %d, Addr: 0x%lx, Count: %d\n",
> +    __FUNCTION__,
> +    Write,
> +    Width,
> +    Address,
> +    Count
> +    );
> +
> +  Status = RootBridgeIoCheckParameter (This, IoOperation, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  InStride = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
> +
> +  for (Uint8Buffer = Buffer; Count > 0; Address += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (Write) {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        MmioWrite8 ((UINTN)Address, *Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        MmioWrite16 ((UINTN)Address, *((UINT16 *)Uint8Buffer));
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        MmioWrite32 ((UINTN)Address, *((UINT32 *)Uint8Buffer));
> +        break;
> +
> +      case EfiPciWidthUint64:
> +        MmioWrite64 ((UINTN)Address, *((UINT64 *)Uint8Buffer));
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    } else {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        *Uint8Buffer = MmioRead8 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        *((UINT16 *)Uint8Buffer) = MmioRead16 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        *((UINT32 *)Uint8Buffer) = MmioRead32 ((UINTN)Address);
> +        break;
> +
> +      case EfiPciWidthUint64:
> +        *((UINT64 *)Uint8Buffer) = MmioRead64 ((UINTN)Address);
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +   Internal help function for read and write PCI configuration space.
> +
> +   @param[in]   This          A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +   @param[in]   Write         Switch value for Read or Write.
> +   @param[in]   Width         Signifies the width of the memory operations.
> +   @param[in]   UserAddress   The address within the PCI configuration space for the PCI controller.
> +   @param[in]   Count         The number of PCI configuration operations to perform. Bytes
> +                              moved is Width size * Count, starting at Address.
> +   @param[in, out] UserBuffer For read operations, the destination buffer to store the results. For
> +                              write operations, the source buffer to write data from.
> +
> +   @retval EFI_SUCCESS            The data was read from or written to the PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +   @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +   @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a lack of resources.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPciRW (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN     BOOLEAN                               Write,
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN     UINT64                                Address,
> +  IN     UINTN                                 Count,
> +  IN OUT VOID                                  *Buffer
> +  )
> +{
> +  EFI_STATUS                                  Status;
> +  UINT8                                       InStride;
> +  UINT8                                       OutStride;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH       OperationWidth;
> +  UINT8                                       *Uint8Buffer;
> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *PciRbAddr;
> +  UINTN                                       PcieRegAddr;
> +  PCI_ROOT_BRIDGE_INSTANCE                    *RootBridgeInstance;
> +
> +  OperationWidth = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
> +  PciRbAddr = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS *)&Address;
> +
> +  Status = RootBridgeIoCheckParameter (This, PciOperation, Width, Address, Count, Buffer);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  PcieRegAddr = (UINTN)PCI_LIB_ADDRESS (
> +                         PciRbAddr->Bus,
> +                         PciRbAddr->Device,
> +                         PciRbAddr->Function,
> +                         (PciRbAddr->ExtendedRegister != 0) ? PciRbAddr->ExtendedRegister : PciRbAddr->Register
> +                         );
> +
> +  //
> +  // Select loop based on the width of the transfer
> +  //
> +  InStride  = mInStride[Width];
> +  OutStride = mOutStride[Width];
> +
> +  for (Uint8Buffer = Buffer; Count > 0; PcieRegAddr += InStride, Uint8Buffer += OutStride, Count--) {
> +    if (Write) {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 1, Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 2, Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, TRUE, 4, Uint8Buffer);
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    } else {
> +      switch (OperationWidth) {
> +      case EfiPciWidthUint8:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 1, Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint16:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 2, Uint8Buffer);
> +        break;
> +
> +      case EfiPciWidthUint32:
> +        Ac01PcieConfigRW ((VOID *)&RootBridgeInstance->RootBridge, PcieRegAddr, FALSE, 4, Uint8Buffer);
> +        break;
> +
> +      default:
> +        //
> +        // The RootBridgeIoCheckParameter call above will ensure that this
> +        // path is not taken.
> +        //
> +        ASSERT (FALSE);
> +        break;
> +      }
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Polls an address in memory mapped I/O space until an exit condition is met,
> +  or a timeout occurs.
> +
> +  This function provides a standard way to poll a PCI memory location. A PCI
> +  memory read operation is performed at the PCI memory address specified by
> +  Address for the width specified by Width. The result of this PCI memory read
> +  operation is stored in Result. This PCI memory read operation is repeated
> +  until either a timeout of Delay 100 ns units has expired, or (Result & Mask)
> +  is equal to Value.
> +
> +  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in]   Width     Signifies the width of the memory operations.
> +  @param[in]   Address   The base address of the memory operations. The caller
> +                         is responsible for aligning Address if required.
> +  @param[in]   Mask      Mask used for the polling criteria. Bytes above Width
> +                         in Mask are ignored. The bits in the bytes below Width
> +                         which are zero in Mask are ignored when polling the
> +                         memory address.
> +  @param[in]   Value     The comparison value used for the polling exit
> +                         criteria.
> +  @param[in]   Delay     The number of 100 ns units to poll. Note that timer
> +                         available may be of poorer granularity.
> +  @param[out]  Result    Pointer to the last value read from the memory
> +                         location.
> +
> +  @retval EFI_SUCCESS            The last data returned from the access matched
> +                                 the poll exit criteria.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid.
> +  @retval EFI_INVALID_PARAMETER  Result is NULL.
> +  @retval EFI_TIMEOUT            Delay expired before a match occurred.
> +  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
> +                                 lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPollMem (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINT64                                Mask,
> +  IN  UINT64                                Value,
> +  IN  UINT64                                Delay,
> +  OUT UINT64                                *Result
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT64     NumberOfTicks;
> +  UINT32     Remainder;
> +
> +  if (Result == NULL || (UINT32)Width > EfiPciWidthUint64) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // No matter what, always do a single poll.
> +  //
> +  Status = This->Mem.Read (This, Width, Address, 1, Result);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if ((*Result & Mask) == Value) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Delay == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (mMetronome == NULL) {
> +    Status = gBS->LocateProtocol (
> +                    &gEfiMetronomeArchProtocolGuid,
> +                    NULL,
> +                    (VOID **)&mMetronome
> +                    );
> +    if (EFI_ERROR (Status)) {
> +      return EFI_OUT_OF_RESOURCES;
> +    }
> +  }
> +
> +  //
> +  // Determine the proper # of metronome ticks to wait for polling the
> +  // location.  The nuber of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
> +  // The "+1" to account for the possibility of the first tick being short
> +  // because we started in the middle of a tick.
> +  //
> +  // BugBug: overriding mMetronome->TickPeriod with UINT32 until Metronome
> +  // protocol definition is updated.
> +  //
> +  NumberOfTicks = DivU64x32Remainder (
> +                    Delay,
> +                    (UINT32)mMetronome->TickPeriod,
> +                    &Remainder
> +                    );
> +  if (Remainder != 0) {
> +    NumberOfTicks += 1;
> +  }
> +  NumberOfTicks += 1;
> +
> +  while (NumberOfTicks != 0) {
> +
> +    mMetronome->WaitForTick (mMetronome, 1);
> +
> +    Status = This->Mem.Read (This, Width, Address, 1, Result);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    if ((*Result & Mask) == Value) {
> +      return EFI_SUCCESS;
> +    }
> +
> +    NumberOfTicks -= 1;
> +  }
> +
> +  return EFI_TIMEOUT;
> +}
> +
> +/**
> +  Reads from the I/O space of a PCI Root Bridge. Returns when either the
> +  polling exit criteria is satisfied or after a defined duration.
> +
> +  This function provides a standard way to poll a PCI I/O location. A PCI I/O
> +  read operation is performed at the PCI I/O address specified by Address for
> +  the width specified by Width.
> +  The result of this PCI I/O read operation is stored in Result. This PCI I/O
> +  read operation is repeated until either a timeout of Delay 100 ns units has
> +  expired, or (Result & Mask) is equal to Value.
> +
> +  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in] Width     Signifies the width of the I/O operations.
> +  @param[in] Address   The base address of the I/O operations. The caller is
> +                       responsible for aligning Address if required.
> +  @param[in] Mask      Mask used for the polling criteria. Bytes above Width in
> +                       Mask are ignored. The bits in the bytes below Width
> +                       which are zero in Mask are ignored when polling the I/O
> +                       address.
> +  @param[in] Value     The comparison value used for the polling exit criteria.
> +  @param[in] Delay     The number of 100 ns units to poll. Note that timer
> +                       available may be of poorer granularity.
> +  @param[out] Result   Pointer to the last value read from the memory location.
> +
> +  @retval EFI_SUCCESS            The last data returned from the access matched
> +                                 the poll exit criteria.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid.
> +  @retval EFI_INVALID_PARAMETER  Result is NULL.
> +  @retval EFI_TIMEOUT            Delay expired before a match occurred.
> +  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
> +                                 lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPollIo (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINT64                                Mask,
> +  IN  UINT64                                Value,
> +  IN  UINT64                                Delay,
> +  OUT UINT64                                *Result
> +  )
> +{
> +  EFI_STATUS Status;
> +  UINT64     NumberOfTicks;
> +  UINT32     Remainder;
> +
> +  //
> +  // No matter what, always do a single poll.
> +  //
> +
> +  if (Result == NULL || (UINT32)Width > EfiPciWidthUint64) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  Status = This->Io.Read (This, Width, Address, 1, Result);
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  if ((*Result & Mask) == Value) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (Delay == 0) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  //
> +  // Determine the proper # of metronome ticks to wait for polling the
> +  // location.  The number of ticks is Roundup (Delay / mMetronome->TickPeriod)+1
> +  // The "+1" to account for the possibility of the first tick being short
> +  // because we started in the middle of a tick.
> +  //
> +  NumberOfTicks = DivU64x32Remainder (
> +                    Delay,
> +                    (UINT32)mMetronome->TickPeriod,
> +                    &Remainder
> +                    );
> +  if (Remainder != 0) {
> +    NumberOfTicks += 1;
> +  }
> +  NumberOfTicks += 1;
> +
> +  while (NumberOfTicks != 0) {
> +
> +    mMetronome->WaitForTick (mMetronome, 1);
> +
> +    Status = This->Io.Read (This, Width, Address, 1, Result);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    if ((*Result & Mask) == Value) {
> +      return EFI_SUCCESS;
> +    }
> +
> +    NumberOfTicks -= 1;
> +  }
> +  return EFI_TIMEOUT;
> +}
> +
> +/**
> +  Enables a PCI driver to access PCI controller registers in the PCI root
> +  bridge memory space.
> +
> +  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
> +  controller registers in the PCI root bridge memory space.
> +  The memory operations are carried out exactly as requested. The caller is
> +  responsible for satisfying any alignment and memory width restrictions that a
> +  PCI Root Bridge on a platform might require.
> +
> +  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in]   Width     Signifies the width of the memory operation.
> +  @param[in]   Address   The base address of the memory operation. The caller
> +                         is responsible for aligning the Address if required.
> +  @param[in]   Count     The number of memory operations to perform. Bytes
> +                         moved is Width size * Count, starting at Address.
> +  @param[out]  Buffer    For read operations, the destination buffer to store
> +                         the results. For write operations, the source buffer
> +                         to write data from.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PCI
> +                                 root bridge.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
> +                                 lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMemRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoMemRW (This, FALSE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Enables a PCI driver to access PCI controller registers in the PCI root
> +  bridge memory space.
> +
> +  The Mem.Read(), and Mem.Write() functions enable a driver to access PCI
> +  controller registers in the PCI root bridge memory space.
> +  The memory operations are carried out exactly as requested. The caller is
> +  responsible for satisfying any alignment and memory width restrictions that a
> +  PCI Root Bridge on a platform might require.
> +
> +  @param[in]   This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in]   Width     Signifies the width of the memory operation.
> +  @param[in]   Address   The base address of the memory operation. The caller
> +                         is responsible for aligning the Address if required.
> +  @param[in]   Count     The number of memory operations to perform. Bytes
> +                         moved is Width size * Count, starting at Address.
> +  @param[in]   Buffer    For read operations, the destination buffer to store
> +                         the results. For write operations, the source buffer
> +                         to write data from.
> +
> +  @retval EFI_SUCCESS            The data was read from or written to the PCI
> +                                 root bridge.
> +  @retval EFI_INVALID_PARAMETER  Width is invalid for this PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER  Buffer is NULL.
> +  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to a
> +                                 lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMemWrite (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                Address,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoMemRW (This, TRUE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Enables a PCI driver to access PCI controller registers in the PCI root
> +  bridge I/O space.
> +
> +  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in]   Width       Signifies the width of the memory operations.
> +  @param[in]   Address     The base address of the I/O operation. The caller is
> +                           responsible for aligning the Address if required.
> +  @param[in]   Count       The number of I/O operations to perform. Bytes moved
> +                           is Width size * Count, starting at Address.
> +  @param[out]  Buffer      For read operations, the destination buffer to store
> +                           the results. For write operations, the source buffer
> +                           to write data from.
> +
> +  @retval EFI_SUCCESS              The data was read from or written to the PCI
> +                                   root bridge.
> +  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER    Buffer is NULL.
> +  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a
> +                                   lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoIoRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoIoRW (This, FALSE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Enables a PCI driver to access PCI controller registers in the PCI root
> +  bridge I/O space.
> +
> +  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in]   Width       Signifies the width of the memory operations.
> +  @param[in]   Address     The base address of the I/O operation. The caller is
> +                           responsible for aligning the Address if required.
> +  @param[in]   Count       The number of I/O operations to perform. Bytes moved
> +                           is Width size * Count, starting at Address.
> +  @param[in]   Buffer      For read operations, the destination buffer to store
> +                           the results. For write operations, the source buffer
> +                           to write data from.
> +
> +  @retval EFI_SUCCESS              The data was read from or written to the PCI
> +                                   root bridge.
> +  @retval EFI_INVALID_PARAMETER    Width is invalid for this PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER    Buffer is NULL.
> +  @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a
> +                                   lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoIoWrite (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                Address,
> +  IN UINTN                                 Count,
> +  IN VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoIoRW (This, TRUE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Enables a PCI driver to copy one region of PCI root bridge memory space to
> +  another region of PCI root bridge memory space.
> +
> +  The CopyMem() function enables a PCI driver to copy one region of PCI root
> +  bridge memory space to another region of PCI root bridge memory space. This
> +  is especially useful for video scroll operation on a memory mapped video
> +  buffer.
> +  The memory operations are carried out exactly as requested. The caller is
> +  responsible for satisfying any alignment and memory width restrictions that a
> +  PCI root bridge on a platform might require.
> +
> +  @param[in] This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +                         instance.
> +  @param[in] Width       Signifies the width of the memory operations.
> +  @param[in] DestAddress The destination address of the memory operation. The
> +                         caller is responsible for aligning the DestAddress if
> +                         required.
> +  @param[in] SrcAddress  The source address of the memory operation. The caller
> +                         is responsible for aligning the SrcAddress if
> +                         required.
> +  @param[in] Count       The number of memory operations to perform. Bytes
> +                         moved is Width size * Count, starting at DestAddress
> +                         and SrcAddress.
> +
> +  @retval  EFI_SUCCESS             The data was copied from one memory region
> +                                   to another memory region.
> +  @retval  EFI_INVALID_PARAMETER   Width is invalid for this PCI root bridge.
> +  @retval  EFI_OUT_OF_RESOURCES    The request could not be completed due to a
> +                                   lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoCopyMem (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN UINT64                                DestAddress,
> +  IN UINT64                                SrcAddress,
> +  IN UINTN                                 Count
> +  )
> +{
> +  EFI_STATUS Status;
> +  BOOLEAN    Direction;
> +  UINTN      Stride;
> +  UINTN      Index;
> +  UINT64     Result;
> +
> +  if ((UINTN)Width > (UINTN)EfiPciWidthUint64) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  if (DestAddress == SrcAddress) {
> +    return EFI_SUCCESS;
> +  }
> +
> +  Stride = (UINTN)(1 << Width);
> +
> +  Direction = TRUE;
> +  if ((DestAddress > SrcAddress) &&
> +      (DestAddress < (SrcAddress + Count * Stride)))
> +  {
> +    Direction   = FALSE;
> +    SrcAddress  = SrcAddress  + (Count - 1) * Stride;
> +    DestAddress = DestAddress + (Count - 1) * Stride;
> +  }
> +
> +  for (Index = 0; Index < Count; Index++) {
> +
> +    Status = RootBridgeIoMemRead (This, Width, SrcAddress, 1, &Result);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    Status = RootBridgeIoMemWrite (This, Width, DestAddress, 1, &Result);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
> +    }
> +
> +    if (Direction) {
> +      SrcAddress  += Stride;
> +      DestAddress += Stride;
> +    } else {
> +      SrcAddress  -= Stride;
> +      DestAddress -= Stride;
> +    }
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Allows read from PCI configuration space.
> +
> +  @param This     A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +  @param Width    Signifies the width of the memory operation.
> +  @param Address  The address within the PCI configuration space
> +                  for the PCI controller.
> +  @param Count    The number of PCI configuration operations
> +                  to perform.
> +  @param Buffer   The destination buffer to store the results.
> +
> +  @retval EFI_SUCCESS           The data was read from the PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER Invalid parameters found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPciRead (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN  UINT64                                Address,
> +  IN  UINTN                                 Count,
> +  OUT VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoPciRW (This, FALSE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Allows write to PCI configuration space.
> +
> +  @param This     A pointer to EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
> +  @param Width    Signifies the width of the memory operation.
> +  @param Address  The address within the PCI configuration space
> +                  for the PCI controller.
> +  @param Count    The number of PCI configuration operations
> +                  to perform.
> +  @param Buffer   The source buffer to get the results.
> +
> +  @retval EFI_SUCCESS            The data was written to the PCI root bridge.
> +  @retval EFI_INVALID_PARAMETER  Invalid parameters found.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoPciWrite (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL       *This,
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
> +  IN     UINT64                                Address,
> +  IN     UINTN                                 Count,
> +  IN OUT VOID                                  *Buffer
> +  )
> +{
> +  return RootBridgeIoPciRW (This, TRUE, Width, Address, Count, Buffer);
> +}
> +
> +/**
> +  Provides the PCI controller-specific address needed to access
> +  system memory for DMA.
> +
> +  @param This           A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param Operation      Indicate if the bus master is going to read or write
> +                        to system memory.
> +  @param HostAddress    The system memory address to map on the PCI controller.
> +  @param NumberOfBytes  On input the number of bytes to map.
> +                        On output the number of bytes that were mapped.
> +  @param DeviceAddress  The resulting map address for the bus master PCI
> +                        controller to use to access the system memory's HostAddress.
> +  @param Mapping        The value to pass to Unmap() when the bus master DMA
> +                        operation is complete.
> +
> +  @retval EFI_SUCCESS            Success.
> +  @retval EFI_INVALID_PARAMETER  Invalid parameters found.
> +  @retval EFI_UNSUPPORTED        The HostAddress cannot be mapped as a common buffer.
> +  @retval EFI_DEVICE_ERROR       The System hardware could not map the requested address.
> +  @retval EFI_OUT_OF_RESOURCES   The request could not be completed due to lack of resources.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoMap (
> +  IN      EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL           *This,
> +  IN      EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
> +  IN      VOID                                      *HostAddress,
> +  IN  OUT UINTN                                     *NumberOfBytes,
> +  OUT     EFI_PHYSICAL_ADDRESS                      *DeviceAddress,
> +  OUT     VOID                                      **Mapping
> +  )
> +{
> +  EFI_PHYSICAL_ADDRESS PhysicalAddress;
> +
> +  if (HostAddress == NULL || NumberOfBytes == NULL ||
> +      DeviceAddress == NULL || Mapping == NULL)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Initialize the return values to their defaults
> +  //
> +  *Mapping = NULL;
> +
> +  //
> +  // Make sure that Operation is valid
> +  //
> +  if ((UINT32)Operation >= EfiPciOperationMaximum) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress;
> +  //
> +  // The transfer is below 4GB, so the DeviceAddress is simply the HostAddress
> +  //
> +  *DeviceAddress = PhysicalAddress;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Completes the Map() operation and releases any corresponding resources.
> +
> +  The Unmap() function completes the Map() operation and releases any
> +  corresponding resources.
> +  If the operation was an EfiPciOperationBusMasterWrite or
> +  EfiPciOperationBusMasterWrite64, the data is committed to the target system
> +  memory.
> +  Any resources used for the mapping are freed.
> +
> +  @param[in] This      A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[in] Mapping   The mapping value returned from Map().
> +
> +  @retval EFI_SUCCESS            The range was unmapped.
> +  @retval EFI_INVALID_PARAMETER  Mapping is not a value that was returned by Map().
> +  @retval EFI_DEVICE_ERROR       The data was not committed to the target system memory.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoUnmap (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN VOID                            *Mapping
> +  )
> +{
> +  MAP_INFO *MapInfo;
> +
> +  //
> +  // See if the Map() operation associated with this Unmap() required a mapping buffer.
> +  // If a mapping buffer was not required, then this function simply returns EFI_SUCCESS.
> +  //
> +  if (Mapping != NULL) {
> +    //
> +    // Get the MAP_INFO structure from Mapping
> +    //
> +    MapInfo = (MAP_INFO *)Mapping;
> +
> +    //
> +    // If this is a write operation from the Bus Master's point of view,
> +    // then copy the contents of the mapped buffer into the real buffer
> +    // so the processor can read the contents of the real buffer.
> +    //
> +    if (MapInfo->Operation == EfiPciOperationBusMasterWrite ||
> +        MapInfo->Operation == EfiPciOperationBusMasterWrite64)
> +    {
> +      CopyMem (
> +        (VOID *)(UINTN)MapInfo->HostAddress,
> +        (VOID *)(UINTN)MapInfo->MappedHostAddress,
> +        MapInfo->NumberOfBytes
> +        );
> +    }
> +
> +    //
> +    // Free the mapped buffer and the MAP_INFO structure.
> +    //
> +    gBS->FreePages (MapInfo->MappedHostAddress, MapInfo->NumberOfPages);
> +    gBS->FreePool (Mapping);
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Allocates pages that are suitable for an EfiPciOperationBusMasterCommonBuffer
> +  or EfiPciOperationBusMasterCommonBuffer64 mapping.
> +
> +  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param Type        This parameter is not used and must be ignored.
> +  @param MemoryType  The type of memory to allocate, EfiBootServicesData or
> +                     EfiRuntimeServicesData.
> +  @param Pages       The number of pages to allocate.
> +  @param HostAddress A pointer to store the base system memory address of the
> +                     allocated range.
> +  @param Attributes  The requested bit mask of attributes for the allocated
> +                     range. Only the attributes
> +                     EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE,
> +                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED, and
> +                     EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE may be used with this
> +                     function.
> +
> +  @retval EFI_SUCCESS            The requested memory pages were allocated.
> +  @retval EFI_INVALID_PARAMETER  MemoryType is invalid.
> +  @retval EFI_INVALID_PARAMETER  HostAddress is NULL.
> +  @retval EFI_UNSUPPORTED        Attributes is unsupported. The only legal
> +                                 attribute bits are MEMORY_WRITE_COMBINE,
> +                                 MEMORY_CACHED, and DUAL_ADDRESS_CYCLE.
> +  @retval EFI_OUT_OF_RESOURCES   The memory pages could not be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoAllocateBuffer (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN  EFI_ALLOCATE_TYPE               Type,
> +  IN  EFI_MEMORY_TYPE                 MemoryType,
> +  IN  UINTN                           Pages,
> +  OUT VOID                            **HostAddress,
> +  IN  UINT64                          Attributes
> +  )
> +{
> +  EFI_STATUS           Status;
> +  EFI_PHYSICAL_ADDRESS PhysicalAddress;
> +
> +  //
> +  // Validate Attributes
> +  //
> +  if ((Attributes & EFI_PCI_ATTRIBUTE_INVALID_FOR_ALLOCATE_BUFFER) != 0) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  //
> +  // Check for invalid inputs
> +  //
> +  if (HostAddress == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
> +  //
> +  if (MemoryType != EfiBootServicesData &&
> +      MemoryType != EfiRuntimeServicesData)
> +  {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  PhysicalAddress = (EFI_PHYSICAL_ADDRESS)(0xFFFFFFFFFFFFFFFFULL);
> +
> +  Status = gBS->AllocatePages (
> +                  AllocateMaxAddress,
> +                  MemoryType,
> +                  Pages,
> +                  &PhysicalAddress
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  *HostAddress = (VOID *)(UINTN)PhysicalAddress;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Frees memory that was allocated with AllocateBuffer().
> +
> +  The FreeBuffer() function frees memory that was allocated with
> +  AllocateBuffer().
> +
> +  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param Pages       The number of pages to free.
> +  @param HostAddress The base system memory address of the allocated range.
> +
> +  @retval EFI_SUCCESS            The requested memory pages were freed.
> +  @retval EFI_INVALID_PARAMETER  The memory range specified by HostAddress and
> +                                 Pages was not allocated with AllocateBuffer().
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoFreeBuffer (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN  UINTN                           Pages,
> +  OUT VOID                            *HostAddress
> +  )
> +{
> +  return gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)HostAddress, Pages);
> +}
> +
> +/**
> +  Flushes all PCI posted write transactions from a PCI host bridge to system
> +  memory.
> +
> +  The Flush() function flushes any PCI posted write transactions from a PCI
> +  host bridge to system memory. Posted write transactions are generated by PCI
> +  bus masters when they perform write transactions to target addresses in
> +  system memory.
> +  This function does not flush posted write transactions from any PCI bridges.
> +  A PCI controller specific action must be taken to guarantee that the posted
> +  write transactions have been flushed from the PCI controller and from all the
> +  PCI bridges into the PCI host bridge. This is typically done with a PCI read
> +  transaction from the PCI controller prior to calling Flush().
> +
> +  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +
> +  @retval EFI_SUCCESS        The PCI posted write transactions were flushed
> +                             from the PCI host bridge to system memory.
> +  @retval EFI_DEVICE_ERROR   The PCI posted write transactions were not flushed
> +                             from the PCI host bridge due to a hardware error.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoFlush (
> +  IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
> +  )
> +{
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Gets the attributes that a PCI root bridge supports setting with
> +  SetAttributes(), and the attributes that a PCI root bridge is currently
> +  using.
> +
> +  The GetAttributes() function returns the mask of attributes that this PCI
> +  root bridge supports and the mask of attributes that the PCI root bridge is
> +  currently using.
> +
> +  @param This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param Supported   A pointer to the mask of attributes that this PCI root
> +                     bridge supports setting with SetAttributes().
> +  @param Attributes  A pointer to the mask of attributes that this PCI root
> +                     bridge is currently using.
> +
> +  @retval  EFI_SUCCESS           If Supports is not NULL, then the attributes
> +                                 that the PCI root bridge supports is returned
> +                                 in Supports. If Attributes is not NULL, then
> +                                 the attributes that the PCI root bridge is
> +                                 currently using is returned in Attributes.
> +  @retval  EFI_INVALID_PARAMETER Both Supports and Attributes are NULL.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoGetAttributes (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  OUT UINT64                          *Supported,
> +  OUT UINT64                          *Attributes
> +  )
> +{
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +
> +  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  if (Attributes == NULL && Supported == NULL) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  //
> +  // Set the return value for Supported and Attributes
> +  //
> +  if (Supported != NULL) {
> +    *Supported  = RootBridgeInstance->RootBridge.Supports;
> +  }
> +
> +  if (Attributes != NULL) {
> +    *Attributes = RootBridgeInstance->RootBridge.Attributes;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Sets attributes for a resource range on a PCI root bridge.
> +
> +  The SetAttributes() function sets the attributes specified in Attributes for
> +  the PCI root bridge on the resource range specified by ResourceBase and
> +  ResourceLength. Since the granularity of setting these attributes may vary
> +  from resource type to resource type, and from platform to platform, the
> +  actual resource range and the one passed in by the caller may differ. As a
> +  result, this function may set the attributes specified by Attributes on a
> +  larger resource range than the caller requested. The actual range is returned
> +  in ResourceBase and ResourceLength. The caller is responsible for verifying
> +  that the actual range for which the attributes were set is acceptable.
> +
> +  @param This            A pointer to the
> +                         EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param Attributes      The mask of attributes to set. If the
> +                         attribute bit MEMORY_WRITE_COMBINE,
> +                         MEMORY_CACHED, or MEMORY_DISABLE is set,
> +                         then the resource range is specified by
> +                         ResourceBase and ResourceLength. If
> +                         MEMORY_WRITE_COMBINE, MEMORY_CACHED, and
> +                         MEMORY_DISABLE are not set, then
> +                         ResourceBase and ResourceLength are ignored,
> +                         and may be NULL.
> +  @param ResourceBase    A pointer to the base address of the
> +                         resource range to be modified by the
> +                         attributes specified by Attributes.
> +  @param ResourceLength  A pointer to the length of the resource
> +                                   range to be modified by the attributes
> +                                   specified by Attributes.
> +
> +  @retval  EFI_SUCCESS           The current configuration of this PCI root bridge
> +                                 was returned in Resources.
> +  @retval  EFI_UNSUPPORTED       The current configuration of this PCI root bridge
> +                                 could not be retrieved.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoSetAttributes (
> +  IN     EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  IN     UINT64                          Attributes,
> +  IN OUT UINT64                          *ResourceBase,
> +  IN OUT UINT64                          *ResourceLength
> +  )
> +{
> +  PCI_ROOT_BRIDGE_INSTANCE *RootBridgeInstance;
> +
> +  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
> +
> +  // Then check optional parameters if eligible
> +  if ((Attributes & (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |
> +                     EFI_PCI_ATTRIBUTE_MEMORY_CACHED |
> +                     EFI_PCI_ATTRIBUTE_MEMORY_DISABLE)) != 0)
> +  {
> +    if (ResourceBase == NULL || ResourceLength == NULL) {
> +      return EFI_INVALID_PARAMETER;
> +    }
> +  }
> +
> +  if (Attributes != 0) {
> +    if ((Attributes & (~(RootBridgeInstance->RootBridge.Supports))) != 0) {
> +      return EFI_UNSUPPORTED;
> +    }
> +  }
> +
> +  //
> +  // This is a generic driver for a PC-AT class system.  It does not have any
> +  // chipset specific knowlegde, so none of the attributes can be set or
> +  // cleared.  Any attempt to set attribute that are already set will succeed,
> +  // and any attempt to set an attribute that is not supported will fail.
> +  //
> +  if (Attributes & (~RootBridgeInstance->RootBridge.Attributes)) {
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  Retrieves the current resource settings of this PCI root bridge in the form
> +  of a set of ACPI resource descriptors.
> +
> +  There are only two resource descriptor types from the ACPI Specification that
> +  may be used to describe the current resources allocated to a PCI root bridge.
> +  These are the QWORD Address Space Descriptor, and the End Tag. The QWORD
> +  Address Space Descriptor can describe memory, I/O, and bus number ranges for
> +  dynamic or fixed resources. The configuration of a PCI root bridge is described
> +  with one or more QWORD Address Space Descriptors followed by an End Tag.
> +
> +  @param[in]   This        A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
> +  @param[out]  Resources   A pointer to the resource descriptors that
> +                           describe the current configuration of this PCI root
> +                           bridge. The storage for the resource
> +                           descriptors is allocated by this function. The
> +                           caller must treat the return buffer as read-only
> +                           data, and the buffer must not be freed by the
> +                          caller.
> +
> +  @retval  EFI_SUCCESS     The current configuration of this PCI root bridge
> +                           was returned in Resources.
> +  @retval  EFI_UNSUPPORTED The current configuration of this PCI root bridge
> +                           could not be retrieved.
> +**/
> +EFI_STATUS
> +EFIAPI
> +RootBridgeIoConfiguration (
> +  IN  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
> +  OUT VOID                            **Resources
> +  )
> +{
> +  PCI_ROOT_BRIDGE_INSTANCE          *RootBridgeInstance;
> +  PCI_RES_NODE                      *ResAllocNode;
> +  EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;
> +  EFI_ACPI_END_TAG_DESCRIPTOR       *End;
> +  UINTN                             Index;
> +
> +  RootBridgeInstance = ROOT_BRIDGE_FROM_THIS (This);
> +  ZeroMem (
> +    RootBridgeInstance->ConfigBuffer,
> +    TypeMax * sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR)
> +    );
> +
> +  Descriptor = RootBridgeInstance->ConfigBuffer;
> +  for (Index = TypeIo; Index < TypeMax; Index++) {
> +
> +    ResAllocNode = &RootBridgeInstance->ResAllocNode[Index];
> +
> +    if (ResAllocNode->Status != ResAllocated) {
> +      continue;
> +    }
> +
> +    switch (ResAllocNode->Type) {
> +
> +    case TypeBus:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_BUS;
> +      break;
> +
> +    case TypeIo:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_IO;
> +      Descriptor->AddrSpaceGranularity = 32;
> +      break;
> +
> +    case TypeMem32:
> +    case TypePMem32:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->SpecificFlag         = (Index == TypeMem32) ? 0 :
> +                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrSpaceGranularity = 32;
> +      break;
> +
> +    case TypeMem64:
> +    case TypePMem64:
> +      Descriptor->ResType              = ACPI_ADDRESS_SPACE_TYPE_MEM;
> +      Descriptor->SpecificFlag         = (Index == TypeMem64) ? 0 :
> +                                         EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
> +      Descriptor->AddrSpaceGranularity = 64;
> +      break;
> +
> +    default:
> +      continue;
> +    }
> +
> +    Descriptor->Desc          = ACPI_ADDRESS_SPACE_DESCRIPTOR;
> +    Descriptor->Len           = sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) - 3;
> +    Descriptor->AddrRangeMin  = ResAllocNode->Base;
> +    Descriptor->AddrRangeMax  = ResAllocNode->Base + ResAllocNode->Length - 1;
> +    Descriptor->AddrLen       = ResAllocNode->Length;
> +
> +    Descriptor++;
> +  }
> +
> +  //
> +  // Terminate the entries.
> +  //
> +  End = (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor;
> +  End->Desc     = ACPI_END_TAG_DESCRIPTOR;
> +  End->Checksum = 0x0;
> +
> +  *Resources = RootBridgeInstance->ConfigBuffer;
> +
> +  return EFI_SUCCESS;
> +}
> -- 
> 2.17.1
> 

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

* Re: [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and Mt. Jade platform
  2021-06-04 23:04   ` Leif Lindholm
@ 2021-06-09  4:50     ` Nhi Pham
  2021-06-09 12:40       ` Leif Lindholm
  2021-06-15 16:46     ` Nhi Pham
  1 sibling, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-06-09  4:50 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

[-- Attachment #1: Type: text/plain, Size: 87628 bytes --]

On 6/5/21 06:04, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:52 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> This commit adds the support for Ampere’s Altra processor-based Mt. Jade
>> platform that provides up to 160 processor cores in a dual socket
>> configuration. The essential modules are wired up enough to boot system
>> to EDK2 UiApp.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec                                         |  28 +
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                                |  42 ++
>>   Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                                            |  46 ++
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                            | 674 +++++++++++++++++++
>>   Platform/Ampere/JadePkg/Jade.dsc                                                                | 100 +++
>>   Platform/Ampere/JadePkg/Jade.fdf                                                                | 225 +++++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf                                  |  41 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf                         |  64 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf                             |  44 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf                         |  57 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf               |  37 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf                     |  63 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf                 |  35 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf                                 |  32 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf                         |  42 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf                                         |  29 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf |  30 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf                                       |  29 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h                                |  17 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h                                    | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h                             | 172 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h                              |  19 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h                                      | 133 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h                      | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h                                         |  31 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h                                                   |  79 +++
>>   Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h                                              | 515 ++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h                                           | 146 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h                                         | 182 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c                                    |  52 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c                           | 151 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c                               | 706 ++++++++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c                           | 169 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c                     | 399 +++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c                 | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c                       |  93 +++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c                   | 184 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c                                   | 202 ++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c                           |  40 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c                                           | 141 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c   | 328 +++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c                                         |  63 ++
>>   Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc                                               | 176 +++++
>>   Platform/Ampere/JadePkg/JadeBoardSetting.cfg                                                    | 209 ++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S                        |  45 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni                                         |  13 +
>>   46 files changed, 6729 insertions(+)
>>
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> new file mode 100755
>> index 000000000000..f68af24a0d78
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -0,0 +1,100 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +################################################################################
>> +#
>> +# Defines Section - statements that will be processed to create a Makefile.
>> +#
>> +################################################################################
>> +[Defines]
>> +  PLATFORM_NAME                  = Jade
>> +  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
>> +  PLATFORM_VERSION               = 0.1
>> +  DSC_SPECIFICATION              = 0x0001001B
>> +  OUTPUT_DIRECTORY               = Build/Jade
>> +  SUPPORTED_ARCHITECTURES        = AARCH64
>> +  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
>> +  SKUID_IDENTIFIER               = DEFAULT
>> +  FLASH_DEFINITION               = Platform/Ampere/JadePkg/Jade.fdf
>> +
>> +  #
>> +  # Defines for default states. These can be changed on the command line.
>> +  # -D FLAG=VALUE
>> +  #
>> +
>> +  #  DEBUG_INIT      0x00000001  // Initialization
>> +  #  DEBUG_WARN      0x00000002  // Warnings
>> +  #  DEBUG_LOAD      0x00000004  // Load events
>> +  #  DEBUG_FS        0x00000008  // EFI File system
>> +  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
>> +  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
>> +  #  DEBUG_INFO      0x00000040  // Informational debug messages
>> +  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
>> +  #  DEBUG_VARIABLE  0x00000100  // Variable
>> +  #  DEBUG_BM        0x00000400  // Boot Manager
>> +  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
>> +  #  DEBUG_NET       0x00004000  // SNP Driver
>> +  #  DEBUG_UNDI      0x00010000  // UNDI Driver
>> +  #  DEBUG_LOADFILE  0x00020000  // LoadFile
>> +  #  DEBUG_EVENT     0x00080000  // Event messages
>> +  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
>> +  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
>> +  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
>> +  #                              // significantly impact boot performance
>> +  #  DEBUG_ERROR     0x80000000  // Error
>> +  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
>> +  DEFINE FIRMWARE_VER            = 0.01.001
>> +  DEFINE EDK2_SKIP_PEICORE       = TRUE
>> +  DEFINE SECURE_BOOT_ENABLE      = FALSE
>> +  DEFINE INCLUDE_TFTP_COMMAND    = TRUE
>> +
>> +  #
>> +  # Network definition
>> +  #
>> +  DEFINE NETWORK_IP6_ENABLE                  = FALSE
>> +  DEFINE NETWORK_HTTP_BOOT_ENABLE            = TRUE
>> +  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS      = TRUE
>> +  DEFINE NETWORK_TLS_ENABLE                  = FALSE
>> +
> You'll want to include that !include MdePkg/MdeLibs.dsc.inc bit
> somewhere here.
>
>> +# Include default Ampere Platform DSC file
>> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Library
>> +#
>> +################################################################################
>> +[LibraryClasses]
>> +  #
>> +  # RTC Library: Common RTC
>> +  #
>> +  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Pcds
>> +#
>> +################################################################################
>> +[PcdsFeatureFlag.common]
>> +[PcdsFixedAtBuild.common]
>> +
>> +!if $(SECURE_BOOT_ENABLE) == TRUE
>> +  # Override the default values from SecurityPkg to ensure images
>> +  # from all sources are verified in secure boot
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
>> +!endif
>> +
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Component
>> +#
>> +################################################################################
>> +[Components.common]
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>> new file mode 100644
>> index 000000000000..de576474fb48
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>> @@ -0,0 +1,282 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef AMPERE_CPU_LIB_H_
>> +#define AMPERE_CPU_LIB_H_
>> +
>> +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
>> +#define CLIDR_CTYPE_SHIFT(Level)    (3 * (Level - 1))
>> +#define CLIDR_CTYPE_MASK(Level)     (7 << CLIDR_CTYPE_SHIFT(Level))
>> +#define CLIDR_CTYPE(Clidr, Level) \
>> +  (((Clidr) & CLIDR_CTYPE_MASK(Level)) >> CLIDR_CTYPE_SHIFT(Level))
>> +
>> +#define CCSIDR_NUMSETS_SHIFT        13
>> +#define CCSIDR_NUMSETS_MASK         0xFFFE000
>> +#define CCSIDR_NUMSETS(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT)
>> +#define CCSIDR_ASSOCIATIVITY_SHIFT  3
>> +#define CCSIDR_ASSOCIATIVITY_MASK   0x1FF8
>> +#define CCSIDR_ASSOCIATIVITY(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_SHIFT)
>> +#define CCSIDR_LINE_SIZE_SHIFT      0
>> +#define CCSIDR_LINE_SIZE_MASK       0x7
>> +#define CCSIDR_LINE_SIZE(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_LINE_SIZE_MASK) >> CCSIDR_LINE_SIZE_SHIFT)
> All of the above (CLIDR/CCSIDR) are architectural.
> We've also developed some new accessors and stuff for these, as part
> of ArmPkg/Universal/SmbiosDxe work that's gone on since v1 of this set.
> We may need to clean some interfaces up, but ideally I'd prefer if you
> could use some accessors from ArmLib or such.
>
>> +
>> +#define SUBNUMA_MODE_MONOLITHIC        0
>> +#define SUBNUMA_MODE_HEMISPHERE        1
>> +#define SUBNUMA_MODE_QUADRANT          2
>> +
>> +#define MONOLITIC_NUM_OF_REGION        1
>> +#define HEMISPHERE_NUM_OF_REGION       2
>> +#define QUADRANT_NUM_OF_REGION         4
>> +#define SUBNUMA_CPM_REGION_SIZE        4
>> +#define NUM_OF_CPM_PER_MESH_ROW        8
>> +
>> +#define CPM_PER_ROW_OFFSET(CpmId)      ((CpmId) % NUM_OF_CPM_PER_MESH_ROW)
>> +#define CPM_ROW_NUMBER(CpmId)          ((CpmId) / NUM_OF_CPM_PER_MESH_ROW)
>> +
>> +#define SOCKET_ID(CpuId)               ((CpuId) / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM))
>> +#define CLUSTER_ID(CpuId)              (((CpuId) / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM)
>> +
>> +
>> +/**
>> +  Get the SubNUMA mode.
>> +
>> +  @return   UINT8      The SubNUMA mode.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumaMode (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of SubNUMA region.
>> +
>> +  @return   UINT8      The number of SubNUMA region.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetNumberOfSubNumaRegion (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the SubNUMA node of a CPM.
>> +
>> +  @param    SocketId    Socket index.
>> +  @param    Cpm         CPM index.
>> +  @return   UINT8       The SubNUMA node of a CPM.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumNode (
>> +  UINT8  Socket,
>> +  UINT16 Cpm
>> +  );
>> +
>> +/**
>> +  Get the associativity of cache.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Associativity of cache.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetAssociativity (
>> +  UINT32 Level
>> +  );
>> +
>> +/**
>> +  Get the cache size.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Cache size.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetCacheSize (
>> +  UINT32 Level
>> +  );
>> +
>> +/**
>> +  Get the number of supported socket.
>> +
>> +  @return   UINT8      Number of supported socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfSupportedSockets (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active socket.
>> +
>> +  @return   UINT8      Number of active socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfActiveSockets (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCPMsPerSocket (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Get the number of configured CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of configured CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfConfiguredCPMs (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Set the number of configured CPM per socket.
>> +
>> +  @param    SocketId        Socket index.
>> +  @param    NumberOfCPMs    Number of CPM to be configured.
>> +  @return   EFI_SUCCESS     Operation succeeded.
>> +  @return   Others          An error has occurred.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SetNumberOfConfiguredCPMs (
>> +  UINT8  SocketId,
>> +  UINT16 NumberOfCPMs
>> +  );
>> +
>> +/**
>> +  Get the maximum number of core per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT16      Maximum number of core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCores (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the maximum number of CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT32      Maximum number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCPMs (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active cores of a sockets.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCoresPerSocket (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Get the number of active cores of all socket.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCores (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the logical CPU is enabled or not.
>> +
>> +  @param    CpuId       The logical Cpu ID. Started from 0.
>> +  @return   BOOLEAN     TRUE if the Cpu enabled
>> +                        FALSE if the Cpu disabled.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsCpuEnabled (
>> +  UINT16 CpuId
>> +  );
>> +
>> +
>> +/**
>> +  Check if the slave socket is present
>> +
>> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
>> +                        FALSE if the Slave Cpu is not present
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketPresent (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the slave socket is active
>> +
>> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
>> +                        FALSE if the Slave CPU Socket is not active.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketActive (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the CPU product ID is Ac01
>> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
>> +                        FALSE otherwise.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsAc01Processor (
>> +  VOID
>> +  );
>> +
>> +#endif /* AMPERE_CPU_LIB_H_ */
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>> new file mode 100644
>> index 000000000000..8da698e0b855
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>> @@ -0,0 +1,706 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiPei.h>
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib/ArmLibPrivate.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <NVParamDef.h>
>> +#include <Platform/Ac01.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +STATIC PLATFORM_INFO_HOB *mPlatformInfoHob = NULL;
>> +
>> +PLATFORM_INFO_HOB *
>> +GetPlatformHob (
>> +  VOID
>> +  )
>> +{
>> +  VOID *Hob;
>> +
>> +  if (mPlatformInfoHob == NULL) {
>> +    Hob = GetNextGuidHob (
>> +            &gPlatformHobGuid,
>> +            (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase)
>> +            );
>> +    ASSERT (Hob != NULL);
>> +    if (Hob == NULL) {
>> +      DEBUG ((DEBUG_ERROR, "%a: Failed to get gPlatformHobGuid!\n", __FUNCTION__));
>> +      return NULL;
>> +    }
>> +
>> +    mPlatformInfoHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +  }
>> +
>> +  return mPlatformInfoHob;
>> +}
>> +
>> +/**
>> +  Get the SubNUMA mode.
>> +
>> +  @return   UINT8      The SubNUMA mode.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumaMode (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return SUBNUMA_MODE_MONOLITHIC;
>> +  }
>> +
>> +  return PlatformHob->SubNumaMode[0];
>> +}
>> +
>> +/**
>> +  Get the number of SubNUMA region.
>> +
>> +  @return   UINT8      The number of SubNUMA region.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetNumberOfSubNumaRegion (
>> +  VOID
>> +  )
>> +{
>> +  UINT8 SubNumaMode;
>> +  UINT8 NumberOfSubNumaRegion;
>> +
>> +  SubNumaMode = CpuGetSubNumaMode ();
>> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
>> +
>> +  switch (SubNumaMode) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION;
>> +    break;
>> +
>> +  default:
>> +    // Should never reach there.
>> +    ASSERT (FALSE);
>> +    break;
>> +  }
>> +
>> +  return NumberOfSubNumaRegion;
>> +}
>> +
>> +/**
>> +  Get the SubNUMA node of a CPM.
>> +
>> +  @param    SocketId    Socket index.
>> +  @param    Cpm         CPM index.
>> +  @return   UINT8       The SubNUMA node of a CPM.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumNode (
>> +  UINT8  SocketId,
>> +  UINT16 Cpm
>> +  )
>> +{
>> +  BOOLEAN IsAsymMesh;
>> +  UINT8   SubNumaNode;
>> +  UINT16  MaxNumberOfCPM;
>> +  UINT8   MiddleRow;
>> +  UINT8   QuadrantHigherRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {1, 1, 1, 1, 3, 3, 3, 3};
>> +  UINT8   QuadrantLowerRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW]  = {0, 0, 0, 0, 2, 2, 2, 2};
>> +  UINT8   QuadrantMiddleRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 1, 1, 3, 3, 2, 2};
>> +  UINT8   SubNumaMode;
>> +
>> +  MaxNumberOfCPM = GetMaximumNumberOfCPMs ();
>> +  SubNumaMode = CpuGetSubNumaMode ();
>> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
>> +
>> +  switch (SubNumaMode) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    SubNumaNode = (SocketId == 0) ? 0 : 1;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    if (CPM_PER_ROW_OFFSET (Cpm) >= SUBNUMA_CPM_REGION_SIZE) {
>> +      SubNumaNode = 1;
>> +    } else {
>> +      SubNumaNode = 0;
>> +    }
>> +
>> +    if (SocketId == 1) {
>> +      SubNumaNode += HEMISPHERE_NUM_OF_REGION;
>> +    }
>> +    break;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    //
>> +    // CPM Mesh Rows
>> +    //
>> +    // |---------------------------------------|
>> +    // | 00 ----------- 03 | 04 ----------- 07 | Row 0
>> +    // |-------------------|-------------------|
>> +    // | 08 ----------- 11 | 12 ----------- 15 | Row 1
>> +    // |-------------------|-------------------|
>> +    // | 16 - 17 | 18 - 19 | 20 - 21 | 22 - 23 | Middle Row
>> +    // |-------------------|-------------------|
>> +    // | 24 ----------- 27 | 28 ----------- 31 | Row 3
>> +    // |-------------------|-------------------|
>> +    // | 32 ----------- 35 | 36 ----------- 39 | Row 4
>> +    // |---------------------------------------|
>> +    //
>> +
>> +    IsAsymMesh = (BOOLEAN)(CPM_ROW_NUMBER (MaxNumberOfCPM) % 2 != 0);
>> +    MiddleRow = CPM_ROW_NUMBER (MaxNumberOfCPM) / 2;
>> +    if (IsAsymMesh
>> +        && CPM_ROW_NUMBER (Cpm) == MiddleRow)
>> +    {
>> +      SubNumaNode = QuadrantMiddleRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +
>> +    } else if (CPM_ROW_NUMBER (Cpm) >= MiddleRow) {
>> +      SubNumaNode = QuadrantHigherRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +
>> +    } else {
>> +      SubNumaNode = QuadrantLowerRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +    }
>> +
>> +    if (SocketId == 1) {
>> +      SubNumaNode += QUADRANT_NUM_OF_REGION;
>> +    }
>> +    break;
>> +
>> +  default:
>> +    // Should never reach there.
>> +    ASSERT (FALSE);
>> +    break;
>> +  }
>> +
>> +  return SubNumaNode;
>> +}
>> +
>> +/**
>> +  Get the associativity of cache.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Associativity of cache.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetAssociativity (
>> +  UINT32 Level
>> +  )
>> +{
> I do feel some of this stuff could be replaced by the common functions
> we now have in ArmLib (that we didn't when v1 went out).
>
>> +  UINT64 CacheCCSIDR;
>> +  UINT64 CacheCLIDR;
>> +  UINT32 Value = 0x2; /* Unknown Set-Associativity */
>> +
>> +  CacheCLIDR = ReadCLIDR ();
>> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
>> +    return Value;
>> +  }
>> +
>> +  CacheCCSIDR = ReadCCSIDR (Level);
>> +  switch (CCSIDR_ASSOCIATIVITY (CacheCCSIDR)) {
>> +  case 0:
>> +    /* Direct mapped */
>> +    Value = 0x3;
>> +    break;
>> +
>> +  case 1:
>> +    /* 2-way Set-Associativity */
>> +    Value = 0x4;
>> +    break;
>> +
>> +  case 3:
>> +    /* 4-way Set-Associativity */
>> +    Value = 0x5;
>> +    break;
>> +
>> +  case 7:
>> +    /* 8-way Set-Associativity */
>> +    Value = 0x7;
>> +    break;
>> +
>> +  case 15:
>> +    /* 16-way Set-Associativity */
>> +    Value = 0x8;
>> +    break;
>> +
>> +  case 11:
>> +    /* 12-way Set-Associativity */
>> +    Value = 0x9;
>> +    break;
>> +
>> +  case 23:
>> +    /* 24-way Set-Associativity */
>> +    Value = 0xA;
>> +    break;
>> +
>> +  case 31:
>> +    /* 32-way Set-Associativity */
>> +    Value = 0xB;
>> +    break;
>> +
>> +  case 47:
>> +    /* 48-way Set-Associativity */
>> +    Value = 0xC;
>> +    break;
>> +
>> +  case 63:
>> +    /* 64-way Set-Associativity */
>> +    Value = 0xD;
>> +    break;
>> +
>> +  case 19:
>> +    /* 20-way Set-Associativity */
>> +    Value = 0xE;
>> +    break;
>> +  }
>> +
>> +  return Value;
>> +}
>> +
>> +/**
>> +  Get the cache size.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Cache size.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetCacheSize (
>> +  UINT32 Level
>> +  )
>> +{
>> +  UINT32 CacheLineSize;
>> +  UINT32 Count;
>> +  UINT64 CacheCCSIDR;
>> +  UINT64 CacheCLIDR;
>> +
>> +  CacheCLIDR = ReadCLIDR ();
>> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
>> +    return 0;
>> +  }
>> +
>> +  CacheCCSIDR = ReadCCSIDR (Level);
>> +  CacheLineSize = 1;
>> +  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
>> +  while (Count-- > 0) {
>> +    CacheLineSize *= 2;
>> +  }
>> +
>> +  return ((CCSIDR_NUMSETS (CacheCCSIDR) + 1) *
>> +          (CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1) *
>> +          CacheLineSize);
>> +}
>> +
>> +/**
>> +  Get the number of supported socket.
>> +
>> +  @return   UINT8      Number of supported socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfSupportedSockets (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    //
>> +    // By default, the number of supported sockets is 1.
>> +    //
>> +    return 1;
>> +  }
>> +
>> +  return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN));
>> +}
>> +
>> +/**
>> +  Get the number of active socket.
>> +
>> +  @return   UINT8      Number of active socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfActiveSockets (
>> +  VOID
>> +  )
>> +{
>> +  UINT8               NumberOfActiveSockets, Count, Index, Index1;
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    //
>> +    // By default, the number of active sockets is 1.
>> +    //
>> +    return 1;
>> +  }
>> +
>> +  NumberOfActiveSockets = 0;
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    Socket = &PlatformHob->ClusterEn[Index];
>> +    Count = ARRAY_SIZE (Socket->EnableMask);
>> +    for (Index1 = 0; Index1 < Count; Index1++) {
>> +      if (Socket->EnableMask[Index1] != 0) {
>> +        NumberOfActiveSockets++;
>> +        break;
>> +      }
>> +    }
>> +  }
>> +
>> +  return NumberOfActiveSockets;
>> +}
>> +
>> +/**
>> +  Get the number of active CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCPMsPerSocket (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  UINT16              NumberOfCPMs, Count, Index;
>> +  UINT32              Val32;
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return 0;
>> +  }
>> +
>> +  if (SocketId >= GetNumberOfActiveSockets ()) {
>> +    return 0;
>> +  }
>> +
>> +  NumberOfCPMs = 0;
>> +  Socket = &PlatformHob->ClusterEn[SocketId];
>> +  Count = ARRAY_SIZE (Socket->EnableMask);
>> +  for (Index = 0; Index < Count; Index++) {
>> +    Val32 = Socket->EnableMask[Index];
>> +    while (Val32 > 0) {
>> +      if ((Val32 & 0x1) != 0) {
>> +        NumberOfCPMs++;
>> +      }
>> +      Val32 >>= 1;
>> +    }
>> +  }
>> +
>> +  return NumberOfCPMs;
>> +}
>> +
>> +/**
>> +  Get the number of configured CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT8       Number of configured CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfConfiguredCPMs (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +  UINT32     Param, ParamStart, ParamEnd;
>> +  UINT16     Count;
>> +
>> +  Count = 0;
>> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
>> +    Status = NVParamGet (
>> +               Param,
>> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +               &Value
>> +               );
>> +    if (EFI_ERROR (Status)) {
>> +      break;
>> +    }
>> +    while (Value != 0) {
>> +      if ((Value & 0x01) != 0) {
>> +        Count++;
>> +      }
>> +      Value >>= 1;
>> +    }
>> +  }
>> +
>> +  return Count;
>> +}
>> +
>> +/**
>> +  Set the number of configured CPM per socket.
>> +
>> +  @param    SocketId        Socket index.
>> +  @param    NumberOfCPMs    Number of CPM to be configured.
>> +  @return   EFI_SUCCESS     Operation succeeded.
>> +  @return   Others          An error has occurred.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SetNumberOfConfiguredCPMs (
>> +  UINT8  SocketId,
>> +  UINT16 NumberOfCPMs
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +  UINT32     Param, ParamStart, ParamEnd;
>> +  BOOLEAN    IsClear;
>> +
>> +  IsClear = FALSE;
>> +  if (NumberOfCPMs == 0) {
>> +    IsClear = TRUE;
>> +  }
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
>> +    if (NumberOfCPMs >= 32) {
>> +      Value = 0xffffffff;
>> +      NumberOfCPMs -= 32;
>> +    } else {
>> +      Value = 0;
>> +      while (NumberOfCPMs > 0) {
>> +        Value |= (1 << (--NumberOfCPMs));
>> +      }
>> +    }
>> +    if (IsClear) {
>> +      /* Clear this param */
>> +      Status = NVParamClr (
>> +                 Param,
>> +                 NV_PERM_BIOS | NV_PERM_MANU
>> +                 );
>> +    } else {
>> +      Status = NVParamSet (
>> +                 Param,
>> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +                 NV_PERM_BIOS | NV_PERM_MANU,
>> +                 Value
>> +                 );
>> +    }
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Get the maximum number of core per socket.
>> +
>> +  @return   UINT16      Maximum number of core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCores (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return 0;
>> +  }
>> +
>> +  return PlatformHob->MaxNumOfCore[0];
>> +}
>> +
>> +/**
>> +  Get the maximum number of CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT16      Maximum number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCPMs (
>> +  VOID
>> +  )
>> +{
>> +  return GetMaximumNumberOfCores () / PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +}
>> +
>> +/**
>> +  Get the number of active cores of a sockets.
>> +
>> +  @param    SocketId    Socket Index.
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCoresPerSocket (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +}
>> +
>> +/**
>> +  Get the number of active cores of all sockets.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCores (
>> +  VOID
>> +  )
>> +{
>> +  UINT16 NumberOfActiveCores;
>> +  UINT8  Index;
>> +
>> +  NumberOfActiveCores = 0;
>> +
>> +  for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) {
>> +    NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index);
>> +  }
>> +
>> +  return NumberOfActiveCores;
>> +}
>> +
>> +/**
>> +  Check if the logical CPU is enabled or not.
>> +
>> +  @param    CpuId       The logical Cpu ID. Started from 0.
>> +  @return   BOOLEAN     TRUE if the Cpu enabled
>> +                        FALSE if the Cpu disabled.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsCpuEnabled (
>> +  UINT16 CpuId
>> +  )
>> +{
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +  UINT8               SocketId;
>> +  UINT16              ClusterId;
>> +
>> +  SocketId = SOCKET_ID (CpuId);
>> +  ClusterId = CLUSTER_ID (CpuId);
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return FALSE;
>> +  }
>> +
>> +  if (SocketId >= GetNumberOfActiveSockets ()) {
>> +    return FALSE;
>> +  }
>> +
>> +  Socket = &PlatformHob->ClusterEn[SocketId];
>> +  if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) {
>> +    return TRUE;
>> +  }
>> +
>> +  return FALSE;
>> +}
>> +
>> +/**
>> +  Check if the slave socket is present
>> +
>> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
>> +                        FALSE if the Slave Cpu is not present
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketPresent (
>> +  VOID
>> +  )
>> +{
>> +  UINT32 Value;
>> +
>> +  Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET);
>> +
>> +  return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE;
>> +}
>> +
>> +/**
>> +  Check if the slave socket is active
>> +
>> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
>> +                        FALSE if the Slave CPU Socket is not active.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketActive (
>> +  VOID
>> +  )
>> +{
>> +  return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE;
>> +}
>> +
>> +/**
>> +  Check if the CPU product ID is Ac01
>> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
>> +                        FALSE otherwise.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsAc01Processor (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  ASSERT (PlatformHob != NULL);
>> +
>> +  if (PlatformHob != NULL) {
>> +    if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) {
>> +      return TRUE;
>> +    }
>> +  }
>> +
>> +  return FALSE;
>> +}
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>> new file mode 100644
>> index 000000000000..8c1eb93f00fd
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>> @@ -0,0 +1,169 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/ArmPlatformLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PL011UartLib.h>
>> +#include <Library/SerialPortLib.h>
>> +#include <Platform/Ac01.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Ppi/ArmMpCoreInfo.h>
>> +#include <Ppi/TemporaryRamSupport.h>
>> +
>> +ARM_CORE_INFO mArmPlatformMpCoreInfoTable[PLATFORM_CPU_MAX_NUM_CORES];
>> +
>> +/**
>> +  Return the current Boot Mode
>> +
>> +  This function returns the boot reason on the platform
>> +
>> +  @return   Return the current Boot Mode of the platform
>> +
>> +**/
>> +EFI_BOOT_MODE
>> +ArmPlatformGetBootMode (
>> +  VOID
>> +  )
>> +{
>> +  return BOOT_WITH_FULL_CONFIGURATION;
>> +}
>> +
>> +/**
>> +  Initialize controllers that must setup in the normal world
>> +
>> +  This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
>> +  in the PEI phase.
>> +
>> +**/
>> +EFI_STATUS
>> +ArmPlatformInitialize (
>> +  IN UINTN MpId
>> +  )
>> +{
>> +  RETURN_STATUS      Status;
>> +  UINT64             BaudRate;
>> +  UINT32             ReceiveFifoDepth;
>> +  EFI_PARITY_TYPE    Parity;
>> +  UINT8              DataBits;
>> +  EFI_STOP_BITS_TYPE StopBits;
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  if (FixedPcdGet64 (PcdSerialRegisterBase) != 0) {
>> +    /* Debug port should use the same parameters with console */
>> +    BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
>> +    ReceiveFifoDepth = FixedPcdGet32 (PcdUartDefaultReceiveFifoDepth);
>> +    Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
>> +    DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
>> +    StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
>> +
>> +    /* Initialize uart debug port */
>> +    Status = PL011UartInitializePort (
>> +               (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
>> +               FixedPcdGet32 (PL011UartClkInHz),
>> +               &BaudRate,
>> +               &ReceiveFifoDepth,
>> +               &Parity,
>> +               &DataBits,
>> +               &StopBits
>> +               );
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +PrePeiCoreGetMpCoreInfo (
>> +  OUT UINTN         *CoreCount,
>> +  OUT ARM_CORE_INFO **ArmCoreTable
>> +  )
>> +{
>> +  UINTN              mArmPlatformCoreCount;
>> +  UINTN              ClusterId;
>> +  UINTN              SocketId;
>> +  UINTN              Index;
>> +
>> +  ASSERT (CoreCount != NULL);
>> +  ASSERT (ArmCoreTable != NULL);
>> +  ASSERT (*ArmCoreTable != NULL);
>> +
>> +  mArmPlatformCoreCount = 0;
>> +  for  (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index++) {
>> +    if (!IsCpuEnabled (Index)) {
>> +      continue;
>> +    }
>> +    SocketId = SOCKET_ID (Index);
>> +    ClusterId = CLUSTER_ID (Index);
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].ClusterId = SocketId;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].CoreId =
>> +      (ClusterId << 8) | (Index % PLATFORM_CPU_NUM_CORES_PER_CPM);
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearAddress = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearValue = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxGetAddress = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxSetAddress = 0;
>> +    mArmPlatformCoreCount++;
>> +  }
>> +
>> +  *CoreCount = mArmPlatformCoreCount;
>> +
>> +  *ArmCoreTable = mArmPlatformMpCoreInfoTable;
>> +  ASSERT (*ArmCoreTable != NULL);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
>> +EFI_GUID             mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
>> +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
>> +
>> +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
>> +  {
>> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
>> +    &mArmMpCoreInfoPpiGuid,
>> +    &mMpCoreInfoPpi
>> +  },
>> +};
>> +
>> +/**
>> +  Return the Platform specific PPIs
>> +
>> +  This function exposes the Platform Specific PPIs. They can be used by any PrePi modules or passed
>> +  to the PeiCore by PrePeiCore.
>> +
>> +  @param[out]   PpiListSize         Size in Bytes of the Platform PPI List
>> +  @param[out]   PpiList             Platform PPI List
>> +
>> +**/
>> +VOID
>> +ArmPlatformGetPlatformPpiList (
>> +  OUT UINTN                  *PpiListSize,
>> +  OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
>> +  )
>> +{
>> +  ASSERT (PpiListSize != NULL);
>> +  ASSERT (PpiList != NULL);
>> +  ASSERT (*PpiList != NULL);
>> +
>> +  if (ArmIsMpCore ()) {
>> +    *PpiListSize = sizeof (gPlatformPpiTable);
>> +    *PpiList = gPlatformPpiTable;
>> +  } else {
>> +    *PpiListSize = 0;
>> +    *PpiList = NULL;
>> +  }
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>> new file mode 100644
>> index 000000000000..117c9cc56ac2
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>> @@ -0,0 +1,399 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmPlatformLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +/* Number of Virtual Memory Map Descriptors */
>> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          50
>> +
>> +/* DDR attributes */
>> +#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
>> +#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
>> +
>> +/**
>> +  Return the Virtual Memory Map of your platform
>> +
>> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
>> +
>> +  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
>> +                                    Virtual Memory mapping. This array must be ended by a zero-filled
>> +                                    entry
>> +
>> +**/
>> +VOID
>> +ArmPlatformGetVirtualMemoryMap (
>> +  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
>> +  )
>> +{
>> +  UINTN                        Index = 0;
>> +  ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
>> +  UINT32                       NumRegion;
>> +  UINTN                        Count;
>> +  VOID                         *Hob;
>> +  PLATFORM_INFO_HOB            *PlatformHob;
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  ASSERT (Hob != NULL);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  ASSERT (VirtualMemoryMap != NULL);
>> +
>> +  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
>> +  if (VirtualMemoryTable == NULL) {
>> +    return;
>> +  }
>> +
>> +  /* For Address space 0x1000_0000_0000 to 0x1001_00FF_FFFF
>> +   *  - Device memory
>> +   */
>> +  VirtualMemoryTable[Index].PhysicalBase = 0x100000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x100000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x102000000ULL;
> Please move all of these live-coded addresses/sizes to a private .h
> and use symbolic names here.
>
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /* For Address space 0x5000_0000_0000 to 0x5001_00FF_FFFF
>> +   *  - Device memory
>> +   */
>> +  if (IsSlaveSocketActive ())
>> +  {
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x500000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x500000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x101000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +  }
>> +
>> +  /*
>> +   *  - PCIe RCA0 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x300000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x300000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x20000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x20000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA1 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x340000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x340000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x28000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x28000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA2 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x380000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x380000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x30000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x30000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA3 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x3C0000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x3C0000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x38000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x38000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB0 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x200000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x200000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x00000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x00000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB1 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x240000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x240000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x08000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x08000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB2 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x280000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x280000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x10000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x10000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB3 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x2C0000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x2C0000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x18000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x18000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  if (IsSlaveSocketActive ()) {
>> +    // Slave socket exist
>> +    /*
>> +     *  - PCIe RCA0 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x700000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x700000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA1 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x740000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x740000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA2 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x780000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x780000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA3 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x7C0000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x7C0000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB0 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x600000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x600000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB1 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x640000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x640000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB2 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x680000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x680000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB3 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x6C0000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x6C0000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +  }
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x60000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x60000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x68000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x68000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x70000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x70000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x78000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x78000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x40000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x40000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x48000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x48000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x50000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x50000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x58000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x58000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - BERT memory region
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x88230000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x88230000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x50000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - DDR memory region
>> +   */
>> +  NumRegion = PlatformHob->DramInfo.NumRegion;
>> +  Count = 0;
>> +  while (NumRegion-- > 0) {
>> +    if (PlatformHob->DramInfo.NvdRegion[Count]) { /* Skip NVDIMM Region */
>> +      Count++;
>> +      continue;
>> +    }
>> +
>> +    VirtualMemoryTable[++Index].PhysicalBase = PlatformHob->DramInfo.Base[Count];
>> +    VirtualMemoryTable[Index].VirtualBase  = PlatformHob->DramInfo.Base[Count];
>> +    VirtualMemoryTable[Index].Length       = PlatformHob->DramInfo.Size[Count];
>> +    VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
>> +    Count++;
>> +  }
>> +
>> +  /* SPM MM NS Buffer for MmCommunicateDxe */
>> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase);
>> +  VirtualMemoryTable[Index].VirtualBase  = PcdGet64 (PcdMmBufferBase);
>> +  VirtualMemoryTable[Index].Length       = PcdGet64 (PcdMmBufferSize);
>> +  VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
>> +
>> +  /* End of Table */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0;
>> +  VirtualMemoryTable[Index].Length       = 0;
>> +  VirtualMemoryTable[Index].Attributes   = (ARM_MEMORY_REGION_ATTRIBUTES)0;
>> +
>> +  ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
>> +
>> +  *VirtualMemoryMap = VirtualMemoryTable;
>> +}
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>> new file mode 100644
>> index 000000000000..0da1f90699f6
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>> @@ -0,0 +1,282 @@
>> +/** @file
>> +  The library implements the hardware Mailbox (Doorbell) interface for communication
>> +  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
>> +
>> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MailboxInterfaceLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/IoLib.h>
>> +
>> +//
>> +// Hardware Doorbells
>> +//
>> +#define SMPRO_DB0_IRQ_OFST               40
>> +#define SMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdSmproDbBaseReg))
>> +
>> +#define PMPRO_DB0_IRQ_OFST               56
>> +#define PMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdPmproDbBaseReg))
>> +
>> +#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000
>> +
>> +//
>> +// The base SPI interrupt number of the Slave socket
>> +//
>> +#define SLAVE_SOCKET_SPI_INTERRUPT 352
>> +
>> +#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32)
>> +
>> +//
>> +// Doorbell base register stride size
>> +//
>> +#define DB_BASE_REG_STRIDE 0x00001000
>> +
>> +#define SMPRO_DBx_ADDRESS(socket, db) \
>> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
>> +
>> +#define PMPRO_DBx_ADDRESS(socket, db) \
>> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
>> +
>> +//
>> +// Doorbell Status Bits
>> +//
>> +#define DB_STATUS_AVAIL_BIT       BIT16
>> +#define DB_STATUS_ACK_BIT         BIT0
>> +
>> +/**
>> +  Get the base address of a doorbell.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +
>> +  @retval UINT32                The base address of the doorbell.
>> +                                The returned value is 0 indicate that the input parameters are invalid.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +MailboxGetDoorbellAddress (
>> +  IN UINT8             Socket,
>> +  IN DOORBELL_CHANNELS Doorbell
>> +  )
>> +{
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return 0;
>> +  }
> Coding style is
>   if () {
>   }
>
> This file gets it consistently wrong.

I agree that it should be consistent. But that coding style conforms to 
"5.2.1.6 Each sub-expression of a complex predicate expression must be 
on a separate line" in EDK II Coding Standards Spec 
(https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/52_spacing#5-2-1-6-each-sub-expression-of-a-complex-predicate-expression-must-be-on-a-separate-line).

"Predicate expressions containing multiple operators with 
sub-expressions joined by && or || must have each sub-expression on a 
separate line. The opening brace, '|{|' of the body shall be on a line 
by itself and aligned in the starting column of the associated keyword.

while ( ( Code == MEETS_STANDARD)
   && ( Code == FUNCTIONAL))
{
   ShipIt();
}

"

However, I'm OK to change it as your suggestion.


Thanks,

Nhi

>
>> +
>> +  if (Doorbell >= SMproDoorbellChannel0) {
>> +    DoorbellAddress = SMPRO_DBx_ADDRESS (Socket, (UINT8)(Doorbell - SMproDoorbellChannel0));
>> +  } else {
>> +    DoorbellAddress = PMPRO_DBx_ADDRESS (Socket, (UINT8)Doorbell);
>> +  }
>> +
>> +  return DoorbellAddress;
>> +}
>> +
>> +/**
>> +  Get the interrupt number of a doorbell.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +
>> +  @retval UINT32                The interrupt number.
>> +                                The returned value is 0 indicate that the input parameters are invalid.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +MailboxGetDoorbellInterruptNumber (
>> +  IN UINT8             Socket,
>> +  IN DOORBELL_CHANNELS Doorbell
>> +  )
>> +{
>> +  UINT32 DoorbellInterruptNumber;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return 0;
>> +  }
>> +
>> +  DoorbellInterruptNumber = 0;
>> +
>> +  if (Socket > 0) {
>> +    DoorbellInterruptNumber = SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE (Socket);
>> +  }
>> +
>> +  if (Doorbell >= SMproDoorbellChannel0) {
>> +    DoorbellInterruptNumber += SMPRO_DB0_IRQ_OFST + (UINT8)(Doorbell - SMproDoorbellChannel0);
>> +  } else {
>> +    DoorbellInterruptNumber += PMPRO_DB0_IRQ_OFST + (UINT8)Doorbell;
>> +  }
>> +
>> +  return DoorbellInterruptNumber;
>> +}
>> +
>> +/**
>> +  Read a message via the hardware Doorbell interface.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +  @param[out] Message           Pointer to the Mailbox message.
>> +
>> +  @retval EFI_SUCCESS           Read the message successfully.
>> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for available message in the mailbox.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxRead (
>> +  IN  UINT8                Socket,
>> +  IN  DOORBELL_CHANNELS    Doorbell,
>> +  OUT MAILBOX_MESSAGE_DATA *Message
>> +  )
>> +{
>> +  UINTN TimeoutCount;
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
>> +      || Message == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  TimeoutCount = MAILBOX_POLL_COUNT;
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  //
>> +  // Polling Doorbell status
>> +  //
>> +  while ((MmioRead32 ((DoorbellAddress + DB_STATUS_REG_OFST)) & DB_STATUS_AVAIL_BIT) == 0) {
>> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
>> +    if (--TimeoutCount == 0) {
>> +      return EFI_TIMEOUT;
>> +    }
>> +  }
>> +
>> +  Message->ExtendedData[0] = MmioRead32 (DoorbellAddress + DB_DIN0_REG_OFST);
>> +  Message->ExtendedData[1] = MmioRead32 (DoorbellAddress + DB_DIN1_REG_OFST);
>> +  Message->Data = MmioRead32 (DoorbellAddress + DB_IN_REG_OFST);
>> +
>> +  //
>> +  // Write 1 to clear the AVAIL status
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_AVAIL_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Write a message via the hardware Doorbell interface.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbel channel for communication with the SMpro/PMpro.
>> +  @param[in]  Message           Pointer to the Mailbox message.
>> +
>> +  @retval EFI_SUCCESS           Write the message successfully.
>> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for acknowledge signal from the mailbox.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxWrite (
>> +  IN UINT8                Socket,
>> +  IN DOORBELL_CHANNELS    Doorbell,
>> +  IN MAILBOX_MESSAGE_DATA *Message
>> +  )
>> +{
>> +  UINTN TimeoutCount;
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
>> +      || Message == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  TimeoutCount = MAILBOX_POLL_COUNT;
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  //
>> +  // Clear previous pending ack if any
>> +  //
>> +  if ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) != 0) {
>> +    MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
>> +  }
>> +
>> +  //
>> +  // Send message
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_DOUT0_REG_OFST, Message->ExtendedData[0]);
>> +  MmioWrite32 (DoorbellAddress + DB_DOUT1_REG_OFST, Message->ExtendedData[1]);
>> +  MmioWrite32 (DoorbellAddress + DB_OUT_REG_OFST, Message->Data);
>> +
>> +  //
>> +  // Wait for ACK
>> +  //
>> +  while ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) == 0) {
>> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
>> +    if (--TimeoutCount == 0) {
>> +      return EFI_TIMEOUT;
>> +    }
>> +  }
>> +
>> +  //
>> +  // Write 1 to clear the ACK status
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Unmask the Doorbell interrupt status.
>> +
>> +  @param  Socket    Active socket index.
>> +  @param  Doorbell  Doorbel channel for communication with the SMpro/PMpro.
>> +
>> +  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
>> +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxUnmaskInterrupt (
>> +  IN UINT8  Socket,
>> +  IN UINT16 Doorbell
>> +  )
>> +{
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_MASK_REG_OFST, ~DB_STATUS_AVAIL_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>> new file mode 100644
>> index 000000000000..bf400ec0a835
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>> @@ -0,0 +1,184 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <IndustryStandard/ArmStdSmc.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/ArmSmcLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MmCommunicationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Protocol/MmCommunication.h>
>> +
>> +//
>> +// Address, Length of the pre-allocated buffer for communication with the secure
>> +// world.
>> +//
>> +STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +MmCommunicationLibConstructor (
>> +  VOID
>> +  )
>> +{
>> +  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
>> +  // During boot , Virtual and Physical are same
> Ideally, use UEFI-defined terms. "During boot" is quite ambiguous.
>
>
>> +  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
>> +  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Communicates with a registered handler.
>> +
>> +  This function provides an interface to send and receive messages to the
>> +  Standalone MM environment in UEFI PEI phase.
>> +
>> +  @param[in, out] CommBuffer          A pointer to the buffer to convey
>> +                                      into MMRAM.
>> +  @param[in, out] CommSize            The size of the data buffer being
>> +                                      passed in. This is optional.
>> +
>> +  @retval EFI_SUCCESS                 The message was successfully posted.
>> +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
>> +  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
>> +                                      implementation. If this error is
>> +                                      returned, the MessageLength field in
>> +                                      the CommBuffer header or the integer
>> +                                      pointed by CommSize are updated to reflect
>> +                                      the maximum payload size the
>> +                                      implementation can accommodate.
>> +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
>> +                                      or CommSize parameter, if not omitted,
>> +                                      are in address range that cannot be
>> +                                      accessed by the MM environment
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MmCommunicationCommunicate (
>> +  IN OUT VOID  *CommBuffer,
>> +  IN OUT UINTN *CommSize OPTIONAL
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
>> +  ARM_SMC_ARGS              CommunicateSmcArgs;
>> +  EFI_STATUS                Status;
>> +  UINTN                     BufferSize;
>> +
>> +  Status = EFI_ACCESS_DENIED;
>> +  BufferSize = 0;
>> +
>> +  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
>> +
>> +  //
>> +  // Check parameters
>> +  //
>> +  if (CommBuffer == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  CommunicateHeader = CommBuffer;
>> +  // CommBuffer is a mandatory parameter. Hence, Rely on
>> +  // MessageLength + Header to ascertain the
>> +  // total size of the communication payload rather than
>> +  // rely on optional CommSize parameter
>> +  BufferSize = CommunicateHeader->MessageLength +
>> +               sizeof (CommunicateHeader->HeaderGuid) +
>> +               sizeof (CommunicateHeader->MessageLength);
>> +
>> +  // If the length of the CommBuffer is 0 then return the expected length.
>> +  if (CommSize != NULL) {
>> +    // This case can be used by the consumer of this driver to find out the
>> +    // max size that can be used for allocating CommBuffer.
>> +    if ((*CommSize == 0) ||
>> +        (*CommSize > mNsCommBuffMemRegion.Length))
>> +    {
> { at end of preceding line.
> Please address throughout this file.
>
>> +      *CommSize = mNsCommBuffMemRegion.Length;
>> +      return EFI_BAD_BUFFER_SIZE;
>> +    }
>> +    //
>> +    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
>> +    //
>> +    if (*CommSize != BufferSize) {
>> +      return EFI_INVALID_PARAMETER;
>> +    }
>> +  }
>> +
>> +  //
>> +  // If the buffer size is 0 or greater than what can be tolerated by the MM
>> +  // environment then return the expected size.
>> +  //
>> +  if ((BufferSize == 0) ||
>> +      (BufferSize > mNsCommBuffMemRegion.Length))
>> +  {
>> +    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
>> +                                       sizeof (CommunicateHeader->HeaderGuid) -
>> +                                       sizeof (CommunicateHeader->MessageLength);
>> +    return EFI_BAD_BUFFER_SIZE;
>> +  }
>> +
>> +  // SMC Function ID
>> +  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
>> +
>> +  // Cookie
>> +  CommunicateSmcArgs.Arg1 = 0;
>> +
>> +  // Copy Communication Payload
>> +  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
>> +
>> +  // comm_buffer_address (64-bit physical address)
>> +  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
>> +
>> +  // comm_size_address (not used, indicated by setting to zero)
>> +  CommunicateSmcArgs.Arg3 = 0;
>> +
>> +  // Call the Standalone MM environment.
>> +  ArmCallSmc (&CommunicateSmcArgs);
>> +
>> +  switch (CommunicateSmcArgs.Arg0) {
>> +  case ARM_SMC_MM_RET_SUCCESS:
>> +    ZeroMem (CommBuffer, BufferSize);
>> +    // On successful return, the size of data being returned is inferred from
>> +    // MessageLength + Header.
>> +    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
>> +    BufferSize = CommunicateHeader->MessageLength +
>> +                 sizeof (CommunicateHeader->HeaderGuid) +
>> +                 sizeof (CommunicateHeader->MessageLength);
>> +
>> +    CopyMem (
>> +      CommBuffer,
>> +      (VOID *)mNsCommBuffMemRegion.VirtualBase,
>> +      BufferSize
>> +      );
>> +    Status = EFI_SUCCESS;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_INVALID_PARAMS:
>> +    Status = EFI_INVALID_PARAMETER;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_DENIED:
>> +    Status = EFI_ACCESS_DENIED;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_NO_MEMORY:
>> +    // Unexpected error since the CommSize was checked for zero length
>> +    // prior to issuing the SMC
>> +    Status = EFI_OUT_OF_RESOURCES;
>> +    ASSERT (0);
>> +    break;
>> +
>> +  default:
>> +    Status = EFI_ACCESS_DENIED;
>> +    ASSERT (0);
>> +  }
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/JadeBoardSetting.cfg b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>> new file mode 100644
>> index 000000000000..5a67e8fc6a75
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>> @@ -0,0 +1,209 @@
>> +# Sample board setting
>> +#
>> +# This is a sample board setting as used for the
>> +# Ampere Altra reference design.
> What is a board setting?
>
>> +#
>> +# Name, offset (hex), value
>> +# value can be hex or decimal
>> +#
>> +
>> +NV_SI_RO_BOARD_VENDOR, 0x0000, 0x0000CD3A
>> +NV_SI_RO_BOARD_TYPE, 0x0008, 0x00000000
>> +NV_SI_RO_BOARD_REV, 0x0010, 0x00000000
>> +NV_SI_RO_BOARD_CFG, 0x0018, 0x00000000
>> +NV_SI_RO_BOARD_S0_DIMM_AVAIL, 0x0020, 0x0000FFFF
>> +NV_SI_RO_BOARD_S1_DIMM_AVAIL, 0x0028, 0x0000FFFF
>> +NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ, 0x0030, 0x000080E8
>> +NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ, 0x0038, 0x000080E8
>> +NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ, 0x0040, 0x00002710
>> +NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ, 0x0048, 0x00002710
>> +NV_SI_RO_BOARD_TPM_LOC, 0x0050, 0x00000000
>> +NV_SI_RO_BOARD_I2C0_FREQ_KHZ, 0x0058, 0x00000190
>> +NV_SI_RO_BOARD_I2C1_FREQ_KHZ, 0x0060, 0x00000190
>> +NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ, 0x0068, 0x00000190
>> +NV_SI_RO_BOARD_I2C3_FREQ_KHZ, 0x0070, 0x00000190
>> +NV_SI_RO_BOARD_I2C9_FREQ_KHZ, 0x0078, 0x00000190
>> +NV_SI_RO_BOARD_2P_CFG, 0x0080, 0xFFFFFF01
>> +NV_SI_RO_BOARD_S0_RCA0_CFG, 0x0088, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA1_CFG, 0x0090, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA2_CFG, 0x0098, 0x00000004
>> +NV_SI_RO_BOARD_S0_RCA3_CFG, 0x00A0, 0x00000004
>> +NV_SI_RO_BOARD_S0_RCB0_LO_CFG, 0x00A8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB0_HI_CFG, 0x00B0, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB1_LO_CFG, 0x00B8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB1_HI_CFG, 0x00C0, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB2_LO_CFG, 0x00C8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB2_HI_CFG, 0x00D0, 0x00000003
>> +NV_SI_RO_BOARD_S0_RCB3_LO_CFG, 0x00D8, 0x00000003
>> +NV_SI_RO_BOARD_S0_RCB3_HI_CFG, 0x00E0, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCA0_CFG, 0x00E8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA1_CFG, 0x00F0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA2_CFG, 0x00F8, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA3_CFG, 0x0100, 0x00030003
>> +NV_SI_RO_BOARD_S1_RCB0_LO_CFG, 0x0108, 0x00000003
>> +NV_SI_RO_BOARD_S1_RCB0_HI_CFG, 0x0110, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB1_LO_CFG, 0x0118, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB1_HI_CFG, 0x0120, 0x00000003
>> +NV_SI_RO_BOARD_S1_RCB2_LO_CFG, 0x0128, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB2_HI_CFG, 0x0130, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB3_LO_CFG, 0x0138, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB3_HI_CFG, 0x0140, 0x00020002
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P0, 0x0148, 0x00000001
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P1, 0x0150, 0x00000002
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P2, 0x0158, 0x00000003
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P3, 0x0160, 0x00000004
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M1, 0x0168, 0xFFFFFFFF
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M2, 0x0170, 0xFFFFFFFE
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M3, 0x0178, 0xFFFFFFFD
>> +NV_SI_RO_BOARD_P_LM_PID_P, 0x0180, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I, 0x0188, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD, 0x0190, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD, 0x0198, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_D, 0x01A0, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST, 0x01A8, 0x00000000
>> +NV_SI_RO_BOARD_TPM_ALG_ID, 0x01B0, 0x00000002
>> +NV_SI_RO_BOARD_DDR_SPEED_GRADE, 0x01B8, 0x00000C80
>> +NV_SI_RO_BOARD_DDR_S0_RTT_WR, 0x01C0, 0x00020000
>> +NV_SI_RO_BOARD_DDR_S1_RTT_WR, 0x01C8, 0x00020000
>> +NV_SI_RO_BOARD_DDR_S0_RTT_NOM, 0x01D0, 0xFF060177
>> +NV_SI_RO_BOARD_DDR_S1_RTT_NOM, 0x01D8, 0xFF060177
>> +NV_SI_RO_BOARD_DDR_S0_RTT_PARK, 0x01E0, 0x00060070
>> +NV_SI_RO_BOARD_DDR_S1_RTT_PARK, 0x01E8, 0x00060070
>> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC, 0x01F0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC, 0x01F8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC, 0x0200, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC, 0x0208, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC, 0x0210, 0x000C0CCC
>> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC, 0x0218, 0x000C0CCC
>> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC, 0x0220, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC, 0x0228, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC, 0x0230, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC, 0x0238, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC, 0x0240, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC, 0x0248, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC, 0x0250, 0x000EDEED
>> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC, 0x0258, 0x000DEDDE
>> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC, 0x0260, 0x000B7BB7
>> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC, 0x0268, 0x0007B77B
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC, 0x0270, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC, 0x0278, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC, 0x0280, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC, 0x0288, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC, 0x0290, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC, 0x0298, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC, 0x02A0, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC, 0x02A8, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC, 0x02B0, 0x00000024
>> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC, 0x02B8, 0x0000001A
>> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC, 0x02C0, 0x00000050
>> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC, 0x02C8, 0x00000020
>> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT, 0x02D0, 0x02800280
>> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT, 0x02D8, 0x90909090
>> +NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT, 0x02E0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT, 0x02E8, 0x00C000C0
>> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ, 0x02F0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ, 0x02F8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ, 0x0300, 0x00000000
>> +NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ, 0x0308, 0x00000000
>> +NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE, 0x0310, 0x02010201
>> +NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE, 0x0318, 0x00000000
>> +NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO, 0x0320, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL, 0x0328, 0x00000000
>> +NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS, 0x0330, 0x01050106
>> +NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD, 0x0338, 0x000005F4
>> +NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE, 0x0340, 0x00000000
>> +NV_SI_RO_BOARD_S0_PCIE_CLK_CFG, 0x0348, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA4_CFG, 0x0350, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA5_CFG, 0x0358, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA6_CFG, 0x0360, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA7_CFG, 0x0368, 0x02020003
>> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET, 0x0370, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET, 0x0378, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET, 0x0380, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET, 0x0388, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET, 0x0390, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET, 0x0398, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET, 0x03A0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET, 0x03A8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET, 0x03B0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET, 0x03B8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET, 0x03C0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET, 0x03C8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET, 0x03D0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET, 0x03D8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET, 0x03E0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET, 0x03E8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET, 0x03F0, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET, 0x03F8, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET, 0x0400, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET, 0x0408, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET, 0x0410, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET, 0x0418, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET, 0x0420, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET, 0x0428, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET, 0x0430, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET, 0x0438, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET, 0x0440, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET, 0x0448, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET, 0x0450, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET, 0x0458, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET, 0x0460, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET, 0x0468, 0x57575757
>> +NV_SI_RO_BOARD_S1_PCIE_CLK_CFG, 0x0470, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA4_CFG, 0x0478, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA5_CFG, 0x0480, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA6_CFG, 0x0488, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA7_CFG, 0x0490, 0x02020003
>> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET, 0x0498, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET, 0x04A0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET, 0x04A8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET, 0x04B0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET, 0x04B8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET, 0x04C0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET, 0x04C8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET, 0x04D0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET, 0x04D8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET, 0x04E0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET, 0x04E8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET, 0x04F0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET, 0x04F8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET, 0x0500, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET, 0x0508, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET, 0x0510, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET, 0x0518, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET, 0x0520, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET, 0x0528, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET, 0x0530, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET, 0x0538, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET, 0x0540, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET, 0x0548, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET, 0x0550, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET, 0x0558, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET, 0x0560, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET, 0x0568, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET, 0x0570, 0x57575757
>> +NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD, 0x0578, 0x00000003
>> +NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL, 0x0580, 0x000001A4
>> +NV_SI_RO_BOARD_SX_PHY_CFG_SETTING, 0x0588, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_DC_CLK, 0x0590, 0x00018000
>> +NV_SI_RO_BOARD_DDR_PHY_DC_DATA, 0x0598, 0x80018000
>> +NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET, 0x05A0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET, 0x05A8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET, 0x05B0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET, 0x05B8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET, 0x05C0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET, 0x05C8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET, 0x05D0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET, 0x05D8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD, 0x05E0, 0x00550055
>> +NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US, 0x05E8, 0x00000064
>> +NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV, 0x05F0, 0x00000005
>> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN, 0x05F8, 0x00000001
>> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME, 0x0600, 0x00000002
>> +NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US, 0x0608, 0x00000005
>> +NV_SI_RO_BOARD_PCIE_AER_FW_FIRST, 0x0610, 0x00000000
>> +NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS, 0x0618, 0x00000000
>> +NV_SI_RO_BOARD_TPM_DISABLE, 0x0620, 0x00000000
>> +NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, 0x0628, 0x00000000
>> +NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, 0x0630, 0x00000000
>> +NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN, 0x0638, 0x00000000
> There was also a few things in this patch where I felt names had
> insufficient namespace - such as starting with TRNG_ or NV_.
> I'm not going to insist on adding prefixes to those, I'm just going to
> say I have warned you, and those might get you in trouble in the
> future :)
>
> Best Regards,
>
> Leif

[-- Attachment #2: Type: text/html, Size: 87986 bytes --]

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

* Re: [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver
  2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
  2021-06-08 22:26   ` Leif Lindholm
@ 2021-06-09  5:29   ` Ard Biesheuvel
  2021-06-15 15:54     ` Nhi Pham
  1 sibling, 1 reply; 87+ messages in thread
From: Ard Biesheuvel @ 2021-06-09  5:29 UTC (permalink / raw)
  To: Nhi Pham
  Cc: edk2-devel-groups-io, Vu Nguyen, Thang Nguyen, Chuong Tran,
	Phong Vo, Leif Lindholm, Michael D Kinney, Ard Biesheuvel,
	Nate DeSimone

On Wed, 26 May 2021 at 12:12, Nhi Pham <nhi@os.amperecomputing.com> wrote:
>
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>
> The roles of this driver:
> * Consume PcieCoreLib to initialize all enable PCIe controllers.
> * Produce neccessary protocols like RootBridgeIo an ResourceAllocation
>   which will be used later by PciBus.
>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>
> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>

Why do you need a re-implementation of PciHostBridgeDxe for any of
this? There is very little h/w specific code there, and it is all
customizable using PciHostBridgeLib and PciSegmentLib (among others)

There are a couple of examples of this in edk2-platforms - please take
a look at those, and if that does not give you enough wiggle room,
let's see if we can accommodate your needs in PciHostBridgeDxe itself.

-- 
Ard.

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

* Re: [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and Mt. Jade platform
  2021-06-09  4:50     ` Nhi Pham
@ 2021-06-09 12:40       ` Leif Lindholm
  0 siblings, 0 replies; 87+ messages in thread
From: Leif Lindholm @ 2021-06-09 12:40 UTC (permalink / raw)
  To: Nhi Pham
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On Wed, Jun 09, 2021 at 11:50:07 +0700, Nhi Pham wrote:
> > > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
> > > new file mode 100644
> > > index 000000000000..0da1f90699f6
> > > --- /dev/null
> > > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
> > > @@ -0,0 +1,282 @@
> > > +/** @file
> > > +  The library implements the hardware Mailbox (Doorbell) interface for communication
> > > +  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
> > > +
> > > +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
> > > +
> > > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > > +
> > > +**/
> > > +
> > > +#include <Uefi.h>
> > > +
> > > +#include <Library/AmpereCpuLib.h>
> > > +#include <Library/BaseMemoryLib.h>
> > > +#include <Library/DebugLib.h>
> > > +#include <Library/MailboxInterfaceLib.h>
> > > +#include <Library/TimerLib.h>
> > > +#include <Library/IoLib.h>
> > > +
> > > +//
> > > +// Hardware Doorbells
> > > +//
> > > +#define SMPRO_DB0_IRQ_OFST               40
> > > +#define SMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdSmproDbBaseReg))
> > > +
> > > +#define PMPRO_DB0_IRQ_OFST               56
> > > +#define PMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdPmproDbBaseReg))
> > > +
> > > +#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000
> > > +
> > > +//
> > > +// The base SPI interrupt number of the Slave socket
> > > +//
> > > +#define SLAVE_SOCKET_SPI_INTERRUPT 352
> > > +
> > > +#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32)
> > > +
> > > +//
> > > +// Doorbell base register stride size
> > > +//
> > > +#define DB_BASE_REG_STRIDE 0x00001000
> > > +
> > > +#define SMPRO_DBx_ADDRESS(socket, db) \
> > > +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
> > > +
> > > +#define PMPRO_DBx_ADDRESS(socket, db) \
> > > +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
> > > +
> > > +//
> > > +// Doorbell Status Bits
> > > +//
> > > +#define DB_STATUS_AVAIL_BIT       BIT16
> > > +#define DB_STATUS_ACK_BIT         BIT0
> > > +
> > > +/**
> > > +  Get the base address of a doorbell.
> > > +
> > > +  @param[in]  Socket            Active socket index.
> > > +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
> > > +
> > > +  @retval UINT32                The base address of the doorbell.
> > > +                                The returned value is 0 indicate that the input parameters are invalid.
> > > +
> > > +**/
> > > +UINTN
> > > +EFIAPI
> > > +MailboxGetDoorbellAddress (
> > > +  IN UINT8             Socket,
> > > +  IN DOORBELL_CHANNELS Doorbell
> > > +  )
> > > +{
> > > +  UINTN DoorbellAddress;
> > > +
> > > +  if (Socket >= GetNumberOfActiveSockets ()
> > > +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
> > > +  {
> > > +    return 0;
> > > +  }
> > Coding style is
> >   if () {
> >   }
> > 
> > This file gets it consistently wrong.
> 
> I agree that it should be consistent. But that coding style conforms to
> "5.2.1.6 Each sub-expression of a complex predicate expression must be on a
> separate line" in EDK II Coding Standards Spec (https://edk2-docs.gitbook.io/edk-ii-c-coding-standards-specification/5_source_files/52_spacing#5-2-1-6-each-sub-expression-of-a-complex-predicate-expression-must-be-on-a-separate-line).
> 
> "Predicate expressions containing multiple operators with sub-expressions
> joined by && or || must have each sub-expression on a separate line. The
> opening brace, '|{|' of the body shall be on a line by itself and aligned in
> the starting column of the associated keyword.
> 
> while ( ( Code == MEETS_STANDARD)
>   && ( Code == FUNCTIONAL))
> {
>   ShipIt();
> }
> 
> "
> 
> However, I'm OK to change it as your suggestion.

I stand corrected.
I think it's confusing, but if it's not only explicitly permitted but
actually required by the spec, then feel free to leave it in.

Best Regards,

Leif (pondering starting a separate thread on changing that rule in the
      coding style)

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

* Re: [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform
  2021-06-07 23:58   ` Leif Lindholm
@ 2021-06-09 15:20     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-09 15:20 UTC (permalink / raw)
  To: Leif Lindholm, Ard Biesheuvel
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Nate DeSimone

On 6/8/21 06:58, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:24 +0700, Nhi Pham wrote:
>> Adds DSC and FDF files to support the LinuxBoot build. Some PEI/DXE
>> drivers are not added into the target build as they are not required for
>> booting to the LinuxBoot Shell.
>>
>> Please note that we MUST have the LinuxBoot binary in the
>> Platform/Ampere/LinuxBootPkg/AArch64 directory before compiling.
> Hmm. So, this step feels a little bit weird to me.
> I think a more common workflow would be to treat the LinuxBoot module
> like an edk2-non-osi module.

The LinuxBoot binary, named flashkernel, that consists of Linux kernel 
and initramfs is built separately from the 
https://github.com/linuxboot/mainboards reposistory. So, I just concern 
about adding the LinuxBoot module with a pre-built flashkernel image 
will violate the Linux kernel's license.

Hi Ard, do you have any idea about that?

Best regards,

Nhi

> I could go along with adding it like this for now, with an
> understanding that we would need to figure out some better solution
> medium-term.
>
> /
>      Leif
>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc | 550 ++++++++++++++++++++
>>   Platform/Ampere/JadePkg/JadeLinuxBoot.dsc                     |  90 ++++
>>   Platform/Ampere/JadePkg/JadeLinuxBoot.fdf                     | 201 +++++++
>>   3 files changed, 841 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
>> new file mode 100755
>> index 000000000000..06b2bb928fe8
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
>> @@ -0,0 +1,550 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
>> +  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x1000
>> +
>> +[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
>> +  GCC:*_*_AARCH64_DLINK_FLAGS = -z common-page-size=0x10000
>> +
>> +[BuildOptions]
>> +  GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
>> +
>> +[LibraryClasses.common]
>> +!if $(TARGET) == RELEASE
>> +  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
>> +!else
>> +  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
>> +!endif
>> +  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
>> +
>> +  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
>> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptDxe/BaseMemoryLibOptDxe.inf
>> +  SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf
>> +  SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf
>> +  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
>> +  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
>> +  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
>> +  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
>> +  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
>> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
>> +  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
>> +
>> +  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
>> +  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
>> +  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
>> +  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
>> +  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
>> +  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
>> +  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
>> +  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
>> +  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
>> +  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
>> +  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
>> +
>> +  #
>> +  # Allow dynamic PCDs
>> +  #
>> +  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
>> +
>> +  #
>> +  # ARM Architectural Libraries
>> +  #
>> +  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
>> +  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
>> +  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
>> +  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
>> +  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
>> +  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
>> +  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
>> +  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
>> +  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
>> +  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
>> +  ArmGenericTimerCounterLib|ArmPkg/Library/ArmGenericTimerPhyCounterLib/ArmGenericTimerPhyCounterLib.inf
>> +  ResetSystemLib|ArmPkg/Library/ArmSmcPsciResetSystemLib/ArmSmcPsciResetSystemLib.inf
>> +  TimerLib|ArmPkg/Library/ArmArchTimerLib/ArmArchTimerLib.inf
>> +
>> +  #
>> +  # Ampere Altra specific Libraries
>> +  #
>> +  ArmPlatformLib|Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf
>> +  PlatformPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf
>> +  NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf
>> +  MailboxInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf
>> +  SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
>> +  PciePhyLib|Silicon/Ampere/AmpereAltraBinPkg/Library/PciePhyLib/PciePhyLib.inf
>> +  PcieCoreLib|Silicon/Ampere/AmpereAltraPkg/Library/PcieCoreLib/PcieCoreLib.inf
>> +  AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>> +  TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
>> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>> +  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
>> +  MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
>> +
>> +  #
>> +  # ARM PL011 UART Driver
>> +  #
>> +  PL011UartLib|ArmPlatformPkg/Library/PL011UartLib/PL011UartLib.inf
>> +  SerialPortLib|ArmPlatformPkg/Library/PL011SerialPortLib/PL011SerialPortLib.inf
>> +  PL011UartClockLib|ArmPlatformPkg/Library/PL011UartClockLib/PL011UartClockLib.inf
>> +
>> +  #
>> +  # Uncomment (and comment out the next line) For RealView Debugger. The Standard IO window
>> +  # in the debugger will show load and unload commands for symbols. You can cut and paste this
>> +  # into the command window to load symbols. We should be able to use a script to do this, but
>> +  # the version of RVD I have does not support scripts accessing system memory.
>> +  #
>> +  #PeCoffExtraActionLib|ArmPkg/Library/RvdPeCoffExtraActionLib/RvdPeCoffExtraActionLib.inf
>> +  PeCoffExtraActionLib|ArmPkg/Library/DebugPeCoffExtraActionLib/DebugPeCoffExtraActionLib.inf
>> +  #PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
>> +
>> +  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
>> +  DebugAgentTimerLib|EmbeddedPkg/Library/DebugAgentTimerLibNull/DebugAgentTimerLibNull.inf
>> +
>> +  SemihostLib|ArmPkg/Library/SemihostLib/SemihostLib.inf
>> +
>> +  #
>> +  # BDS Libraries
>> +  #
>> +  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
>> +  PlatformBootManagerLib|Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
>> +  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
>> +  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
>> +
>> +  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf
>> +  VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf
>> +
>> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
>> +  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
>> +
>> +  ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
>> +
>> +[LibraryClasses.common.SEC]
>> +  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
>> +  DebugAgentLib|ArmPkg/Library/DebugAgentSymbolsBaseLib/DebugAgentSymbolsBaseLib.inf
>> +
>> +!ifdef $(EDK2_SKIP_PEICORE)
>> +  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
>> +  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
>> +  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
>> +  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
>> +  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
>> +  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
>> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
>> +!endif
>> +
>> +  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
>> +
>> +[LibraryClasses.common.PEI_CORE]
>> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
>> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
>> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
>> +  PeiCoreEntryPoint|MdePkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf
>> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
>> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
>> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
>> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
>> +  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>> +
>> +  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
>> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
>> +
>> +[LibraryClasses.common.PEIM]
>> +  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>> +  HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
>> +  PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
>> +  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
>> +  PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
>> +  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
>> +  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
>> +  OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
>> +  PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf
>> +  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
>> +  PeiServicesTablePointerLib|ArmPkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
>> +
>> +[LibraryClasses.common.SEC, LibraryClasses.common.PEIM]
>> +  MemoryInitPeiLib|Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf
>> +  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
>> +
>> +[LibraryClasses.common.DXE_CORE]
>> +  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
>> +  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
>> +  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
>> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
>> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
>> +  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
>> +
>> +[LibraryClasses.common.DXE_DRIVER]
>> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
>> +  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
>> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
>> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>> +
>> +[LibraryClasses.common.UEFI_APPLICATION]
>> +  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
>> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
>> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
>> +
>> +[LibraryClasses.common.UEFI_DRIVER]
>> +  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
>> +  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
>> +  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
>> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>> +
>> +[LibraryClasses.common.DXE_RUNTIME_DRIVER]
>> +  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>> +  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
>> +  ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf
>> +!if $(TARGET) != RELEASE
>> +  DebugLib|MdePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf
>> +!endif
>> +  VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf
>> +
>> +  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
>> +  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
>> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>> +
>> +[LibraryClasses.ARM,LibraryClasses.AARCH64]
>> +  #
>> +  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
>> +  # This library provides the instrinsic functions generate by a given compiler.
>> +  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
>> +  #
>> +  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
>> +
>> +  #
>> +  # Add support for GCC stack protector
>> +  #
>> +  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
>> +
>> +################################################################################
>> +#
>> +# Pcd Section - list of all EDK II PCD Entries defined by this Platform
>> +#
>> +################################################################################
>> +
>> +[PcdsFeatureFlag.common]
>> +  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|FALSE
>> +  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
>> +  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|FALSE
>> +  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
>> +
>> +  #
>> +  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at PcdCpuVectorBaseAddress
>> +  #
>> +  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
>> +
>> +  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
>> +
>> +  #
>> +  # If TRUE, Graphics Output Protocol will be installed on virtual handle
>> +  # created by ConsplitterDxe. It could be set FALSE to save size.
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|FALSE
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
>> +
>> +[PcdsFixedAtBuild.common]
>> +!ifdef $(FIRMWARE_VER)
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
>> +!endif
>> +
>> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
>> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
>> +  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
>> +  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
>> +  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
>> +  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
>> +  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
>> +  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
>> +
>> +  # DEBUG_ASSERT_ENABLED       0x01
>> +  # DEBUG_PRINT_ENABLED        0x02
>> +  # DEBUG_CODE_ENABLED         0x04
>> +  # CLEAR_MEMORY_ENABLED       0x08
>> +  # ASSERT_BREAKPOINT_ENABLED  0x10
>> +  # ASSERT_DEADLOOP_ENABLED    0x20
>> +!if $(TARGET) == RELEASE
>> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x21
>> +!else
>> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2A
>> +!endif
>> +
>> +  #
>> +  # SBSA Watchdog Count
>> +  #
>> +!ifndef DISABLE_SBSA_WATCHDOG
>> +  gArmPlatformTokenSpaceGuid.PcdWatchdogCount|1
>> +!endif
>> +
>> +  #  DEBUG_INIT      0x00000001  // Initialization
>> +  #  DEBUG_WARN      0x00000002  // Warnings
>> +  #  DEBUG_LOAD      0x00000004  // Load events
>> +  #  DEBUG_FS        0x00000008  // EFI File system
>> +  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
>> +  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
>> +  #  DEBUG_INFO      0x00000040  // Informational debug messages
>> +  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
>> +  #  DEBUG_VARIABLE  0x00000100  // Variable
>> +  #  DEBUG_BM        0x00000400  // Boot Manager
>> +  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
>> +  #  DEBUG_NET       0x00004000  // SNP Driver
>> +  #  DEBUG_UNDI      0x00010000  // UNDI Driver
>> +  #  DEBUG_LOADFILE  0x00020000  // LoadFile
>> +  #  DEBUG_EVENT     0x00080000  // Event messages
>> +  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
>> +  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
>> +  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
>> +  #                              // significantly impact boot performance
>> +  #  DEBUG_ERROR     0x80000000  // Error
>> +  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|$(DEBUG_PRINT_ERROR_LEVEL)
>> +
>> +  #
>> +  # Optional feature to help prevent EFI memory map fragments
>> +  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
>> +  # Values are in EFI Pages (4K). DXE Core will make sure that
>> +  # at least this much of each type of memory can be allocated
>> +  # from a single memory range. This way you only end up with
>> +  # maximum of two fragements for each type in the memory map
>> +  # (the memory used, and the free memory that was prereserved
>> +  # but not used).
>> +  #
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|65
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|20000
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|20
>> +  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
>> +
>> +  gArmTokenSpaceGuid.PcdVFPEnabled|1
>> +
>> +  gArmTokenSpaceGuid.PcdArmPrimaryCore|0x0
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxAuthVariableSize|0x2800
>> +
>> +  #
>> +  # Stacks for MPCores in Normal World
>> +  #
>> +  gArmPlatformTokenSpaceGuid.PcdCPUCoresStackBase|0x91100000
>> +  gArmPlatformTokenSpaceGuid.PcdCPUCorePrimaryStackSize|0x20000
>> +  gArmPlatformTokenSpaceGuid.PcdCPUCoreSecondaryStackSize|0x1000
>> +
>> +  #
>> +  # System Memory Base
>> +  #
>> +  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x90000000
>> +
>> +  #
>> +  # UEFI region size
>> +  #
>> +  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x08000000
>> +
>> +  #
>> +  # Ampere Altra Core-Cluster profile
>> +  #
>> +  gArmPlatformTokenSpaceGuid.PcdCoreCount|80
>> +  gArmPlatformTokenSpaceGuid.PcdClusterCount|40
>> +
>> +  #
>> +  # PL011 - Serial Terminal
>> +  # Ampere Altra UART0
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x100002600000
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|115200
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultReceiveFifoDepth|32
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|8
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|1
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultStopBits|1
>> +
>> +  gArmPlatformTokenSpaceGuid.PL011UartClkInHz|1843200
>> +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt|0x62
>> +
>> +  #
>> +  # PL011 - Serial Debug UART
>> +  # Ampere Altra UART2
>> +  #
>> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase|0x100002620000
>> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgUartBaudRate|115200
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
>> +
>> +  #
>> +  # ARM SBSA Watchdog
>> +  #
>> +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase|0x1000027c0000
>> +  gArmTokenSpaceGuid.PcdGenericWatchdogRefreshBase|0x1000027d0000
>> +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum|92
>> +
>> +  #
>> +  # ARM Generic Interrupt Controller
>> +  #
>> +  gArmTokenSpaceGuid.PcdGicDistributorBase|0x100100000000
>> +  gArmTokenSpaceGuid.PcdGicRedistributorsBase|0x100100140000
>> +
>> +  #
>> +  # ARM Architectural Timer Frequency
>> +  #
>> +  # Set it to 0 so that the code will read frequence from register
>> +  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|0
>> +  gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
>> +
>> +  #
>> +  # use the TTY terminal type
>> +  #
>> +  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
>> +
>> +  #
>> +  # GUID of the UI app
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
>> +
>> +  #
>> +  # ACPI table
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
>> +
>> +  #
>> +  # Enable strict image permissions for all images. (This applies
>> +  # only to images that were built with >= 4 KB section alignment.)
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdImageProtectionPolicy|0x3
>> +
>> +  #
>> +  # Enable NX memory protection for all non-code regions, including OEM and OS
>> +  # reserved ones, with the exception of LoaderData regions, of which OS loaders
>> +  # (i.e., GRUB) may assume that its contents are executable.
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdDxeNxMemoryProtectionPolicy|0xC000000000007FD1
>> +
>> +  #
>> +  # Enable the non-executable DXE stack. (This gets set up by DxeIpl)
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSetNxForStack|TRUE
>> +
>> +  #
>> +  # MmCommunication
>> +  #
>> +  gArmTokenSpaceGuid.PcdMmBufferBase|0x88300000
>> +  gArmTokenSpaceGuid.PcdMmBufferSize|0x100000
>> +
>> +[PcdsDynamicHii.common.DEFAULT]
>> +  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|L"Timeout"|gEfiGlobalVariableGuid|0x0|0
>> +
>> +[PcdsDynamicDefault.common]
>> +  #
>> +  # Fist DRAM Memory region under 4GB address range
>> +  #
>> +  gArmTokenSpaceGuid.PcdSystemMemorySize|0x70000000
>> +
>> +################################################################################
>> +#
>> +# Component Section - list of all EDK II Component Entries defined by this Platform
>> +#
>> +################################################################################
>> +
>> +[Components.common]
>> +  #
>> +  # PEI Phase modules
>> +  #
>> +  ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
>> +  MdeModulePkg/Core/Pei/PeiMain.inf
>> +  MdeModulePkg/Universal/PCD/Pei/Pcd.inf {
>> +    <LibraryClasses>
>> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
>> +  }
>> +  ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>> +  ArmPkg/Drivers/CpuPei/CpuPei.inf
>> +  UefiCpuPkg/CpuIoPei/CpuIoPei.inf
>> +  MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>> +  MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
>> +    <LibraryClasses>
>> +      NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
>> +  }
>> +
>> +  #
>> +  # DXE Phase modules
>> +  #
>> +  MdeModulePkg/Core/Dxe/DxeMain.inf {
>> +    <LibraryClasses>
>> +      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
>> +  }
>> +
>> +  #
>> +  # PCD
>> +  #
>> +  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
>> +    <LibraryClasses>
>> +      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
>> +  }
>> +
>> +  #
>> +  # Architectural Protocols
>> +  #
>> +  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
>> +  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>> +  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
>> +  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
>> +  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
>> +  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
>> +  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>> +  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
>> +
>> +  #
>> +  # Environment Variables Protocol
>> +  #
>> +  MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
>> +    <PcdsFixedAtBuild>
>> +      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
>> +    <LibraryClasses>
>> +      AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
>> +      TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
>> +      VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
>> +  }
>> +
>> +  #
>> +  # Timer
>> +  #
>> +  ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> +
>> +  #
>> +  # ARM GIC Dxe
>> +  #
>> +  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
>> +
>> +  #
>> +  # Console
>> +  #
>> +  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
>> +  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
>> +
>> +  #
>> +  # Hii Database
>> +  #
>> +  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
>> +
>> +  #
>> +  # PCIe Support
>> +  #
>> +  Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>> +
>> +  #
>> +  # Bds
>> +  #
>> +  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
>> new file mode 100755
>> index 000000000000..d3c7328fb7ed
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.dsc
>> @@ -0,0 +1,90 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +################################################################################
>> +#
>> +# Defines Section - statements that will be processed to create a Makefile.
>> +#
>> +################################################################################
>> +[Defines]
>> +  PLATFORM_NAME                  = Jade
>> +  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
>> +  PLATFORM_VERSION               = 0.1
>> +  DSC_SPECIFICATION              = 0x0001001B
>> +  OUTPUT_DIRECTORY               = Build/Jade
>> +  SUPPORTED_ARCHITECTURES        = AARCH64
>> +  BUILD_TARGETS                  = DEBUG|RELEASE
>> +  SKUID_IDENTIFIER               = DEFAULT
>> +  FLASH_DEFINITION               = Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
>> +
>> +  #
>> +  # Defines for default states.  These can be changed on the command line.
>> +  # -D FLAG=VALUE
>> +  #
>> +  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
>> +  DEFINE FIRMWARE_VER            = 0.01.001
>> +  DEFINE EDK2_SKIP_PEICORE       = TRUE
>> +
>> +# Include default Ampere Platform DSC file
>> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraLinuxBootPkg.dsc.inc
>> +
>> +#
>> +# Specific Platform Library
>> +#
>> +[LibraryClasses.common]
>> +  #
>> +  # RTC Library: Common RTC
>> +  #
>> +  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>> +
>> +  #
>> +  # Library for FailSafe support
>> +  #
>> +  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>> +
>> +  #
>> +  # ACPI Libraries
>> +  #
>> +  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
>> +  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
>> +  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
>> +
>> +  #
>> +  # Pcie Board
>> +  #
>> +  PcieBoardLib|Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
>> +
>> +[PcdsDynamicDefault.common.DEFAULT]
>> +  # SMBIOS Type 0 - BIOS Information
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
>> +
>> +#
>> +# Specific Platform Component
>> +#
>> +[Components.common]
>> +
>> +  #
>> +  # ACPI
>> +  #
>> +  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> +  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> +  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> +
>> +  #
>> +  # SMBIOS
>> +  #
>> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> +
>> +  #
>> +  # FailSafeDxe added to prevent watchdog from resetting the system
>> +  #
>> +  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
>> new file mode 100755
>> index 000000000000..aa5817ec6f4a
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/JadeLinuxBoot.fdf
>> @@ -0,0 +1,201 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +################################################################################
>> +#
>> +# FD Section
>> +# The [FD] Section is made up of the definition statements and a
>> +# description of what goes into  the Flash Device Image.  Each FD section
>> +# defines one flash "device" image.  A flash device image may be one of
>> +# the following: Removable media bootable image (like a boot floppy
>> +# image,) an Option ROM image (that would be "flashed" into an add-in
>> +# card,) a System "Flash"  image (that would be burned into a system's
>> +# flash) or an Update ("Capsule") image that will be used to update and
>> +# existing system flash.
>> +#
>> +################################################################################
>> +
>> +[FD.BL33_JADE_UEFI]
>> +BaseAddress   = 0x92000000|gArmTokenSpaceGuid.PcdFdBaseAddress  # The base address of the Firmware in NOR Flash.
>> +Size          = 0x00AC0000|gArmTokenSpaceGuid.PcdFdSize         # The size in bytes of the FLASH Device
>> +ErasePolarity = 1
>> +
>> +# This one is tricky, it must be: BlockSize * NumBlocks = Size
>> +BlockSize     = 0x10000
>> +NumBlocks     = 0xAC
>> +
>> +################################################################################
>> +#
>> +# Following are lists of FD Region layout which correspond to the locations of different
>> +# images within the flash device.
>> +#
>> +# Regions must be defined in ascending order and may not overlap.
>> +#
>> +# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
>> +# the pipe "|" character, followed by the size of the region, also in hex with the leading
>> +# "0x" characters. Like:
>> +# Offset|Size
>> +# PcdOffsetCName|PcdSizeCName
>> +# RegionType <FV, DATA, or FILE>
>> +#
>> +################################################################################
>> +
>> +0x00000000|0x00AC0000
>> +gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
>> +FV = FVMAIN_COMPACT
>> +
>> +################################################################################
>> +#
>> +# FV Section
>> +#
>> +# [FV] section is used to define what components or modules are placed within a flash
>> +# device file.  This section also defines order the components and modules are positioned
>> +# within the image.  The [FV] section consists of define statements, set statements and
>> +# module statements.
>> +#
>> +################################################################################
>> +
>> +[FV.FvMain]
>> +BlockSize          = 0x10000
>> +NumBlocks          = 0         # This FV gets compressed so make it just big enough
>> +FvAlignment        = 16        # FV alignment and FV attributes setting.
>> +ERASE_POLARITY     = 1
>> +MEMORY_MAPPED      = TRUE
>> +STICKY_WRITE       = TRUE
>> +LOCK_CAP           = TRUE
>> +LOCK_STATUS        = TRUE
>> +WRITE_DISABLED_CAP = TRUE
>> +WRITE_ENABLED_CAP  = TRUE
>> +WRITE_STATUS       = TRUE
>> +WRITE_LOCK_CAP     = TRUE
>> +WRITE_LOCK_STATUS  = TRUE
>> +READ_DISABLED_CAP  = TRUE
>> +READ_ENABLED_CAP   = TRUE
>> +READ_STATUS        = TRUE
>> +READ_LOCK_CAP      = TRUE
>> +READ_LOCK_STATUS   = TRUE
>> +FvNameGuid         = 5C60F367-A505-419A-859E-2A4FF6CA6FE5
>> +
>> +APRIORI DXE {
>> +  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>> +}
>> +
>> +  INF MdeModulePkg/Core/Dxe/DxeMain.inf
>> +  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>> +
>> +  #
>> +  # PI DXE Drivers producing Architectural Protocols (EFI Services)
>> +  #
>> +  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
>> +  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
>> +  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
>> +  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
>> +  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
>> +  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
>> +  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
>> +  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
>> +  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
>> +
>> +  #
>> +  # Environment Variables Protocol
>> +  #
>> +  INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
>> +
>> +  #
>> +  # Multiple Console IO support
>> +  #
>> +  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
>> +  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
>> +
>> +  #
>> +  # Timer
>> +  #
>> +  INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> +
>> +  #
>> +  # ARM GIC Dxe
>> +  #
>> +  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
>> +
>> +  #
>> +  # PCIe Support
>> +  #
>> +  INF Silicon/Ampere/AmpereAltraPkg/Bus/Pci/PciHostBridgeDxe/PciHostBridgeDxe.inf
>> +
>> +  #
>> +  # Linuxboot in Flash Support
>> +  #
>> +  INF Platform/Ampere/LinuxBootPkg/LinuxBoot.inf
>> +
>> +  #
>> +  # Bds
>> +  #
>> +  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
>> +
>> +  #
>> +  # Driver to handle HW Watchdog
>> +  #
>> +  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> +
>> +  #
>> +  # ACPI
>> +  #
>> +  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> +  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> +  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> +
>> +  #
>> +  # SMBIOS
>> +  #
>> +  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> +
>> +[FV.FVMAIN_COMPACT]
>> +FvAlignment        = 16
>> +ERASE_POLARITY     = 1
>> +MEMORY_MAPPED      = TRUE
>> +STICKY_WRITE       = TRUE
>> +LOCK_CAP           = TRUE
>> +LOCK_STATUS        = TRUE
>> +WRITE_DISABLED_CAP = TRUE
>> +WRITE_ENABLED_CAP  = TRUE
>> +WRITE_STATUS       = TRUE
>> +WRITE_LOCK_CAP     = TRUE
>> +WRITE_LOCK_STATUS  = TRUE
>> +READ_DISABLED_CAP  = TRUE
>> +READ_ENABLED_CAP   = TRUE
>> +READ_STATUS        = TRUE
>> +READ_LOCK_CAP      = TRUE
>> +READ_LOCK_STATUS   = TRUE
>> +
>> +APRIORI PEI {
>> +  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>> +}
>> +
>> +  INF ArmPlatformPkg/PrePeiCore/PrePeiCoreMPCore.inf
>> +  INF MdeModulePkg/Core/Pei/PeiMain.inf
>> +  INF UefiCpuPkg/CpuIoPei/CpuIoPei.inf
>> +  INF ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>> +  INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>> +  INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>> +  INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>> +
>> +  INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>> +
>> +  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
>> +    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
>> +      SECTION FV_IMAGE = FVMAIN
>> +    }
>> +  }
>> +
>> +!include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot
  2021-06-07 23:50   ` Leif Lindholm
@ 2021-06-09 15:21     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-09 15:21 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On 6/8/21 06:50, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:22 +0700, Nhi Pham wrote:
>> The PlatformBootManagerLib library derived from
>> ArmPkg/Library/PlatformBootManagerLib.
>>
>> This implementation registers only a common GUID for LinuxBoot Payload
>> ("D834A5AD-459C-4AED-B0D0-8CBCB28838D7") as a active boot option. This
>> allows BDS to jump to the LinuxBoot Shell immediately without entering
>> the UiApp Setup Screen or UEFI Shell.
> This driver does not look spectacularly platform specific to me,
> although the GUID handling could posibly do with some additional
> engineering if this was to be shared with others.
>
> Would you consider submitting it for ArmPkg for now? (Unless it's
> something for MinPlatformPkg?)

Ok, I will separate this driver and submit it for ArmPkg for now.

Best regards,

Nhi

>
> /
>      Leif
>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf |  54 ++++++
>>   Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c               | 173 ++++++++++++++++++++
>>   2 files changed, 227 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
>> new file mode 100644
>> index 000000000000..cb4ade210117
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBootManagerLib.inf
>> @@ -0,0 +1,54 @@
>> +## @file
>> +#  Implementation for PlatformBootManagerLib library class interfaces.
>> +#
>> +#  Copyright (C) 2015-2016, Red Hat, Inc.
>> +#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
>> +#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
>> +#  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
>> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x00010005
>> +  BASE_NAME                      = LinuxBootBootManagerLib
>> +  FILE_GUID                      = 1FA91547-DB23-4F6A-8AF8-3B9782A7F917
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = PlatformBootManagerLib|DXE_DRIVER
>> +
>> +#
>> +# The following information is for reference only and not required by the build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = ARM AARCH64
>> +#
>> +
>> +[Sources]
>> +  LinuxBootBm.c
>> +
>> +[Packages]
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  ShellPkg/ShellPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  MemoryAllocationLib
>> +  PrintLib
>> +  UefiBootManagerLib
>> +  UefiBootServicesTableLib
>> +  UefiLib
>> +  UefiRuntimeServicesTableLib
>> +
>> +[Pcd]
>> +
>> +[Guids]
>> +  gEfiEndOfDxeEventGroupGuid
>> +  gUefiShellFileGuid
>> +
>> +[Protocols]
>> +  gEfiLoadedImageProtocolGuid
>> diff --git a/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
>> new file mode 100644
>> index 000000000000..2d0f087477d6
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereSiliconPkg/Library/LinuxBootBootManagerLib/LinuxBootBm.c
>> @@ -0,0 +1,173 @@
>> +/** @file
>> +  Implementation for PlatformBootManagerLib library class interfaces.
>> +
>> +  Copyright (C) 2015-2016, Red Hat, Inc.
>> +  Copyright (c) 2014 - 2019, ARM Ltd. All rights reserved.<BR>
>> +  Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
>> +  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/EventGroup.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DevicePathLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/UefiBootManagerLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Protocol/LoadedImage.h>
>> +#include <Protocol/PlatformBootManager.h>
>> +
>> +// This GUID must match the FILE_GUID in the LinuxBootPkg/LinuxBoot.inf file.
>> +// GUID: D834A5AD-459C-4AED-B0D0-8CBCB28838D7
>> +EFI_GUID mLinuxBootFileGuid = { 0xD834A5AD, 0x459C, 0x4AED, { 0xB0, 0xD0, 0x8C, 0xBC, 0xB2, 0x88, 0x38, 0xD7 } };
>> +
>> +STATIC
>> +VOID
>> +RegisterFvBootOption (
>> +  CONST EFI_GUID *FileGuid,
>> +  CHAR16         *Description,
>> +  UINT32         Attributes
>> +  )
>> +{
>> +  EFI_STATUS                        Status;
>> +  INTN                              OptionIndex;
>> +  EFI_BOOT_MANAGER_LOAD_OPTION      NewOption;
>> +  EFI_BOOT_MANAGER_LOAD_OPTION      *BootOptions;
>> +  UINTN                             BootOptionCount;
>> +  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
>> +  EFI_LOADED_IMAGE_PROTOCOL         *LoadedImage;
>> +  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
>> +
>> +  Status = gBS->HandleProtocol (
>> +                  gImageHandle,
>> +                  &gEfiLoadedImageProtocolGuid,
>> +                  (VOID **)&LoadedImage
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
>> +  DevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
>> +  ASSERT (DevicePath != NULL);
>> +  DevicePath = AppendDevicePathNode (
>> +                 DevicePath,
>> +                 (EFI_DEVICE_PATH_PROTOCOL *)&FileNode
>> +                 );
>> +  ASSERT (DevicePath != NULL);
>> +
>> +  Status = EfiBootManagerInitializeLoadOption (
>> +             &NewOption,
>> +             LoadOptionNumberUnassigned,
>> +             LoadOptionTypeBoot,
>> +             Attributes,
>> +             Description,
>> +             DevicePath,
>> +             NULL,
>> +             0
>> +             );
>> +  ASSERT_EFI_ERROR (Status);
>> +  FreePool (DevicePath);
>> +
>> +  BootOptions = EfiBootManagerGetLoadOptions (
>> +                  &BootOptionCount,
>> +                  LoadOptionTypeBoot
>> +                  );
>> +
>> +  OptionIndex = EfiBootManagerFindLoadOption (
>> +                  &NewOption,
>> +                  BootOptions,
>> +                  BootOptionCount
>> +                  );
>> +
>> +  if (OptionIndex == -1) {
>> +    Status = EfiBootManagerAddLoadOptionVariable (&NewOption, MAX_UINTN);
>> +    ASSERT_EFI_ERROR (Status);
>> +  }
>> +  EfiBootManagerFreeLoadOption (&NewOption);
>> +  EfiBootManagerFreeLoadOptions (BootOptions, BootOptionCount);
>> +}
>> +
>> +/**
>> +  Do the platform specific action before the console is connected.
>> +
>> +  Such as:
>> +    Update console variable;
>> +    Register new Driver#### or Boot####;
>> +    Signal ReadyToLock event.
>> +**/
>> +VOID
>> +EFIAPI
>> +PlatformBootManagerBeforeConsole (
>> +  VOID
>> +  )
>> +{
>> +  //
>> +  // Signal EndOfDxe PI Event
>> +  //
>> +  EfiEventGroupSignal (&gEfiEndOfDxeEventGroupGuid);
>> +}
>> +
>> +/**
>> +  Do the platform specific action after the console is connected.
>> +
>> +  Such as:
>> +    Dynamically switch output mode;
>> +    Signal console ready platform customized event;
>> +    Run diagnostics like memory testing;
>> +    Connect certain devices;
>> +    Dispatch additional option roms.
>> +**/
>> +VOID
>> +EFIAPI
>> +PlatformBootManagerAfterConsole (
>> +  VOID
>> +  )
>> +{
>> +  //
>> +  // Register LinuxBoot
>> +  //
>> +  RegisterFvBootOption (
>> +    &mLinuxBootFileGuid,
>> +    L"LinuxBoot",
>> +    LOAD_OPTION_ACTIVE
>> +    );
>> +}
>> +
>> +/**
>> +  This function is called each second during the boot manager waits the
>> +  timeout.
>> +
>> +  @param TimeoutRemain  The remaining timeout.
>> +**/
>> +VOID
>> +EFIAPI
>> +PlatformBootManagerWaitCallback (
>> +  UINT16 TimeoutRemain
>> +  )
>> +{
>> +  return;
>> +}
>> +
>> +/**
>> +  The function is called when no boot option could be launched,
>> +  including platform recovery options and options pointing to applications
>> +  built into firmware volumes.
>> +
>> +  If this function returns, BDS attempts to enter an infinite loop.
>> +**/
>> +VOID
>> +EFIAPI
>> +PlatformBootManagerUnableToBoot (
>> +  VOID
>> +  )
>> +{
>> +  return;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver
  2021-06-09  5:29   ` Ard Biesheuvel
@ 2021-06-15 15:54     ` Nhi Pham
  2021-06-16 14:20       ` Ard Biesheuvel
  0 siblings, 1 reply; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 15:54 UTC (permalink / raw)
  To: Ard Biesheuvel, Leif Lindholm
  Cc: edk2-devel-groups-io, Vu Nguyen, Thang Nguyen, Chuong Tran,
	Phong Vo, Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/9/21 12:29, Ard Biesheuvel wrote:
> On Wed, 26 May 2021 at 12:12, Nhi Pham <nhi@os.amperecomputing.com> wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> The roles of this driver:
>> * Consume PcieCoreLib to initialize all enable PCIe controllers.
>> * Produce neccessary protocols like RootBridgeIo an ResourceAllocation
>>    which will be used later by PciBus.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> Why do you need a re-implementation of PciHostBridgeDxe for any of
> this? There is very little h/w specific code there, and it is all
> customizable using PciHostBridgeLib and PciSegmentLib (among others)
>
> There are a couple of examples of this in edk2-platforms - please take
> a look at those, and if that does not give you enough wiggle room,
> let's see if we can accommodate your needs in PciHostBridgeDxe itself.
>
Hi Leif, Ard,

Thanks for your comments. The current implementation which has little 
deltas comparing with the standard one has been well-tested. It's a good 
idea that we need to re-implement it based on Ard's suggestion, but it 
will take time and we need to make sure that it is well-tested 
internally before getting it out. So, we want to keep this current 
implementation but we will start looking at working the 
re-implementation in the future.

Best regards,
Nhi

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

* Re: [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and Mt. Jade platform
  2021-06-04 23:04   ` Leif Lindholm
  2021-06-09  4:50     ` Nhi Pham
@ 2021-06-15 16:46     ` Nhi Pham
  1 sibling, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:46 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Hi Leif,

On 6/5/21 06:04, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:52 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> This commit adds the support for Ampere’s Altra processor-based Mt. Jade
>> platform that provides up to 160 processor cores in a dual socket
>> configuration. The essential modules are wired up enough to boot system
>> to EDK2 UiApp.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec                                         |  28 +
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                                                |  42 ++
>>   Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                                            |  46 ++
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                            | 674 +++++++++++++++++++
>>   Platform/Ampere/JadePkg/Jade.dsc                                                                | 100 +++
>>   Platform/Ampere/JadePkg/Jade.fdf                                                                | 225 +++++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf                                  |  41 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf                         |  64 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf                             |  44 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.inf                         |  57 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.inf               |  37 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.inf                     |  63 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf                 |  35 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.inf                                 |  32 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.inf                         |  42 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.inf                                         |  29 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf |  30 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.inf                                       |  29 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Guid/PlatformInfoHobGuid.h                                |  17 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h                                    | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/MailboxInterfaceLib.h                             | 172 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h                              |  19 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/NVParamLib.h                                      | 133 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h                      | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h                                         |  31 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/MmLib.h                                                   |  79 +++
>>   Silicon/Ampere/AmpereAltraPkg/Include/NVParamDef.h                                              | 515 ++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Platform/Ac01.h                                           | 146 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Include/PlatformInfoHob.h                                         | 182 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.c                                    |  52 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.c                           | 151 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c                               | 706 ++++++++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c                           | 169 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c                     | 399 +++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c                 | 282 ++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MemoryInitPeiLib/MemoryInitPeiLib.c                       |  93 +++
>>   Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c                   | 184 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/NVParamLib.c                                   | 202 ++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/PlatformPeiLib/PlatformPeiLib.c                           |  40 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.c                                           | 141 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.c   | 328 +++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/TrngLib/TrngLib.c                                         |  63 ++
>>   Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc                                               | 176 +++++
>>   Platform/Ampere/JadePkg/JadeBoardSetting.cfg                                                    | 209 ++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformHelper.S                        |  45 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/RngLib/RngLib.uni                                         |  13 +
>>   46 files changed, 6729 insertions(+)
>>
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> new file mode 100755
>> index 000000000000..f68af24a0d78
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -0,0 +1,100 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +################################################################################
>> +#
>> +# Defines Section - statements that will be processed to create a Makefile.
>> +#
>> +################################################################################
>> +[Defines]
>> +  PLATFORM_NAME                  = Jade
>> +  PLATFORM_GUID                  = 7BDD00C0-68F3-4CC1-8775-F0F00572019F
>> +  PLATFORM_VERSION               = 0.1
>> +  DSC_SPECIFICATION              = 0x0001001B
>> +  OUTPUT_DIRECTORY               = Build/Jade
>> +  SUPPORTED_ARCHITECTURES        = AARCH64
>> +  BUILD_TARGETS                  = DEBUG|RELEASE|NOOPT
>> +  SKUID_IDENTIFIER               = DEFAULT
>> +  FLASH_DEFINITION               = Platform/Ampere/JadePkg/Jade.fdf
>> +
>> +  #
>> +  # Defines for default states. These can be changed on the command line.
>> +  # -D FLAG=VALUE
>> +  #
>> +
>> +  #  DEBUG_INIT      0x00000001  // Initialization
>> +  #  DEBUG_WARN      0x00000002  // Warnings
>> +  #  DEBUG_LOAD      0x00000004  // Load events
>> +  #  DEBUG_FS        0x00000008  // EFI File system
>> +  #  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
>> +  #  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
>> +  #  DEBUG_INFO      0x00000040  // Informational debug messages
>> +  #  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
>> +  #  DEBUG_VARIABLE  0x00000100  // Variable
>> +  #  DEBUG_BM        0x00000400  // Boot Manager
>> +  #  DEBUG_BLKIO     0x00001000  // BlkIo Driver
>> +  #  DEBUG_NET       0x00004000  // SNP Driver
>> +  #  DEBUG_UNDI      0x00010000  // UNDI Driver
>> +  #  DEBUG_LOADFILE  0x00020000  // LoadFile
>> +  #  DEBUG_EVENT     0x00080000  // Event messages
>> +  #  DEBUG_GCD       0x00100000  // Global Coherency Database changes
>> +  #  DEBUG_CACHE     0x00200000  // Memory range cachability changes
>> +  #  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
>> +  #                              // significantly impact boot performance
>> +  #  DEBUG_ERROR     0x80000000  // Error
>> +  DEFINE DEBUG_PRINT_ERROR_LEVEL = 0x8000000F
>> +  DEFINE FIRMWARE_VER            = 0.01.001
>> +  DEFINE EDK2_SKIP_PEICORE       = TRUE
>> +  DEFINE SECURE_BOOT_ENABLE      = FALSE
>> +  DEFINE INCLUDE_TFTP_COMMAND    = TRUE
>> +
>> +  #
>> +  # Network definition
>> +  #
>> +  DEFINE NETWORK_IP6_ENABLE                  = FALSE
>> +  DEFINE NETWORK_HTTP_BOOT_ENABLE            = TRUE
>> +  DEFINE NETWORK_ALLOW_HTTP_CONNECTIONS      = TRUE
>> +  DEFINE NETWORK_TLS_ENABLE                  = FALSE
>> +
> You'll want to include that !include MdePkg/MdeLibs.dsc.inc bit
> somewhere here.
Thanks. I will fix it in the v3 and test the patch set with the latest 
edk2 to check if any issue before sending it out.
>
>> +# Include default Ampere Platform DSC file
>> +!include Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Library
>> +#
>> +################################################################################
>> +[LibraryClasses]
>> +  #
>> +  # RTC Library: Common RTC
>> +  #
>> +  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Pcds
>> +#
>> +################################################################################
>> +[PcdsFeatureFlag.common]
>> +[PcdsFixedAtBuild.common]
>> +
>> +!if $(SECURE_BOOT_ENABLE) == TRUE
>> +  # Override the default values from SecurityPkg to ensure images
>> +  # from all sources are verified in secure boot
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
>> +  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
>> +!endif
>> +
>> +
>> +################################################################################
>> +#
>> +# Specific Platform Component
>> +#
>> +################################################################################
>> +[Components.common]
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>> new file mode 100644
>> index 000000000000..de576474fb48
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/AmpereCpuLib.h
>> @@ -0,0 +1,282 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef AMPERE_CPU_LIB_H_
>> +#define AMPERE_CPU_LIB_H_
>> +
>> +/* Ctypen, bits[3(n - 1) + 2 : 3(n - 1)], for n = 1 to 7 */
>> +#define CLIDR_CTYPE_SHIFT(Level)    (3 * (Level - 1))
>> +#define CLIDR_CTYPE_MASK(Level)     (7 << CLIDR_CTYPE_SHIFT(Level))
>> +#define CLIDR_CTYPE(Clidr, Level) \
>> +  (((Clidr) & CLIDR_CTYPE_MASK(Level)) >> CLIDR_CTYPE_SHIFT(Level))
>> +
>> +#define CCSIDR_NUMSETS_SHIFT        13
>> +#define CCSIDR_NUMSETS_MASK         0xFFFE000
>> +#define CCSIDR_NUMSETS(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_NUMSETS_MASK) >> CCSIDR_NUMSETS_SHIFT)
>> +#define CCSIDR_ASSOCIATIVITY_SHIFT  3
>> +#define CCSIDR_ASSOCIATIVITY_MASK   0x1FF8
>> +#define CCSIDR_ASSOCIATIVITY(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_ASSOCIATIVITY_MASK) >> CCSIDR_ASSOCIATIVITY_SHIFT)
>> +#define CCSIDR_LINE_SIZE_SHIFT      0
>> +#define CCSIDR_LINE_SIZE_MASK       0x7
>> +#define CCSIDR_LINE_SIZE(Ccsidr) \
>> +  (((Ccsidr) & CCSIDR_LINE_SIZE_MASK) >> CCSIDR_LINE_SIZE_SHIFT)
> All of the above (CLIDR/CCSIDR) are architectural.
> We've also developed some new accessors and stuff for these, as part
> of ArmPkg/Universal/SmbiosDxe work that's gone on since v1 of this set.
> We may need to clean some interfaces up, but ideally I'd prefer if you
> could use some accessors from ArmLib or such.
Yes, I will use the ArmLib for cache-related functions and definitions.
>
>> +
>> +#define SUBNUMA_MODE_MONOLITHIC        0
>> +#define SUBNUMA_MODE_HEMISPHERE        1
>> +#define SUBNUMA_MODE_QUADRANT          2
>> +
>> +#define MONOLITIC_NUM_OF_REGION        1
>> +#define HEMISPHERE_NUM_OF_REGION       2
>> +#define QUADRANT_NUM_OF_REGION         4
>> +#define SUBNUMA_CPM_REGION_SIZE        4
>> +#define NUM_OF_CPM_PER_MESH_ROW        8
>> +
>> +#define CPM_PER_ROW_OFFSET(CpmId)      ((CpmId) % NUM_OF_CPM_PER_MESH_ROW)
>> +#define CPM_ROW_NUMBER(CpmId)          ((CpmId) / NUM_OF_CPM_PER_MESH_ROW)
>> +
>> +#define SOCKET_ID(CpuId)               ((CpuId) / (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM))
>> +#define CLUSTER_ID(CpuId)              (((CpuId) / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM)
>> +
>> +
>> +/**
>> +  Get the SubNUMA mode.
>> +
>> +  @return   UINT8      The SubNUMA mode.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumaMode (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of SubNUMA region.
>> +
>> +  @return   UINT8      The number of SubNUMA region.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetNumberOfSubNumaRegion (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the SubNUMA node of a CPM.
>> +
>> +  @param    SocketId    Socket index.
>> +  @param    Cpm         CPM index.
>> +  @return   UINT8       The SubNUMA node of a CPM.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumNode (
>> +  UINT8  Socket,
>> +  UINT16 Cpm
>> +  );
>> +
>> +/**
>> +  Get the associativity of cache.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Associativity of cache.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetAssociativity (
>> +  UINT32 Level
>> +  );
>> +
>> +/**
>> +  Get the cache size.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Cache size.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetCacheSize (
>> +  UINT32 Level
>> +  );
>> +
>> +/**
>> +  Get the number of supported socket.
>> +
>> +  @return   UINT8      Number of supported socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfSupportedSockets (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active socket.
>> +
>> +  @return   UINT8      Number of active socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfActiveSockets (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCPMsPerSocket (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Get the number of configured CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of configured CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfConfiguredCPMs (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Set the number of configured CPM per socket.
>> +
>> +  @param    SocketId        Socket index.
>> +  @param    NumberOfCPMs    Number of CPM to be configured.
>> +  @return   EFI_SUCCESS     Operation succeeded.
>> +  @return   Others          An error has occurred.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SetNumberOfConfiguredCPMs (
>> +  UINT8  SocketId,
>> +  UINT16 NumberOfCPMs
>> +  );
>> +
>> +/**
>> +  Get the maximum number of core per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT16      Maximum number of core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCores (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the maximum number of CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT32      Maximum number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCPMs (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Get the number of active cores of a sockets.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCoresPerSocket (
>> +  UINT8 SocketId
>> +  );
>> +
>> +/**
>> +  Get the number of active cores of all socket.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCores (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the logical CPU is enabled or not.
>> +
>> +  @param    CpuId       The logical Cpu ID. Started from 0.
>> +  @return   BOOLEAN     TRUE if the Cpu enabled
>> +                        FALSE if the Cpu disabled.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsCpuEnabled (
>> +  UINT16 CpuId
>> +  );
>> +
>> +
>> +/**
>> +  Check if the slave socket is present
>> +
>> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
>> +                        FALSE if the Slave Cpu is not present
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketPresent (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the slave socket is active
>> +
>> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
>> +                        FALSE if the Slave CPU Socket is not active.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketActive (
>> +  VOID
>> +  );
>> +
>> +/**
>> +  Check if the CPU product ID is Ac01
>> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
>> +                        FALSE otherwise.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsAc01Processor (
>> +  VOID
>> +  );
>> +
>> +#endif /* AMPERE_CPU_LIB_H_ */
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>> new file mode 100644
>> index 000000000000..8da698e0b855
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.c
>> @@ -0,0 +1,706 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiPei.h>
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib/ArmLibPrivate.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <NVParamDef.h>
>> +#include <Platform/Ac01.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +STATIC PLATFORM_INFO_HOB *mPlatformInfoHob = NULL;
>> +
>> +PLATFORM_INFO_HOB *
>> +GetPlatformHob (
>> +  VOID
>> +  )
>> +{
>> +  VOID *Hob;
>> +
>> +  if (mPlatformInfoHob == NULL) {
>> +    Hob = GetNextGuidHob (
>> +            &gPlatformHobGuid,
>> +            (CONST VOID *)FixedPcdGet64 (PcdSystemMemoryBase)
>> +            );
>> +    ASSERT (Hob != NULL);
>> +    if (Hob == NULL) {
>> +      DEBUG ((DEBUG_ERROR, "%a: Failed to get gPlatformHobGuid!\n", __FUNCTION__));
>> +      return NULL;
>> +    }
>> +
>> +    mPlatformInfoHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +  }
>> +
>> +  return mPlatformInfoHob;
>> +}
>> +
>> +/**
>> +  Get the SubNUMA mode.
>> +
>> +  @return   UINT8      The SubNUMA mode.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumaMode (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return SUBNUMA_MODE_MONOLITHIC;
>> +  }
>> +
>> +  return PlatformHob->SubNumaMode[0];
>> +}
>> +
>> +/**
>> +  Get the number of SubNUMA region.
>> +
>> +  @return   UINT8      The number of SubNUMA region.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetNumberOfSubNumaRegion (
>> +  VOID
>> +  )
>> +{
>> +  UINT8 SubNumaMode;
>> +  UINT8 NumberOfSubNumaRegion;
>> +
>> +  SubNumaMode = CpuGetSubNumaMode ();
>> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
>> +
>> +  switch (SubNumaMode) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    NumberOfSubNumaRegion = MONOLITIC_NUM_OF_REGION;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    NumberOfSubNumaRegion = HEMISPHERE_NUM_OF_REGION;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    NumberOfSubNumaRegion = QUADRANT_NUM_OF_REGION;
>> +    break;
>> +
>> +  default:
>> +    // Should never reach there.
>> +    ASSERT (FALSE);
>> +    break;
>> +  }
>> +
>> +  return NumberOfSubNumaRegion;
>> +}
>> +
>> +/**
>> +  Get the SubNUMA node of a CPM.
>> +
>> +  @param    SocketId    Socket index.
>> +  @param    Cpm         CPM index.
>> +  @return   UINT8       The SubNUMA node of a CPM.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +CpuGetSubNumNode (
>> +  UINT8  SocketId,
>> +  UINT16 Cpm
>> +  )
>> +{
>> +  BOOLEAN IsAsymMesh;
>> +  UINT8   SubNumaNode;
>> +  UINT16  MaxNumberOfCPM;
>> +  UINT8   MiddleRow;
>> +  UINT8   QuadrantHigherRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {1, 1, 1, 1, 3, 3, 3, 3};
>> +  UINT8   QuadrantLowerRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW]  = {0, 0, 0, 0, 2, 2, 2, 2};
>> +  UINT8   QuadrantMiddleRowNodeNumber[NUM_OF_CPM_PER_MESH_ROW] = {0, 0, 1, 1, 3, 3, 2, 2};
>> +  UINT8   SubNumaMode;
>> +
>> +  MaxNumberOfCPM = GetMaximumNumberOfCPMs ();
>> +  SubNumaMode = CpuGetSubNumaMode ();
>> +  ASSERT (SubNumaMode <= SUBNUMA_MODE_QUADRANT);
>> +
>> +  switch (SubNumaMode) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    SubNumaNode = (SocketId == 0) ? 0 : 1;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    if (CPM_PER_ROW_OFFSET (Cpm) >= SUBNUMA_CPM_REGION_SIZE) {
>> +      SubNumaNode = 1;
>> +    } else {
>> +      SubNumaNode = 0;
>> +    }
>> +
>> +    if (SocketId == 1) {
>> +      SubNumaNode += HEMISPHERE_NUM_OF_REGION;
>> +    }
>> +    break;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    //
>> +    // CPM Mesh Rows
>> +    //
>> +    // |---------------------------------------|
>> +    // | 00 ----------- 03 | 04 ----------- 07 | Row 0
>> +    // |-------------------|-------------------|
>> +    // | 08 ----------- 11 | 12 ----------- 15 | Row 1
>> +    // |-------------------|-------------------|
>> +    // | 16 - 17 | 18 - 19 | 20 - 21 | 22 - 23 | Middle Row
>> +    // |-------------------|-------------------|
>> +    // | 24 ----------- 27 | 28 ----------- 31 | Row 3
>> +    // |-------------------|-------------------|
>> +    // | 32 ----------- 35 | 36 ----------- 39 | Row 4
>> +    // |---------------------------------------|
>> +    //
>> +
>> +    IsAsymMesh = (BOOLEAN)(CPM_ROW_NUMBER (MaxNumberOfCPM) % 2 != 0);
>> +    MiddleRow = CPM_ROW_NUMBER (MaxNumberOfCPM) / 2;
>> +    if (IsAsymMesh
>> +        && CPM_ROW_NUMBER (Cpm) == MiddleRow)
>> +    {
>> +      SubNumaNode = QuadrantMiddleRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +
>> +    } else if (CPM_ROW_NUMBER (Cpm) >= MiddleRow) {
>> +      SubNumaNode = QuadrantHigherRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +
>> +    } else {
>> +      SubNumaNode = QuadrantLowerRowNodeNumber[CPM_PER_ROW_OFFSET (Cpm)];
>> +    }
>> +
>> +    if (SocketId == 1) {
>> +      SubNumaNode += QUADRANT_NUM_OF_REGION;
>> +    }
>> +    break;
>> +
>> +  default:
>> +    // Should never reach there.
>> +    ASSERT (FALSE);
>> +    break;
>> +  }
>> +
>> +  return SubNumaNode;
>> +}
>> +
>> +/**
>> +  Get the associativity of cache.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Associativity of cache.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetAssociativity (
>> +  UINT32 Level
>> +  )
>> +{
> I do feel some of this stuff could be replaced by the common functions
> we now have in ArmLib (that we didn't when v1 went out).
Yes, will replace it.
>
>> +  UINT64 CacheCCSIDR;
>> +  UINT64 CacheCLIDR;
>> +  UINT32 Value = 0x2; /* Unknown Set-Associativity */
>> +
>> +  CacheCLIDR = ReadCLIDR ();
>> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
>> +    return Value;
>> +  }
>> +
>> +  CacheCCSIDR = ReadCCSIDR (Level);
>> +  switch (CCSIDR_ASSOCIATIVITY (CacheCCSIDR)) {
>> +  case 0:
>> +    /* Direct mapped */
>> +    Value = 0x3;
>> +    break;
>> +
>> +  case 1:
>> +    /* 2-way Set-Associativity */
>> +    Value = 0x4;
>> +    break;
>> +
>> +  case 3:
>> +    /* 4-way Set-Associativity */
>> +    Value = 0x5;
>> +    break;
>> +
>> +  case 7:
>> +    /* 8-way Set-Associativity */
>> +    Value = 0x7;
>> +    break;
>> +
>> +  case 15:
>> +    /* 16-way Set-Associativity */
>> +    Value = 0x8;
>> +    break;
>> +
>> +  case 11:
>> +    /* 12-way Set-Associativity */
>> +    Value = 0x9;
>> +    break;
>> +
>> +  case 23:
>> +    /* 24-way Set-Associativity */
>> +    Value = 0xA;
>> +    break;
>> +
>> +  case 31:
>> +    /* 32-way Set-Associativity */
>> +    Value = 0xB;
>> +    break;
>> +
>> +  case 47:
>> +    /* 48-way Set-Associativity */
>> +    Value = 0xC;
>> +    break;
>> +
>> +  case 63:
>> +    /* 64-way Set-Associativity */
>> +    Value = 0xD;
>> +    break;
>> +
>> +  case 19:
>> +    /* 20-way Set-Associativity */
>> +    Value = 0xE;
>> +    break;
>> +  }
>> +
>> +  return Value;
>> +}
>> +
>> +/**
>> +  Get the cache size.
>> +
>> +  @param    Level       Cache level.
>> +  @return   UINT32      Cache size.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +CpuGetCacheSize (
>> +  UINT32 Level
>> +  )
>> +{
>> +  UINT32 CacheLineSize;
>> +  UINT32 Count;
>> +  UINT64 CacheCCSIDR;
>> +  UINT64 CacheCLIDR;
>> +
>> +  CacheCLIDR = ReadCLIDR ();
>> +  if (!CLIDR_CTYPE (CacheCLIDR, Level)) {
>> +    return 0;
>> +  }
>> +
>> +  CacheCCSIDR = ReadCCSIDR (Level);
>> +  CacheLineSize = 1;
>> +  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
>> +  while (Count-- > 0) {
>> +    CacheLineSize *= 2;
>> +  }
>> +
>> +  return ((CCSIDR_NUMSETS (CacheCCSIDR) + 1) *
>> +          (CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1) *
>> +          CacheLineSize);
>> +}
>> +
>> +/**
>> +  Get the number of supported socket.
>> +
>> +  @return   UINT8      Number of supported socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfSupportedSockets (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    //
>> +    // By default, the number of supported sockets is 1.
>> +    //
>> +    return 1;
>> +  }
>> +
>> +  return (sizeof (PlatformHob->ClusterEn) / sizeof (PLATFORM_CLUSTER_EN));
>> +}
>> +
>> +/**
>> +  Get the number of active socket.
>> +
>> +  @return   UINT8      Number of active socket.
>> +
>> +**/
>> +UINT8
>> +EFIAPI
>> +GetNumberOfActiveSockets (
>> +  VOID
>> +  )
>> +{
>> +  UINT8               NumberOfActiveSockets, Count, Index, Index1;
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    //
>> +    // By default, the number of active sockets is 1.
>> +    //
>> +    return 1;
>> +  }
>> +
>> +  NumberOfActiveSockets = 0;
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    Socket = &PlatformHob->ClusterEn[Index];
>> +    Count = ARRAY_SIZE (Socket->EnableMask);
>> +    for (Index1 = 0; Index1 < Count; Index1++) {
>> +      if (Socket->EnableMask[Index1] != 0) {
>> +        NumberOfActiveSockets++;
>> +        break;
>> +      }
>> +    }
>> +  }
>> +
>> +  return NumberOfActiveSockets;
>> +}
>> +
>> +/**
>> +  Get the number of active CPM per socket.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT16      Number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCPMsPerSocket (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  UINT16              NumberOfCPMs, Count, Index;
>> +  UINT32              Val32;
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return 0;
>> +  }
>> +
>> +  if (SocketId >= GetNumberOfActiveSockets ()) {
>> +    return 0;
>> +  }
>> +
>> +  NumberOfCPMs = 0;
>> +  Socket = &PlatformHob->ClusterEn[SocketId];
>> +  Count = ARRAY_SIZE (Socket->EnableMask);
>> +  for (Index = 0; Index < Count; Index++) {
>> +    Val32 = Socket->EnableMask[Index];
>> +    while (Val32 > 0) {
>> +      if ((Val32 & 0x1) != 0) {
>> +        NumberOfCPMs++;
>> +      }
>> +      Val32 >>= 1;
>> +    }
>> +  }
>> +
>> +  return NumberOfCPMs;
>> +}
>> +
>> +/**
>> +  Get the number of configured CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @param    SocketId    Socket index.
>> +  @return   UINT8       Number of configured CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfConfiguredCPMs (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +  UINT32     Param, ParamStart, ParamEnd;
>> +  UINT16     Count;
>> +
>> +  Count = 0;
>> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
>> +    Status = NVParamGet (
>> +               Param,
>> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +               &Value
>> +               );
>> +    if (EFI_ERROR (Status)) {
>> +      break;
>> +    }
>> +    while (Value != 0) {
>> +      if ((Value & 0x01) != 0) {
>> +        Count++;
>> +      }
>> +      Value >>= 1;
>> +    }
>> +  }
>> +
>> +  return Count;
>> +}
>> +
>> +/**
>> +  Set the number of configured CPM per socket.
>> +
>> +  @param    SocketId        Socket index.
>> +  @param    NumberOfCPMs    Number of CPM to be configured.
>> +  @return   EFI_SUCCESS     Operation succeeded.
>> +  @return   Others          An error has occurred.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SetNumberOfConfiguredCPMs (
>> +  UINT8  SocketId,
>> +  UINT16 NumberOfCPMs
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +  UINT32     Param, ParamStart, ParamEnd;
>> +  BOOLEAN    IsClear;
>> +
>> +  IsClear = FALSE;
>> +  if (NumberOfCPMs == 0) {
>> +    IsClear = TRUE;
>> +  }
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  ParamStart = NV_SI_S0_PCP_ACTIVECPM_0_31 + SocketId * NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  ParamEnd = ParamStart + NV_PARAM_ENTRYSIZE * (PLATFORM_CPU_MAX_CPM / 32);
>> +  for (Param = ParamStart; Param < ParamEnd; Param += NV_PARAM_ENTRYSIZE) {
>> +    if (NumberOfCPMs >= 32) {
>> +      Value = 0xffffffff;
>> +      NumberOfCPMs -= 32;
>> +    } else {
>> +      Value = 0;
>> +      while (NumberOfCPMs > 0) {
>> +        Value |= (1 << (--NumberOfCPMs));
>> +      }
>> +    }
>> +    if (IsClear) {
>> +      /* Clear this param */
>> +      Status = NVParamClr (
>> +                 Param,
>> +                 NV_PERM_BIOS | NV_PERM_MANU
>> +                 );
>> +    } else {
>> +      Status = NVParamSet (
>> +                 Param,
>> +                 NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +                 NV_PERM_BIOS | NV_PERM_MANU,
>> +                 Value
>> +                 );
>> +    }
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Get the maximum number of core per socket.
>> +
>> +  @return   UINT16      Maximum number of core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCores (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return 0;
>> +  }
>> +
>> +  return PlatformHob->MaxNumOfCore[0];
>> +}
>> +
>> +/**
>> +  Get the maximum number of CPM per socket. This number
>> +  should be the same for all sockets.
>> +
>> +  @return   UINT16      Maximum number of CPM.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetMaximumNumberOfCPMs (
>> +  VOID
>> +  )
>> +{
>> +  return GetMaximumNumberOfCores () / PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +}
>> +
>> +/**
>> +  Get the number of active cores of a sockets.
>> +
>> +  @param    SocketId    Socket Index.
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCoresPerSocket (
>> +  UINT8 SocketId
>> +  )
>> +{
>> +  return GetNumberOfActiveCPMsPerSocket (SocketId) * PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +}
>> +
>> +/**
>> +  Get the number of active cores of all sockets.
>> +
>> +  @return   UINT16      Number of active core.
>> +
>> +**/
>> +UINT16
>> +EFIAPI
>> +GetNumberOfActiveCores (
>> +  VOID
>> +  )
>> +{
>> +  UINT16 NumberOfActiveCores;
>> +  UINT8  Index;
>> +
>> +  NumberOfActiveCores = 0;
>> +
>> +  for (Index = 0; Index < GetNumberOfActiveSockets (); Index++) {
>> +    NumberOfActiveCores += GetNumberOfActiveCoresPerSocket (Index);
>> +  }
>> +
>> +  return NumberOfActiveCores;
>> +}
>> +
>> +/**
>> +  Check if the logical CPU is enabled or not.
>> +
>> +  @param    CpuId       The logical Cpu ID. Started from 0.
>> +  @return   BOOLEAN     TRUE if the Cpu enabled
>> +                        FALSE if the Cpu disabled.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsCpuEnabled (
>> +  UINT16 CpuId
>> +  )
>> +{
>> +  PLATFORM_CLUSTER_EN *Socket;
>> +  PLATFORM_INFO_HOB   *PlatformHob;
>> +  UINT8               SocketId;
>> +  UINT16              ClusterId;
>> +
>> +  SocketId = SOCKET_ID (CpuId);
>> +  ClusterId = CLUSTER_ID (CpuId);
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  if (PlatformHob == NULL) {
>> +    return FALSE;
>> +  }
>> +
>> +  if (SocketId >= GetNumberOfActiveSockets ()) {
>> +    return FALSE;
>> +  }
>> +
>> +  Socket = &PlatformHob->ClusterEn[SocketId];
>> +  if ((Socket->EnableMask[ClusterId / 32] & (1 << (ClusterId % 32))) != 0) {
>> +    return TRUE;
>> +  }
>> +
>> +  return FALSE;
>> +}
>> +
>> +/**
>> +  Check if the slave socket is present
>> +
>> +  @return   BOOLEAN     TRUE if the Slave Cpu is present
>> +                        FALSE if the Slave Cpu is not present
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketPresent (
>> +  VOID
>> +  )
>> +{
>> +  UINT32 Value;
>> +
>> +  Value = MmioRead32 (SMPRO_EFUSE_SHADOW0 + CFG2P_OFFSET);
>> +
>> +  return ((Value & SLAVE_PRESENT_N) != 0) ? FALSE : TRUE;
>> +}
>> +
>> +/**
>> +  Check if the slave socket is active
>> +
>> +  @return   BOOLEAN     TRUE if the Slave CPU Socket is active.
>> +                        FALSE if the Slave CPU Socket is not active.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsSlaveSocketActive (
>> +  VOID
>> +  )
>> +{
>> +  return (GetNumberOfActiveSockets () > 1) ? TRUE : FALSE;
>> +}
>> +
>> +/**
>> +  Check if the CPU product ID is Ac01
>> +  @return   BOOLEAN     TRUE if the Product ID is Ac01
>> +                        FALSE otherwise.
>> +
>> +**/
>> +BOOLEAN
>> +EFIAPI
>> +IsAc01Processor (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  PlatformHob = GetPlatformHob ();
>> +  ASSERT (PlatformHob != NULL);
>> +
>> +  if (PlatformHob != NULL) {
>> +    if ((PlatformHob->ScuProductId[0] & 0xFF) == 0x01) {
>> +      return TRUE;
>> +    }
>> +  }
>> +
>> +  return FALSE;
>> +}
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>> new file mode 100644
>> index 000000000000..8c1eb93f00fd
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLib.c
>> @@ -0,0 +1,169 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/ArmPlatformLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PL011UartLib.h>
>> +#include <Library/SerialPortLib.h>
>> +#include <Platform/Ac01.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Ppi/ArmMpCoreInfo.h>
>> +#include <Ppi/TemporaryRamSupport.h>
>> +
>> +ARM_CORE_INFO mArmPlatformMpCoreInfoTable[PLATFORM_CPU_MAX_NUM_CORES];
>> +
>> +/**
>> +  Return the current Boot Mode
>> +
>> +  This function returns the boot reason on the platform
>> +
>> +  @return   Return the current Boot Mode of the platform
>> +
>> +**/
>> +EFI_BOOT_MODE
>> +ArmPlatformGetBootMode (
>> +  VOID
>> +  )
>> +{
>> +  return BOOT_WITH_FULL_CONFIGURATION;
>> +}
>> +
>> +/**
>> +  Initialize controllers that must setup in the normal world
>> +
>> +  This function is called by the ArmPlatformPkg/PrePi or ArmPlatformPkg/PlatformPei
>> +  in the PEI phase.
>> +
>> +**/
>> +EFI_STATUS
>> +ArmPlatformInitialize (
>> +  IN UINTN MpId
>> +  )
>> +{
>> +  RETURN_STATUS      Status;
>> +  UINT64             BaudRate;
>> +  UINT32             ReceiveFifoDepth;
>> +  EFI_PARITY_TYPE    Parity;
>> +  UINT8              DataBits;
>> +  EFI_STOP_BITS_TYPE StopBits;
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  if (FixedPcdGet64 (PcdSerialRegisterBase) != 0) {
>> +    /* Debug port should use the same parameters with console */
>> +    BaudRate = FixedPcdGet64 (PcdUartDefaultBaudRate);
>> +    ReceiveFifoDepth = FixedPcdGet32 (PcdUartDefaultReceiveFifoDepth);
>> +    Parity = (EFI_PARITY_TYPE)FixedPcdGet8 (PcdUartDefaultParity);
>> +    DataBits = FixedPcdGet8 (PcdUartDefaultDataBits);
>> +    StopBits = (EFI_STOP_BITS_TYPE)FixedPcdGet8 (PcdUartDefaultStopBits);
>> +
>> +    /* Initialize uart debug port */
>> +    Status = PL011UartInitializePort (
>> +               (UINTN)FixedPcdGet64 (PcdSerialRegisterBase),
>> +               FixedPcdGet32 (PL011UartClkInHz),
>> +               &BaudRate,
>> +               &ReceiveFifoDepth,
>> +               &Parity,
>> +               &DataBits,
>> +               &StopBits
>> +               );
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +PrePeiCoreGetMpCoreInfo (
>> +  OUT UINTN         *CoreCount,
>> +  OUT ARM_CORE_INFO **ArmCoreTable
>> +  )
>> +{
>> +  UINTN              mArmPlatformCoreCount;
>> +  UINTN              ClusterId;
>> +  UINTN              SocketId;
>> +  UINTN              Index;
>> +
>> +  ASSERT (CoreCount != NULL);
>> +  ASSERT (ArmCoreTable != NULL);
>> +  ASSERT (*ArmCoreTable != NULL);
>> +
>> +  mArmPlatformCoreCount = 0;
>> +  for  (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index++) {
>> +    if (!IsCpuEnabled (Index)) {
>> +      continue;
>> +    }
>> +    SocketId = SOCKET_ID (Index);
>> +    ClusterId = CLUSTER_ID (Index);
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].ClusterId = SocketId;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].CoreId =
>> +      (ClusterId << 8) | (Index % PLATFORM_CPU_NUM_CORES_PER_CPM);
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearAddress = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxClearValue = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxGetAddress = 0;
>> +    mArmPlatformMpCoreInfoTable[mArmPlatformCoreCount].MailboxSetAddress = 0;
>> +    mArmPlatformCoreCount++;
>> +  }
>> +
>> +  *CoreCount = mArmPlatformCoreCount;
>> +
>> +  *ArmCoreTable = mArmPlatformMpCoreInfoTable;
>> +  ASSERT (*ArmCoreTable != NULL);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +// Needs to be declared in the file. Otherwise gArmMpCoreInfoPpiGuid is undefined in the contect of PrePeiCore
>> +EFI_GUID             mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
>> +ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
>> +
>> +EFI_PEI_PPI_DESCRIPTOR gPlatformPpiTable[] = {
>> +  {
>> +    EFI_PEI_PPI_DESCRIPTOR_PPI,
>> +    &mArmMpCoreInfoPpiGuid,
>> +    &mMpCoreInfoPpi
>> +  },
>> +};
>> +
>> +/**
>> +  Return the Platform specific PPIs
>> +
>> +  This function exposes the Platform Specific PPIs. They can be used by any PrePi modules or passed
>> +  to the PeiCore by PrePeiCore.
>> +
>> +  @param[out]   PpiListSize         Size in Bytes of the Platform PPI List
>> +  @param[out]   PpiList             Platform PPI List
>> +
>> +**/
>> +VOID
>> +ArmPlatformGetPlatformPpiList (
>> +  OUT UINTN                  *PpiListSize,
>> +  OUT EFI_PEI_PPI_DESCRIPTOR **PpiList
>> +  )
>> +{
>> +  ASSERT (PpiListSize != NULL);
>> +  ASSERT (PpiList != NULL);
>> +  ASSERT (*PpiList != NULL);
>> +
>> +  if (ArmIsMpCore ()) {
>> +    *PpiListSize = sizeof (gPlatformPpiTable);
>> +    *PpiList = gPlatformPpiTable;
>> +  } else {
>> +    *PpiListSize = 0;
>> +    *PpiList = NULL;
>> +  }
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>> new file mode 100644
>> index 000000000000..117c9cc56ac2
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/ArmPlatformLib/ArmPlatformLibMemory.c
>> @@ -0,0 +1,399 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmPlatformLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +/* Number of Virtual Memory Map Descriptors */
>> +#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS          50
>> +
>> +/* DDR attributes */
>> +#define DDR_ATTRIBUTES_CACHED           ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
>> +#define DDR_ATTRIBUTES_UNCACHED         ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
>> +
>> +/**
>> +  Return the Virtual Memory Map of your platform
>> +
>> +  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
>> +
>> +  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
>> +                                    Virtual Memory mapping. This array must be ended by a zero-filled
>> +                                    entry
>> +
>> +**/
>> +VOID
>> +ArmPlatformGetVirtualMemoryMap (
>> +  OUT ARM_MEMORY_REGION_DESCRIPTOR **VirtualMemoryMap
>> +  )
>> +{
>> +  UINTN                        Index = 0;
>> +  ARM_MEMORY_REGION_DESCRIPTOR *VirtualMemoryTable;
>> +  UINT32                       NumRegion;
>> +  UINTN                        Count;
>> +  VOID                         *Hob;
>> +  PLATFORM_INFO_HOB            *PlatformHob;
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  ASSERT (Hob != NULL);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  ASSERT (VirtualMemoryMap != NULL);
>> +
>> +  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR *)AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
>> +  if (VirtualMemoryTable == NULL) {
>> +    return;
>> +  }
>> +
>> +  /* For Address space 0x1000_0000_0000 to 0x1001_00FF_FFFF
>> +   *  - Device memory
>> +   */
>> +  VirtualMemoryTable[Index].PhysicalBase = 0x100000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x100000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x102000000ULL;
> Please move all of these live-coded addresses/sizes to a private .h
> and use symbolic names here.

Will define them in a private header file.

>
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /* For Address space 0x5000_0000_0000 to 0x5001_00FF_FFFF
>> +   *  - Device memory
>> +   */
>> +  if (IsSlaveSocketActive ())
>> +  {
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x500000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x500000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x101000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +  }
>> +
>> +  /*
>> +   *  - PCIe RCA0 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x300000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x300000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x20000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x20000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA1 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x340000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x340000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x28000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x28000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA2 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x380000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x380000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x30000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x30000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCA3 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x3C0000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x3C0000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCA3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x38000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x38000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB0 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x200000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x200000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x00000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x00000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB1 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x240000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x240000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x08000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x08000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB2 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x280000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x280000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x10000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x10000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - PCIe RCB3 Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x2C0000000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x2C0000000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket0 RCB3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCB1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x18000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x18000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  if (IsSlaveSocketActive ()) {
>> +    // Slave socket exist
>> +    /*
>> +     *  - PCIe RCA0 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x700000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x700000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA1 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x740000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x740000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA2 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x780000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x780000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCA3 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x7C0000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x7C0000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB0 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x600000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x600000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB1 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x640000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x640000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB2 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x680000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x680000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +    /*
>> +     *  - PCIe RCB3 Device memory
>> +     */
>> +    VirtualMemoryTable[++Index].PhysicalBase = 0x6C0000000000ULL;
>> +    VirtualMemoryTable[Index].VirtualBase  = 0x6C0000000000ULL;
>> +    VirtualMemoryTable[Index].Length       = 0x40000000000ULL;
>> +    VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +  }
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x60000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x60000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA2 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x68000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x68000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x70000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x70000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCA3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA3 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x78000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x78000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB0 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x40000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x40000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB1 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA0 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x48000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x48000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB2 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x50000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x50000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - 2P/PCIe Socket1 RCB3 32-bit Device memory
>> +   *  - 1P/PCIe consolidated to RCA1 32-bit Device memory
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x58000000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x58000000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x8000000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - BERT memory region
>> +   */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0x88230000ULL;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0x88230000ULL;
>> +  VirtualMemoryTable[Index].Length       = 0x50000ULL;
>> +  VirtualMemoryTable[Index].Attributes   = ARM_MEMORY_REGION_ATTRIBUTE_DEVICE;
>> +
>> +  /*
>> +   *  - DDR memory region
>> +   */
>> +  NumRegion = PlatformHob->DramInfo.NumRegion;
>> +  Count = 0;
>> +  while (NumRegion-- > 0) {
>> +    if (PlatformHob->DramInfo.NvdRegion[Count]) { /* Skip NVDIMM Region */
>> +      Count++;
>> +      continue;
>> +    }
>> +
>> +    VirtualMemoryTable[++Index].PhysicalBase = PlatformHob->DramInfo.Base[Count];
>> +    VirtualMemoryTable[Index].VirtualBase  = PlatformHob->DramInfo.Base[Count];
>> +    VirtualMemoryTable[Index].Length       = PlatformHob->DramInfo.Size[Count];
>> +    VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
>> +    Count++;
>> +  }
>> +
>> +  /* SPM MM NS Buffer for MmCommunicateDxe */
>> +  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdMmBufferBase);
>> +  VirtualMemoryTable[Index].VirtualBase  = PcdGet64 (PcdMmBufferBase);
>> +  VirtualMemoryTable[Index].Length       = PcdGet64 (PcdMmBufferSize);
>> +  VirtualMemoryTable[Index].Attributes   = DDR_ATTRIBUTES_CACHED;
>> +
>> +  /* End of Table */
>> +  VirtualMemoryTable[++Index].PhysicalBase = 0;
>> +  VirtualMemoryTable[Index].VirtualBase  = 0;
>> +  VirtualMemoryTable[Index].Length       = 0;
>> +  VirtualMemoryTable[Index].Attributes   = (ARM_MEMORY_REGION_ATTRIBUTES)0;
>> +
>> +  ASSERT ((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
>> +
>> +  *VirtualMemoryMap = VirtualMemoryTable;
>> +}
>
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>> new file mode 100644
>> index 000000000000..0da1f90699f6
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MailboxInterfaceLib/MailboxInterfaceLib.c
>> @@ -0,0 +1,282 @@
>> +/** @file
>> +  The library implements the hardware Mailbox (Doorbell) interface for communication
>> +  between the Application Processor (ARMv8) and the System Control Processors (SMpro/PMpro).
>> +
>> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MailboxInterfaceLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/IoLib.h>
>> +
>> +//
>> +// Hardware Doorbells
>> +//
>> +#define SMPRO_DB0_IRQ_OFST               40
>> +#define SMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdSmproDbBaseReg))
>> +
>> +#define PMPRO_DB0_IRQ_OFST               56
>> +#define PMPRO_DB0_BASE_ADDRESS           (FixedPcdGet64 (PcdPmproDbBaseReg))
>> +
>> +#define SLAVE_SOCKET_BASE_ADDRESS_OFFSET 0x400000000000
>> +
>> +//
>> +// The base SPI interrupt number of the Slave socket
>> +//
>> +#define SLAVE_SOCKET_SPI_INTERRUPT 352
>> +
>> +#define SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE(Socket) ((Socket) * SLAVE_SOCKET_SPI_INTERRUPT - 32)
>> +
>> +//
>> +// Doorbell base register stride size
>> +//
>> +#define DB_BASE_REG_STRIDE 0x00001000
>> +
>> +#define SMPRO_DBx_ADDRESS(socket, db) \
>> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + SMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
>> +
>> +#define PMPRO_DBx_ADDRESS(socket, db) \
>> +        ((socket) * SLAVE_SOCKET_BASE_ADDRESS_OFFSET + PMPRO_DB0_BASE_ADDRESS + DB_BASE_REG_STRIDE * (db))
>> +
>> +//
>> +// Doorbell Status Bits
>> +//
>> +#define DB_STATUS_AVAIL_BIT       BIT16
>> +#define DB_STATUS_ACK_BIT         BIT0
>> +
>> +/**
>> +  Get the base address of a doorbell.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +
>> +  @retval UINT32                The base address of the doorbell.
>> +                                The returned value is 0 indicate that the input parameters are invalid.
>> +
>> +**/
>> +UINTN
>> +EFIAPI
>> +MailboxGetDoorbellAddress (
>> +  IN UINT8             Socket,
>> +  IN DOORBELL_CHANNELS Doorbell
>> +  )
>> +{
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return 0;
>> +  }
> Coding style is
>   if () {
>   }
>
> This file gets it consistently wrong.
>
>> +
>> +  if (Doorbell >= SMproDoorbellChannel0) {
>> +    DoorbellAddress = SMPRO_DBx_ADDRESS (Socket, (UINT8)(Doorbell - SMproDoorbellChannel0));
>> +  } else {
>> +    DoorbellAddress = PMPRO_DBx_ADDRESS (Socket, (UINT8)Doorbell);
>> +  }
>> +
>> +  return DoorbellAddress;
>> +}
>> +
>> +/**
>> +  Get the interrupt number of a doorbell.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +
>> +  @retval UINT32                The interrupt number.
>> +                                The returned value is 0 indicate that the input parameters are invalid.
>> +
>> +**/
>> +UINT32
>> +EFIAPI
>> +MailboxGetDoorbellInterruptNumber (
>> +  IN UINT8             Socket,
>> +  IN DOORBELL_CHANNELS Doorbell
>> +  )
>> +{
>> +  UINT32 DoorbellInterruptNumber;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return 0;
>> +  }
>> +
>> +  DoorbellInterruptNumber = 0;
>> +
>> +  if (Socket > 0) {
>> +    DoorbellInterruptNumber = SLAVE_SOCKET_DOORBELL_INTERRUPT_BASE (Socket);
>> +  }
>> +
>> +  if (Doorbell >= SMproDoorbellChannel0) {
>> +    DoorbellInterruptNumber += SMPRO_DB0_IRQ_OFST + (UINT8)(Doorbell - SMproDoorbellChannel0);
>> +  } else {
>> +    DoorbellInterruptNumber += PMPRO_DB0_IRQ_OFST + (UINT8)Doorbell;
>> +  }
>> +
>> +  return DoorbellInterruptNumber;
>> +}
>> +
>> +/**
>> +  Read a message via the hardware Doorbell interface.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbell channel for communication with the SMpro/PMpro.
>> +  @param[out] Message           Pointer to the Mailbox message.
>> +
>> +  @retval EFI_SUCCESS           Read the message successfully.
>> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for available message in the mailbox.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxRead (
>> +  IN  UINT8                Socket,
>> +  IN  DOORBELL_CHANNELS    Doorbell,
>> +  OUT MAILBOX_MESSAGE_DATA *Message
>> +  )
>> +{
>> +  UINTN TimeoutCount;
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
>> +      || Message == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  TimeoutCount = MAILBOX_POLL_COUNT;
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  //
>> +  // Polling Doorbell status
>> +  //
>> +  while ((MmioRead32 ((DoorbellAddress + DB_STATUS_REG_OFST)) & DB_STATUS_AVAIL_BIT) == 0) {
>> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
>> +    if (--TimeoutCount == 0) {
>> +      return EFI_TIMEOUT;
>> +    }
>> +  }
>> +
>> +  Message->ExtendedData[0] = MmioRead32 (DoorbellAddress + DB_DIN0_REG_OFST);
>> +  Message->ExtendedData[1] = MmioRead32 (DoorbellAddress + DB_DIN1_REG_OFST);
>> +  Message->Data = MmioRead32 (DoorbellAddress + DB_IN_REG_OFST);
>> +
>> +  //
>> +  // Write 1 to clear the AVAIL status
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_AVAIL_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Write a message via the hardware Doorbell interface.
>> +
>> +  @param[in]  Socket            Active socket index.
>> +  @param[in]  Doorbell          Doorbel channel for communication with the SMpro/PMpro.
>> +  @param[in]  Message           Pointer to the Mailbox message.
>> +
>> +  @retval EFI_SUCCESS           Write the message successfully.
>> +  @retval EFI_TIMEOUT           Timeout occurred when waiting for acknowledge signal from the mailbox.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxWrite (
>> +  IN UINT8                Socket,
>> +  IN DOORBELL_CHANNELS    Doorbell,
>> +  IN MAILBOX_MESSAGE_DATA *Message
>> +  )
>> +{
>> +  UINTN TimeoutCount;
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET
>> +      || Message == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  TimeoutCount = MAILBOX_POLL_COUNT;
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  //
>> +  // Clear previous pending ack if any
>> +  //
>> +  if ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) != 0) {
>> +    MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
>> +  }
>> +
>> +  //
>> +  // Send message
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_DOUT0_REG_OFST, Message->ExtendedData[0]);
>> +  MmioWrite32 (DoorbellAddress + DB_DOUT1_REG_OFST, Message->ExtendedData[1]);
>> +  MmioWrite32 (DoorbellAddress + DB_OUT_REG_OFST, Message->Data);
>> +
>> +  //
>> +  // Wait for ACK
>> +  //
>> +  while ((MmioRead32 (DoorbellAddress + DB_STATUS_REG_OFST) & DB_STATUS_ACK_BIT) == 0) {
>> +    MicroSecondDelay (MAILBOX_POLL_INTERVAL_US);
>> +    if (--TimeoutCount == 0) {
>> +      return EFI_TIMEOUT;
>> +    }
>> +  }
>> +
>> +  //
>> +  // Write 1 to clear the ACK status
>> +  //
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_REG_OFST, DB_STATUS_ACK_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Unmask the Doorbell interrupt status.
>> +
>> +  @param  Socket    Active socket index.
>> +  @param  Doorbell  Doorbel channel for communication with the SMpro/PMpro.
>> +
>> +  @retval EFI_SUCCESS            Unmask the Doorbell interrupt successfully.
>> +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MailboxUnmaskInterrupt (
>> +  IN UINT8  Socket,
>> +  IN UINT16 Doorbell
>> +  )
>> +{
>> +  UINTN DoorbellAddress;
>> +
>> +  if (Socket >= GetNumberOfActiveSockets ()
>> +      || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +  ASSERT (DoorbellAddress != 0);
>> +
>> +  MmioWrite32 (DoorbellAddress + DB_STATUS_MASK_REG_OFST, ~DB_STATUS_AVAIL_BIT);
>> +
>> +  return EFI_SUCCESS;
>> +}
>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>> new file mode 100644
>> index 000000000000..bf400ec0a835
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.c
>> @@ -0,0 +1,184 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <IndustryStandard/ArmStdSmc.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/ArmSmcLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MmCommunicationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Protocol/MmCommunication.h>
>> +
>> +//
>> +// Address, Length of the pre-allocated buffer for communication with the secure
>> +// world.
>> +//
>> +STATIC ARM_MEMORY_REGION_DESCRIPTOR mNsCommBuffMemRegion;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +MmCommunicationLibConstructor (
>> +  VOID
>> +  )
>> +{
>> +  mNsCommBuffMemRegion.PhysicalBase = PcdGet64 (PcdMmBufferBase);
>> +  // During boot , Virtual and Physical are same
> Ideally, use UEFI-defined terms. "During boot" is quite ambiguous.
Will fix it.
>
>
>> +  mNsCommBuffMemRegion.VirtualBase = mNsCommBuffMemRegion.PhysicalBase;
>> +  mNsCommBuffMemRegion.Length = PcdGet64 (PcdMmBufferSize);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Communicates with a registered handler.
>> +
>> +  This function provides an interface to send and receive messages to the
>> +  Standalone MM environment in UEFI PEI phase.
>> +
>> +  @param[in, out] CommBuffer          A pointer to the buffer to convey
>> +                                      into MMRAM.
>> +  @param[in, out] CommSize            The size of the data buffer being
>> +                                      passed in. This is optional.
>> +
>> +  @retval EFI_SUCCESS                 The message was successfully posted.
>> +  @retval EFI_INVALID_PARAMETER       The CommBuffer was NULL.
>> +  @retval EFI_BAD_BUFFER_SIZE         The buffer size is incorrect for the MM
>> +                                      implementation. If this error is
>> +                                      returned, the MessageLength field in
>> +                                      the CommBuffer header or the integer
>> +                                      pointed by CommSize are updated to reflect
>> +                                      the maximum payload size the
>> +                                      implementation can accommodate.
>> +  @retval EFI_ACCESS_DENIED           The CommunicateBuffer parameter
>> +                                      or CommSize parameter, if not omitted,
>> +                                      are in address range that cannot be
>> +                                      accessed by the MM environment
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +MmCommunicationCommunicate (
>> +  IN OUT VOID  *CommBuffer,
>> +  IN OUT UINTN *CommSize OPTIONAL
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_HEADER *CommunicateHeader;
>> +  ARM_SMC_ARGS              CommunicateSmcArgs;
>> +  EFI_STATUS                Status;
>> +  UINTN                     BufferSize;
>> +
>> +  Status = EFI_ACCESS_DENIED;
>> +  BufferSize = 0;
>> +
>> +  ZeroMem (&CommunicateSmcArgs, sizeof (ARM_SMC_ARGS));
>> +
>> +  //
>> +  // Check parameters
>> +  //
>> +  if (CommBuffer == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  CommunicateHeader = CommBuffer;
>> +  // CommBuffer is a mandatory parameter. Hence, Rely on
>> +  // MessageLength + Header to ascertain the
>> +  // total size of the communication payload rather than
>> +  // rely on optional CommSize parameter
>> +  BufferSize = CommunicateHeader->MessageLength +
>> +               sizeof (CommunicateHeader->HeaderGuid) +
>> +               sizeof (CommunicateHeader->MessageLength);
>> +
>> +  // If the length of the CommBuffer is 0 then return the expected length.
>> +  if (CommSize != NULL) {
>> +    // This case can be used by the consumer of this driver to find out the
>> +    // max size that can be used for allocating CommBuffer.
>> +    if ((*CommSize == 0) ||
>> +        (*CommSize > mNsCommBuffMemRegion.Length))
>> +    {
> { at end of preceding line.
> Please address throughout this file.
>
>> +      *CommSize = mNsCommBuffMemRegion.Length;
>> +      return EFI_BAD_BUFFER_SIZE;
>> +    }
>> +    //
>> +    // CommSize must match MessageLength + sizeof (EFI_MM_COMMUNICATE_HEADER);
>> +    //
>> +    if (*CommSize != BufferSize) {
>> +      return EFI_INVALID_PARAMETER;
>> +    }
>> +  }
>> +
>> +  //
>> +  // If the buffer size is 0 or greater than what can be tolerated by the MM
>> +  // environment then return the expected size.
>> +  //
>> +  if ((BufferSize == 0) ||
>> +      (BufferSize > mNsCommBuffMemRegion.Length))
>> +  {
>> +    CommunicateHeader->MessageLength = mNsCommBuffMemRegion.Length -
>> +                                       sizeof (CommunicateHeader->HeaderGuid) -
>> +                                       sizeof (CommunicateHeader->MessageLength);
>> +    return EFI_BAD_BUFFER_SIZE;
>> +  }
>> +
>> +  // SMC Function ID
>> +  CommunicateSmcArgs.Arg0 = ARM_SMC_ID_MM_COMMUNICATE_AARCH64;
>> +
>> +  // Cookie
>> +  CommunicateSmcArgs.Arg1 = 0;
>> +
>> +  // Copy Communication Payload
>> +  CopyMem ((VOID *)mNsCommBuffMemRegion.VirtualBase, CommBuffer, BufferSize);
>> +
>> +  // comm_buffer_address (64-bit physical address)
>> +  CommunicateSmcArgs.Arg2 = (UINTN)mNsCommBuffMemRegion.PhysicalBase;
>> +
>> +  // comm_size_address (not used, indicated by setting to zero)
>> +  CommunicateSmcArgs.Arg3 = 0;
>> +
>> +  // Call the Standalone MM environment.
>> +  ArmCallSmc (&CommunicateSmcArgs);
>> +
>> +  switch (CommunicateSmcArgs.Arg0) {
>> +  case ARM_SMC_MM_RET_SUCCESS:
>> +    ZeroMem (CommBuffer, BufferSize);
>> +    // On successful return, the size of data being returned is inferred from
>> +    // MessageLength + Header.
>> +    CommunicateHeader = (EFI_MM_COMMUNICATE_HEADER *)mNsCommBuffMemRegion.VirtualBase;
>> +    BufferSize = CommunicateHeader->MessageLength +
>> +                 sizeof (CommunicateHeader->HeaderGuid) +
>> +                 sizeof (CommunicateHeader->MessageLength);
>> +
>> +    CopyMem (
>> +      CommBuffer,
>> +      (VOID *)mNsCommBuffMemRegion.VirtualBase,
>> +      BufferSize
>> +      );
>> +    Status = EFI_SUCCESS;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_INVALID_PARAMS:
>> +    Status = EFI_INVALID_PARAMETER;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_DENIED:
>> +    Status = EFI_ACCESS_DENIED;
>> +    break;
>> +
>> +  case ARM_SMC_MM_RET_NO_MEMORY:
>> +    // Unexpected error since the CommSize was checked for zero length
>> +    // prior to issuing the SMC
>> +    Status = EFI_OUT_OF_RESOURCES;
>> +    ASSERT (0);
>> +    break;
>> +
>> +  default:
>> +    Status = EFI_ACCESS_DENIED;
>> +    ASSERT (0);
>> +  }
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/JadeBoardSetting.cfg b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>> new file mode 100644
>> index 000000000000..5a67e8fc6a75
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/JadeBoardSetting.cfg
>> @@ -0,0 +1,209 @@
>> +# Sample board setting
>> +#
>> +# This is a sample board setting as used for the
>> +# Ampere Altra reference design.
> What is a board setting?

Board Settings is a collection of board and hardware configurations for 
an Altra-based ARM64 platform. It is stored in the persistent storage.

Will add that description to this file.
>
>> +#
>> +# Name, offset (hex), value
>> +# value can be hex or decimal
>> +#
>> +
>> +NV_SI_RO_BOARD_VENDOR, 0x0000, 0x0000CD3A
>> +NV_SI_RO_BOARD_TYPE, 0x0008, 0x00000000
>> +NV_SI_RO_BOARD_REV, 0x0010, 0x00000000
>> +NV_SI_RO_BOARD_CFG, 0x0018, 0x00000000
>> +NV_SI_RO_BOARD_S0_DIMM_AVAIL, 0x0020, 0x0000FFFF
>> +NV_SI_RO_BOARD_S1_DIMM_AVAIL, 0x0028, 0x0000FFFF
>> +NV_SI_RO_BOARD_SPI0CS0_FREQ_KHZ, 0x0030, 0x000080E8
>> +NV_SI_RO_BOARD_SPI0CS1_FREQ_KHZ, 0x0038, 0x000080E8
>> +NV_SI_RO_BOARD_SPI1CS0_FREQ_KHZ, 0x0040, 0x00002710
>> +NV_SI_RO_BOARD_SPI1CS1_FREQ_KHZ, 0x0048, 0x00002710
>> +NV_SI_RO_BOARD_TPM_LOC, 0x0050, 0x00000000
>> +NV_SI_RO_BOARD_I2C0_FREQ_KHZ, 0x0058, 0x00000190
>> +NV_SI_RO_BOARD_I2C1_FREQ_KHZ, 0x0060, 0x00000190
>> +NV_SI_RO_BOARD_I2C2_10_FREQ_KHZ, 0x0068, 0x00000190
>> +NV_SI_RO_BOARD_I2C3_FREQ_KHZ, 0x0070, 0x00000190
>> +NV_SI_RO_BOARD_I2C9_FREQ_KHZ, 0x0078, 0x00000190
>> +NV_SI_RO_BOARD_2P_CFG, 0x0080, 0xFFFFFF01
>> +NV_SI_RO_BOARD_S0_RCA0_CFG, 0x0088, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA1_CFG, 0x0090, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA2_CFG, 0x0098, 0x00000004
>> +NV_SI_RO_BOARD_S0_RCA3_CFG, 0x00A0, 0x00000004
>> +NV_SI_RO_BOARD_S0_RCB0_LO_CFG, 0x00A8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB0_HI_CFG, 0x00B0, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB1_LO_CFG, 0x00B8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB1_HI_CFG, 0x00C0, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB2_LO_CFG, 0x00C8, 0x00020002
>> +NV_SI_RO_BOARD_S0_RCB2_HI_CFG, 0x00D0, 0x00000003
>> +NV_SI_RO_BOARD_S0_RCB3_LO_CFG, 0x00D8, 0x00000003
>> +NV_SI_RO_BOARD_S0_RCB3_HI_CFG, 0x00E0, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCA0_CFG, 0x00E8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA1_CFG, 0x00F0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA2_CFG, 0x00F8, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA3_CFG, 0x0100, 0x00030003
>> +NV_SI_RO_BOARD_S1_RCB0_LO_CFG, 0x0108, 0x00000003
>> +NV_SI_RO_BOARD_S1_RCB0_HI_CFG, 0x0110, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB1_LO_CFG, 0x0118, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB1_HI_CFG, 0x0120, 0x00000003
>> +NV_SI_RO_BOARD_S1_RCB2_LO_CFG, 0x0128, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB2_HI_CFG, 0x0130, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB3_LO_CFG, 0x0138, 0x00020002
>> +NV_SI_RO_BOARD_S1_RCB3_HI_CFG, 0x0140, 0x00020002
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P0, 0x0148, 0x00000001
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P1, 0x0150, 0x00000002
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P2, 0x0158, 0x00000003
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_P3, 0x0160, 0x00000004
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M1, 0x0168, 0xFFFFFFFF
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M2, 0x0170, 0xFFFFFFFE
>> +NV_SI_RO_BOARD_T_LTLM_DELTA_M3, 0x0178, 0xFFFFFFFD
>> +NV_SI_RO_BOARD_P_LM_PID_P, 0x0180, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I, 0x0188, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I_L_THOLD, 0x0190, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_I_H_THOLD, 0x0198, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_PID_D, 0x01A0, 0x00000000
>> +NV_SI_RO_BOARD_P_LM_EXP_SMOOTH_CONST, 0x01A8, 0x00000000
>> +NV_SI_RO_BOARD_TPM_ALG_ID, 0x01B0, 0x00000002
>> +NV_SI_RO_BOARD_DDR_SPEED_GRADE, 0x01B8, 0x00000C80
>> +NV_SI_RO_BOARD_DDR_S0_RTT_WR, 0x01C0, 0x00020000
>> +NV_SI_RO_BOARD_DDR_S1_RTT_WR, 0x01C8, 0x00020000
>> +NV_SI_RO_BOARD_DDR_S0_RTT_NOM, 0x01D0, 0xFF060177
>> +NV_SI_RO_BOARD_DDR_S1_RTT_NOM, 0x01D8, 0xFF060177
>> +NV_SI_RO_BOARD_DDR_S0_RTT_PARK, 0x01E0, 0x00060070
>> +NV_SI_RO_BOARD_DDR_S1_RTT_PARK, 0x01E8, 0x00060070
>> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_1DPC, 0x01F0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_1DPC, 0x01F8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_1DPC, 0x0200, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_1DPC, 0x0208, 0x00000000
>> +NV_SI_RO_BOARD_DDR_CS0_RDODT_MASK_2DPC, 0x0210, 0x000C0CCC
>> +NV_SI_RO_BOARD_DDR_CS1_RDODT_MASK_2DPC, 0x0218, 0x000C0CCC
>> +NV_SI_RO_BOARD_DDR_CS2_RDODT_MASK_2DPC, 0x0220, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS3_RDODT_MASK_2DPC, 0x0228, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_1DPC, 0x0230, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_1DPC, 0x0238, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_1DPC, 0x0240, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_1DPC, 0x0248, 0x00030333
>> +NV_SI_RO_BOARD_DDR_CS0_WRODT_MASK_2DPC, 0x0250, 0x000EDEED
>> +NV_SI_RO_BOARD_DDR_CS1_WRODT_MASK_2DPC, 0x0258, 0x000DEDDE
>> +NV_SI_RO_BOARD_DDR_CS2_WRODT_MASK_2DPC, 0x0260, 0x000B7BB7
>> +NV_SI_RO_BOARD_DDR_CS3_WRODT_MASK_2DPC, 0x0268, 0x0007B77B
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_1DPC, 0x0270, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_1DPC, 0x0278, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_1DPC, 0x0280, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_1DPC, 0x0288, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_CTRL_2DPC, 0x0290, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQ_VAL_2DPC, 0x0298, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_CTRL_2DPC, 0x02A0, 0x00000005
>> +NV_SI_RO_BOARD_DDR_PHY_TERM_DQS_VAL_2DPC, 0x02A8, 0x0090DD90
>> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_1DPC, 0x02B0, 0x00000024
>> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_1DPC, 0x02B8, 0x0000001A
>> +NV_SI_RO_BOARD_DDR_PHY_VREFDQ_RANGE_VAL_2DPC, 0x02C0, 0x00000050
>> +NV_SI_RO_BOARD_DDR_DRAM_VREFDQ_RANGE_VAL_2DPC, 0x02C8, 0x00000020
>> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_DEFAULT, 0x02D0, 0x02800280
>> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_DEFAULT, 0x02D8, 0x90909090
>> +NV_SI_RO_BOARD_DDR_WRDQS_SHIFT_DEFAULT, 0x02E0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_ADCMD_DLY_DEFAULT, 0x02E8, 0x00C000C0
>> +NV_SI_RO_BOARD_DDR_CLK_WRDQ_DLY_ADJ, 0x02F0, 0x00000000
>> +NV_SI_RO_BOARD_DDR_RDDQS_DQ_DLY_ADJ, 0x02F8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_VREF_ADJ, 0x0300, 0x00000000
>> +NV_SI_RO_BOARD_DDR_DRAM_VREF_ADJ, 0x0308, 0x00000000
>> +NV_SI_RO_BOARD_DDR_WR_PREAMBLE_CYCLE, 0x0310, 0x02010201
>> +NV_SI_RO_BOARD_DDR_ADCMD_2T_MODE, 0x0318, 0x00000000
>> +NV_SI_RO_BOARD_I2C_VRD_CONFIG_INFO, 0x0320, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_FEATURE_CTRL, 0x0328, 0x00000000
>> +NV_SI_RO_BOARD_BMC_HANDSHAKE_SPI_ACCESS, 0x0330, 0x01050106
>> +NV_SI_RO_BOARD_DIMM_TEMP_THRESHOLD, 0x0338, 0x000005F4
>> +NV_SI_RO_BOARD_DIMM_SPD_COMPARE_DISABLE, 0x0340, 0x00000000
>> +NV_SI_RO_BOARD_S0_PCIE_CLK_CFG, 0x0348, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA4_CFG, 0x0350, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA5_CFG, 0x0358, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA6_CFG, 0x0360, 0x02020202
>> +NV_SI_RO_BOARD_S0_RCA7_CFG, 0x0368, 0x02020003
>> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET, 0x0370, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G3PRESET, 0x0378, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G3PRESET, 0x0380, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G3PRESET, 0x0388, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET, 0x0390, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G3PRESET, 0x0398, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G3PRESET, 0x03A0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G3PRESET, 0x03A8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G3PRESET, 0x03B0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G3PRESET, 0x03B8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G3PRESET, 0x03C0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G3PRESET, 0x03C8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET, 0x03D0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G3PRESET, 0x03D8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G3PRESET, 0x03E0, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G3PRESET, 0x03E8, 0x00000000
>> +NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET, 0x03F0, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA1_TXRX_G4PRESET, 0x03F8, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA2_TXRX_G4PRESET, 0x0400, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA3_TXRX_G4PRESET, 0x0408, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET, 0x0410, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB0B_TXRX_G4PRESET, 0x0418, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB1A_TXRX_G4PRESET, 0x0420, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB1B_TXRX_G4PRESET, 0x0428, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB2A_TXRX_G4PRESET, 0x0430, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB2B_TXRX_G4PRESET, 0x0438, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB3A_TXRX_G4PRESET, 0x0440, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCB3B_TXRX_G4PRESET, 0x0448, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET, 0x0450, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA5_TXRX_G4PRESET, 0x0458, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA6_TXRX_G4PRESET, 0x0460, 0x57575757
>> +NV_SI_RO_BOARD_S0_RCA7_TXRX_G4PRESET, 0x0468, 0x57575757
>> +NV_SI_RO_BOARD_S1_PCIE_CLK_CFG, 0x0470, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA4_CFG, 0x0478, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA5_CFG, 0x0480, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA6_CFG, 0x0488, 0x02020202
>> +NV_SI_RO_BOARD_S1_RCA7_CFG, 0x0490, 0x02020003
>> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET, 0x0498, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G3PRESET, 0x04A0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET, 0x04A8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G3PRESET, 0x04B0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G3PRESET, 0x04B8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G3PRESET, 0x04C0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G3PRESET, 0x04C8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G3PRESET, 0x04D0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G3PRESET, 0x04D8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G3PRESET, 0x04E0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET, 0x04E8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G3PRESET, 0x04F0, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G3PRESET, 0x04F8, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G3PRESET, 0x0500, 0x00000000
>> +NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET, 0x0508, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA3_TXRX_G4PRESET, 0x0510, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET, 0x0518, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB0B_TXRX_G4PRESET, 0x0520, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB1A_TXRX_G4PRESET, 0x0528, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB1B_TXRX_G4PRESET, 0x0530, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB2A_TXRX_G4PRESET, 0x0538, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB2B_TXRX_G4PRESET, 0x0540, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB3A_TXRX_G4PRESET, 0x0548, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCB3B_TXRX_G4PRESET, 0x0550, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET, 0x0558, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA5_TXRX_G4PRESET, 0x0560, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA6_TXRX_G4PRESET, 0x0568, 0x57575757
>> +NV_SI_RO_BOARD_S1_RCA7_TXRX_G4PRESET, 0x0570, 0x57575757
>> +NV_SI_RO_BOARD_2P_CE_MASK_THRESHOLD, 0x0578, 0x00000003
>> +NV_SI_RO_BOARD_2P_CE_MASK_INTERVAL, 0x0580, 0x000001A4
>> +NV_SI_RO_BOARD_SX_PHY_CFG_SETTING, 0x0588, 0x00000000
>> +NV_SI_RO_BOARD_DDR_PHY_DC_CLK, 0x0590, 0x00018000
>> +NV_SI_RO_BOARD_DDR_PHY_DC_DATA, 0x0598, 0x80018000
>> +NV_SI_RO_BOARD_SX_RCA0_TXRX_20GPRESET, 0x05A0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA1_TXRX_20GPRESET, 0x05A8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA2_TXRX_20GPRESET, 0x05B0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA3_TXRX_20GPRESET, 0x05B8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA0_TXRX_25GPRESET, 0x05C0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA1_TXRX_25GPRESET, 0x05C8, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA2_TXRX_25GPRESET, 0x05D0, 0x00000000
>> +NV_SI_RO_BOARD_SX_RCA3_TXRX_25GPRESET, 0x05D8, 0x00000000
>> +NV_SI_RO_BOARD_DDR_2X_REFRESH_TEMP_THRESHOLD, 0x05E0, 0x00550055
>> +NV_SI_RO_BOARD_PCP_VRD_VOUT_WAIT_US, 0x05E8, 0x00000064
>> +NV_SI_RO_BOARD_PCP_VRD_VOUT_RESOLUTION_MV, 0x05F0, 0x00000005
>> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_EN, 0x05F8, 0x00000001
>> +NV_SI_RO_BOARD_DVFS_VOLT_READ_BACK_TIME, 0x0600, 0x00000002
>> +NV_SI_RO_BOARD_DVFS_VOUT_20MV_RAMP_TIME_US, 0x0608, 0x00000005
>> +NV_SI_RO_BOARD_PCIE_AER_FW_FIRST, 0x0610, 0x00000000
>> +NV_SI_RO_BOARD_RTC_GPI_LOCK_BYPASS, 0x0618, 0x00000000
>> +NV_SI_RO_BOARD_TPM_DISABLE, 0x0620, 0x00000000
>> +NV_SI_RO_BOARD_MESH_S0_CXG_RC_STRONG_ORDERING_EN, 0x0628, 0x00000000
>> +NV_SI_RO_BOARD_MESH_S1_CXG_RC_STRONG_ORDERING_EN, 0x0630, 0x00000000
>> +NV_SI_RO_BOARD_GPIO_SW_WATCHDOG_EN, 0x0638, 0x00000000
> There was also a few things in this patch where I felt names had
> insufficient namespace - such as starting with TRNG_ or NV_.
> I'm not going to insist on adding prefixes to those, I'm just going to
> say I have warned you, and those might get you in trouble in the
> future :)

Thanks, Leif. Will keep that in mind when I have a new implementation in 
the future.

Best regards,

Nhi

>
> Best Regards,
>
> Leif

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

* Re: [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support
  2021-06-04 23:12   ` Leif Lindholm
@ 2021-06-15 16:47     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:47 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

Hi Leif,

On 6/5/21 06:12, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:56 +0700, Nhi Pham wrote:
>> The FailSafeDxe driver reverts the system's configuration to known good
>> values if the system fails to boot up multiple times. It also implements
>> the Watchdog Timer Architectural Protocol to reset the system if it
>> hangs.
>>
>> By default, when system starts, it configures the secure watchdog timer
>> with a default value of 5 minutes. If the system boots up cleanly to the
>> considered good stage, the counter is cleared as it indicates FailSafe
>> monitor (ATF) that has booted up successfully. If the timer expires, it
>> is considered a failed boot and system is rebooted.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                  |   1 -
>>   Platform/Ampere/JadePkg/Jade.dsc                                      |   9 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                      |   6 +-
>>   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf |  54 +++
>>   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h      |  20 ++
>>   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h      |  29 ++
>>   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c   | 184 ++++++++++
>>   Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c      | 357 ++++++++++++++++++++
>>   8 files changed, 658 insertions(+), 2 deletions(-)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 0332473b59b0..6a6f72e995af 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -585,7 +585,6 @@ [Components.common]
>>     # Timer
>>     #
>>     ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> -  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> It's not clear from the commit message why this should happen.
>
>>   
>>     #
>>     # ARM GIC Dxe
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index f68af24a0d78..f92855af99ab 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -75,6 +75,11 @@ [LibraryClasses]
>>     #
>>     RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>>   
>> +  #
>> +  # Library for FailSafe support
>> +  #
>> +  FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>> +
>>   ################################################################################
>>   #
>>   # Specific Platform Pcds
>> @@ -98,3 +103,7 @@ [PcdsFixedAtBuild.common]
>>   #
>>   ################################################################################
>>   [Components.common]
>> +  #
>> +  # FailSafe and Watchdog Timer
>> +  #
>> +  Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 905289844378..80a86d7c1156 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -185,7 +185,11 @@ [FV.FvMain]
>>     # Timer
>>     #
>>     INF ArmPkg/Drivers/TimerDxe/TimerDxe.inf
>> -  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
> It's not clear from the commit message why this should happen.

The Watchdog protocol which is implemented in this Failsafe driver will 
replace the WatchdogTimer.inf. I will update the commit message to 
clarify this.

Best regards,

Nhi

>
> /
>      Leif
>
>> +
>> +  #
>> +  # FailSafe and Watchdog Timer
>> +  #
>> +  INF Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>>   
>>     #
>>     # ARM GIC Dxe
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> new file mode 100755
>> index 000000000000..60de10c95c85
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> @@ -0,0 +1,54 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = FailSafeDxe
>> +  FILE_GUID                      = 7BC4F970-B1CF-11E6-80F5-76304DEC7EB7
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = FailSafeDxeEntryPoint
>> +
>> +[Sources]
>> +  FailSafe.h
>> +  FailSafeDxe.c
>> +  Watchdog.c
>> +  Watchdog.h
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Platform/Ampere/AmperePlatformPkg/AmperePlatformPkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  ArmSmcLib
>> +  DebugLib
>> +  FailSafeLib
>> +  NVParamLib
>> +  PcdLib
>> +  TimerLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +  UefiRuntimeServicesTableLib
>> +
>> +[Pcd]
>> +  gArmTokenSpaceGuid.PcdGenericWatchdogControlBase
>> +  gArmTokenSpaceGuid.PcdGenericWatchdogEl2IntrNum
>> +
>> +[Protocols]
>> +  gEfiWatchdogTimerArchProtocolGuid             ## PRODUCES
>> +  gHardwareInterrupt2ProtocolGuid               ## CONSUMES
>> +
>> +[Depex]
>> +  gHardwareInterrupt2ProtocolGuid
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>> new file mode 100644
>> index 000000000000..8bf3a98f1d8e
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafe.h
>> @@ -0,0 +1,20 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef FAILSAFE_H_
>> +#define FAILSAFE_H_
>> +
>> +#include <Uefi.h>
>> +
>> +BOOLEAN
>> +EFIAPI
>> +IsFailSafeOff (
>> +  VOID
>> +  );
>> +
>> +#endif /* FAILSAFE_H_ */
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>> new file mode 100755
>> index 000000000000..6c9106fdbea5
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.h
>> @@ -0,0 +1,29 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef GENERIC_WATCHDOG_H_
>> +#define GENERIC_WATCHDOG_H_
>> +
>> +#include <Protocol/WatchdogTimer.h>
>> +
>> +/* The number of 100ns periods (the unit of time passed to these functions)
>> +   in a second */
>> +#define TIME_UNITS_PER_SECOND           10000000
>> +
>> +/**
>> +  The function to install Watchdog timer protocol to the system
>> +
>> +  @retval  Return         EFI_SUCCESS if install Watchdog timer protocol successfully.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerInstallProtocol (
>> +  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
>> +  );
>> +
>> +#endif /* GENERIC_WATCHDOG_H_ */
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>> new file mode 100644
>> index 000000000000..1b8978b12ea7
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.c
>> @@ -0,0 +1,184 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/EventGroup.h>
>> +#include <Library/ArmSmcLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/FailSafeLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +
>> +#include "FailSafe.h"
>> +#include "Watchdog.h"
>> +
>> +STATIC UINTN                            gWatchdogOSTimeout;
>> +STATIC BOOLEAN                          gFailSafeOff;
>> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FailSafeTestBootFailure (
>> +  VOID
>> +  );
>> +
>> +STATIC VOID
>> +FailSafeTurnOff (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  if (IsFailSafeOff ()) {
>> +    return;
>> +  }
>> +
>> +  Status = FailSafeBootSuccessfully ();
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  gFailSafeOff = TRUE;
>> +
>> +  /* Disable Watchdog timer */
>> +  gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
>> +}
>> +
>> +BOOLEAN
>> +EFIAPI
>> +IsFailSafeOff (
>> +  VOID
>> +  )
>> +{
>> +  return gFailSafeOff;
>> +}
>> +
>> +/**
>> +  The function to disable Watchdog timer when enter Setup screen
>> + **/
>> +VOID
>> +WdtTimerEnterSetupScreenCallback (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  /* Make sure FailSafe is turned off */
>> +  FailSafeTurnOff ();
>> +}
>> +
>> +/**
>> +  The function to refresh Watchdog timer in the event before booting
>> + **/
>> +VOID
>> +WdtTimerBeforeBootCallback (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  /*
>> +   * At this point, the system is considered boot successfully to BIOS
>> +   */
>> +  FailSafeTurnOff ();
>> +
>> +  /*
>> +   * It is BIOS's responsibility to setup Watchdog when load an EFI application
>> +   * after this step
>> +   */
>> +}
>> +
>> +/**
>> +  The function to refresh Watchdog timer in the event before exiting boot services
>> + **/
>> +VOID
>> +WdtTimerExitBootServiceCallback (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +
>> +  /* Enable Watchdog timer for OS booting */
>> +  if (gWatchdogOSTimeout != 0) {
>> +    gWatchdogTimer->SetTimerPeriod (
>> +                      gWatchdogTimer,
>> +                      gWatchdogOSTimeout * TIME_UNITS_PER_SECOND
>> +                      );
>> +  } else {
>> +    /* Disable Watchdog timer */
>> +    gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, 0);
>> +  }
>> +}
>> +
>> +/**
>> +  This function is a hook called when user loads the manufacturing
>> +  or optimal defaults.
>> +
>> +  @param Defaults : (NVRAM_VARIABLE *)optimal or manufacturing
>> +  @Data           : Messagebox
>> +
>> +  @retval VOID
>> +**/
>> +VOID
>> +LoadNVRAMDefaultConfig (
>> +  IN VOID  *Defaults,
>> +  IN UINTN Data
>> +  )
>> +{
>> +  NVParamClrAll ();
>> +}
>> +
>> +/**
>> +  Main entry for this driver.
>> +
>> +  @param ImageHandle     Image handle this driver.
>> +  @param SystemTable     Pointer to SystemTable.
>> +
>> +  @retval EFI_SUCESS     This function always complete successfully.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FailSafeDxeEntryPoint (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_EVENT  ExitBootServicesEvent;
>> +  EFI_STATUS Status;
>> +
>> +  gFailSafeOff = FALSE;
>> +
>> +  FailSafeTestBootFailure ();
>> +
>> +  /* We need to setup non secure Watchdog to ensure that the system will
>> +   * boot to OS successfully.
>> +   *
>> +   * The BIOS doesn't handle Watchdog interrupt so we expect WS1 asserted EL3
>> +   * when Watchdog timeout triggered
>> +   */
>> +
>> +  Status = WatchdogTimerInstallProtocol (&gWatchdogTimer);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  // FIXME: We should register a callback function before entering to Setup screen
>> +  // rather than always call it at DXE phase.
>> +  FailSafeTurnOff ();
>> +
>> +  /* Register event before exit boot services */
>> +  Status = gBS->CreateEvent (
>> +                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
>> +                  TPL_NOTIFY,
>> +                  WdtTimerExitBootServiceCallback,
>> +                  NULL,
>> +                  &ExitBootServicesEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>> new file mode 100644
>> index 000000000000..34329d04206a
>> --- /dev/null
>> +++ b/Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/Watchdog.c
>> @@ -0,0 +1,357 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/ArmGenericTimerCounterLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Protocol/HardwareInterrupt2.h>
>> +
>> +#include "FailSafe.h"
>> +#include "Watchdog.h"
>> +
>> +/* Watchdog timer controller registers */
>> +#define WDT_CTRL_BASE_REG                     FixedPcdGet64 (PcdGenericWatchdogControlBase)
>> +#define WDT_CTRL_WCS_OFF                      0x0
>> +#define WDT_CTRL_WCS_ENABLE_MASK              0x1
>> +#define WDT_CTRL_WOR_OFF                      0x8
>> +#define WDT_CTRL_WCV_OFF                      0x10
>> +#define WS0_INTERRUPT_SOURCE                  FixedPcdGet32 (PcdGenericWatchdogEl2IntrNum)
>> +
>> +STATIC UINT64                           mNumTimerTicks;
>> +STATIC EFI_HARDWARE_INTERRUPT2_PROTOCOL *mInterruptProtocol;
>> +BOOLEAN                                 mInterruptWS0Enabled;
>> +
>> +STATIC
>> +VOID
>> +WatchdogTimerWriteOffsetRegister (
>> +  UINT32 Value
>> +  )
>> +{
>> +  MmioWrite32 (WDT_CTRL_BASE_REG + WDT_CTRL_WOR_OFF, Value);
>> +}
>> +
>> +STATIC
>> +VOID
>> +WatchdogTimerWriteCompareRegister (
>> +  UINT64 Value
>> +  )
>> +{
>> +  MmioWrite64 (WDT_CTRL_BASE_REG + WDT_CTRL_WCV_OFF, Value);
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +WatchdogTimerEnable (
>> +  IN BOOLEAN Enable
>> +  )
>> +{
>> +  UINT32 Val =  MmioRead32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF));
>> +
>> +  if (Enable) {
>> +    Val |= WDT_CTRL_WCS_ENABLE_MASK;
>> +  } else {
>> +    Val &= ~WDT_CTRL_WCS_ENABLE_MASK;
>> +  }
>> +  MmioWrite32 ((UINTN)(WDT_CTRL_BASE_REG + WDT_CTRL_WCS_OFF), Val);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +WatchdogTimerSetup (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  /* Disable Watchdog timer */
>> +  WatchdogTimerEnable (FALSE);
>> +
>> +  if (!mInterruptWS0Enabled) {
>> +    Status = mInterruptProtocol->EnableInterruptSource (
>> +                                   mInterruptProtocol,
>> +                                   WS0_INTERRUPT_SOURCE
>> +                                   );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    mInterruptWS0Enabled = TRUE;
>> +  }
>> +
>> +  if (mNumTimerTicks == 0) {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  /* If the number of required ticks is greater than the max the Watchdog's
>> +     offset register (WOR) can hold, we need to manually compute and set
>> +     the compare register (WCV) */
>> +  if (mNumTimerTicks > MAX_UINT32) {
>> +    /* We need to enable the Watchdog *before* writing to the compare register,
>> +       because enabling the Watchdog causes an "explicit refresh", which
>> +       clobbers the compare register (WCV). In order to make sure this doesn't
>> +       trigger an interrupt, set the offset to max. */
>> +    WatchdogTimerWriteOffsetRegister (MAX_UINT32);
>> +    WatchdogTimerEnable (TRUE);
>> +    WatchdogTimerWriteCompareRegister (ArmGenericTimerGetSystemCount () + mNumTimerTicks);
>> +  } else {
>> +    WatchdogTimerWriteOffsetRegister ((UINT32)mNumTimerTicks);
>> +    WatchdogTimerEnable (TRUE);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +
>> +/* This function is called when the Watchdog's first signal (WS0) goes high.
>> +   It uses the ResetSystem Runtime Service to reset the board.
>> +*/
>> +VOID
>> +EFIAPI
>> +WatchdogTimerInterruptHandler (
>> +  IN HARDWARE_INTERRUPT_SOURCE Source,
>> +  IN EFI_SYSTEM_CONTEXT        SystemContext
>> +  )
>> +{
>> +  STATIC CONST CHAR16 ResetString[]= L"The generic Watchdog timer ran out.";
>> +
>> +  mInterruptProtocol->EndOfInterrupt (mInterruptProtocol, Source);
>> +
>> +  if (!IsFailSafeOff ()) {
>> +    /* Not handling interrupt as ATF is monitoring it */
>> +    return;
>> +  }
>> +
>> +  WatchdogTimerEnable (FALSE);
>> +
>> +  gRT->ResetSystem (
>> +         EfiResetCold,
>> +         EFI_TIMEOUT,
>> +         StrSize (ResetString),
>> +         (VOID *)&ResetString
>> +         );
>> +
>> +  /* If we got here then the reset didn't work */
>> +  ASSERT (FALSE);
>> +}
>> +
>> +/**
>> +  This function registers the handler NotifyFunction so it is called every time
>> +  the Watchdog timer expires.  It also passes the amount of time since the last
>> +  handler call to the NotifyFunction.
>> +  If NotifyFunction is not NULL and a handler is not already registered,
>> +  then the new handler is registered and EFI_SUCCESS is returned.
>> +  If NotifyFunction is NULL, and a handler is already registered,
>> +  then that handler is unregistered.
>> +  If an attempt is made to register a handler when a handler is already
>> +  registered, then EFI_ALREADY_STARTED is returned.
>> +  If an attempt is made to unregister a handler when a handler is not
>> +  registered, then EFI_INVALID_PARAMETER is returned.
>> +
>> +  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
>> +  @param  NotifyFunction   The function to call when a timer interrupt fires.
>> +                           This function executes at TPL_HIGH_LEVEL. The DXE
>> +                           Core will register a handler for the timer interrupt,
>> +                           so it can know how much time has passed. This
>> +                           information is used to signal timer based events.
>> +                           NULL will unregister the handler.
>> +
>> +  @retval EFI_UNSUPPORTED       The code does not support NotifyFunction.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerRegisterHandler (
>> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> +  IN       EFI_WATCHDOG_TIMER_NOTIFY        NotifyFunction
>> +  )
>> +{
>> +  /* Not support. Watchdog will reset the board */
>> +  return EFI_UNSUPPORTED;
>> +}
>> +
>> +/**
>> +  This function sets the amount of time to wait before firing the Watchdog
>> +  timer to TimerPeriod 100ns units.  If TimerPeriod is 0, then the Watchdog
>> +  timer is disabled.
>> +
>> +  @param  This             The EFI_WATCHDOG_TIMER_ARCH_PROTOCOL instance.
>> +  @param  TimerPeriod      The amount of time in 100ns units to wait before
>> +                           the Watchdog timer is fired. If TimerPeriod is zero,
>> +                           then the Watchdog timer is disabled.
>> +
>> +  @retval EFI_SUCCESS           The Watchdog timer has been programmed to fire
>> +                                in Time  100ns units.
>> +  @retval EFI_DEVICE_ERROR      A Watchdog timer could not be programmed due
>> +                                to a device error.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerSetPeriod (
>> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> +  IN       UINT64                           TimerPeriod   // In 100ns units
>> +  )
>> +{
>> +  mNumTimerTicks  = (ArmGenericTimerGetTimerFreq () * TimerPeriod) / TIME_UNITS_PER_SECOND;
>> +
>> +  if (!IsFailSafeOff ()) {
>> +    /* Not support Watchdog timer service until FailSafe is off as ATF is monitoring it */
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  return WatchdogTimerSetup ();
>> +}
>> +
>> +/**
>> +  This function retrieves the period of timer interrupts in 100ns units,
>> +  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
>> +  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
>> +  returned, then the timer is currently disabled.
>> +
>> +  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
>> +  @param  TimerPeriod      A pointer to the timer period to retrieve in
>> +                           100ns units. If 0 is returned, then the timer is
>> +                           currently disabled.
>> +
>> +
>> +  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
>> +  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerGetPeriod (
>> +  IN CONST EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *This,
>> +  OUT      UINT64                           *TimerPeriod
>> +  )
>> +{
>> +  if (TimerPeriod == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  *TimerPeriod = ((TIME_UNITS_PER_SECOND / ArmGenericTimerGetTimerFreq ()) * mNumTimerTicks);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Interface structure for the Watchdog Architectural Protocol.
>> +
>> +  @par Protocol Description:
>> +  This protocol provides a service to set the amount of time to wait
>> +  before firing the Watchdog timer, and it also provides a service to
>> +  register a handler that is invoked when the Watchdog timer fires.
>> +
>> +  @par When the Watchdog timer fires, control will be passed to a handler
>> +  if one has been registered.  If no handler has been registered,
>> +  or the registered handler returns, then the system will be
>> +  reset by calling the Runtime Service ResetSystem().
>> +
>> +  @param RegisterHandler
>> +  Registers a handler that will be called each time the
>> +  Watchdogtimer interrupt fires.  TimerPeriod defines the minimum
>> +  time between timer interrupts, so TimerPeriod will also
>> +  be the minimum time between calls to the registered
>> +  handler.
>> +  NOTE: If the Watchdog resets the system in hardware, then
>> +        this function will not have any chance of executing.
>> +
>> +  @param SetTimerPeriod
>> +  Sets the period of the timer interrupt in 100ns units.
>> +  This function is optional, and may return EFI_UNSUPPORTED.
>> +  If this function is supported, then the timer period will
>> +  be rounded up to the nearest supported timer period.
>> +
>> +  @param GetTimerPeriod
>> +  Retrieves the period of the timer interrupt in 100ns units.
>> +
>> +**/
>> +STATIC EFI_WATCHDOG_TIMER_ARCH_PROTOCOL gWatchdogTimer = {
>> +  (EFI_WATCHDOG_TIMER_REGISTER_HANDLER)WatchdogTimerRegisterHandler,
>> +  (EFI_WATCHDOG_TIMER_SET_TIMER_PERIOD)WatchdogTimerSetPeriod,
>> +  (EFI_WATCHDOG_TIMER_GET_TIMER_PERIOD)WatchdogTimerGetPeriod
>> +};
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +WatchdogTimerInstallProtocol (
>> +  EFI_WATCHDOG_TIMER_ARCH_PROTOCOL **WatchdogTimerProtocol
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  EFI_HANDLE Handle;
>> +  EFI_TPL    CurrentTpl;
>> +
>> +  /* Make sure the Watchdog Timer Architectural Protocol has not been installed
>> +     in the system yet.
>> +     This will avoid conflicts with the universal Watchdog */
>> +  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiWatchdogTimerArchProtocolGuid);
>> +
>> +  ASSERT (ArmGenericTimerGetTimerFreq () != 0);
>> +
>> +  /* Install interrupt handler */
>> +  Status = gBS->LocateProtocol (
>> +                  &gHardwareInterrupt2ProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&mInterruptProtocol
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  /*
>> +   * We don't want to be interrupted while registering Watchdog interrupt source as the interrupt
>> +   * may be trigger in the middle because the interrupt line already enabled in the EL3.
>> +   */
>> +  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
>> +
>> +  Status = mInterruptProtocol->RegisterInterruptSource (
>> +                                 mInterruptProtocol,
>> +                                 WS0_INTERRUPT_SOURCE,
>> +                                 WatchdogTimerInterruptHandler
>> +                                 );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  /* Don't enable interrupt until FailSafe off */
>> +  mInterruptWS0Enabled = FALSE;
>> +  Status = mInterruptProtocol->DisableInterruptSource (
>> +                                 mInterruptProtocol,
>> +                                 WS0_INTERRUPT_SOURCE
>> +                                 );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  gBS->RestoreTPL (CurrentTpl);
>> +
>> +  Status = mInterruptProtocol->SetTriggerType (
>> +                                 mInterruptProtocol,
>> +                                 WS0_INTERRUPT_SOURCE,
>> +                                 EFI_HARDWARE_INTERRUPT2_TRIGGER_LEVEL_HIGH
>> +                                 );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  /* Install the Timer Architectural Protocol onto a new handle */
>> +  Handle = NULL;
>> +  Status = gBS->InstallMultipleProtocolInterfaces (
>> +                  &Handle,
>> +                  &gEfiWatchdogTimerArchProtocolGuid,
>> +                  &gWatchdogTimer,
>> +                  NULL
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  mNumTimerTicks = 0;
>> +
>> +  if (WatchdogTimerProtocol != NULL) {
>> +    *WatchdogTimerProtocol = &gWatchdogTimer;
>> +  }
>> +
>> +  return Status;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library
  2021-06-04 23:21   ` Leif Lindholm
@ 2021-06-15 16:47     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:47 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/5/21 06:21, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:57 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> The DwI2cLib library provides basic functions to control the I2C
>> controller on Ampere Altra processor.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
> (but I think this was one of the ones that have issues that should be
> addressed - please ensure build with CLANG38 before v3)

Thanks, Leif. I will fix the clang compilation issues in the v3.

Best regards,

Nhi

>
> /
>      Leif
>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec            |   3 +
>>   Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf |  38 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h      | 100 +++
>>   Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c   | 883 ++++++++++++++++++++
>>   4 files changed, 1024 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> index 73097afaf841..8be6a329bb26 100644
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> @@ -28,6 +28,9 @@ [LibraryClasses]
>>     ##  @libraryclass  Defines a set of methods to communicate with SCP.
>>     SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/SystemFirmwareInterfaceLib.h
>>   
>> +  ##  @libraryclass  Defines a set of methods to read/write to I2C devices.
>> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>> +
>>     ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>>     MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>>   
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>> new file mode 100644
>> index 000000000000..091f5f9b310c
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>> @@ -0,0 +1,38 @@
>> +## @file
>> +# Component description for DwI2cLib library for the Designware I2C controller.
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = DwI2cLib
>> +  FILE_GUID                      = 222609E2-C181-11E6-A4A6-CEC0C932CE01
>> +  MODULE_TYPE                    = BASE
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = I2cLib
>> +  CONSTRUCTOR                    = I2cLibConstructor
>> +
>> +[Sources]
>> +  DwI2cLib.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  HobLib
>> +  IoLib
>> +  TimerLib
>> +
>> +[Guids]
>> +  gEfiEventVirtualAddressChangeGuid
>> +  gPlatformHobGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>> new file mode 100644
>> index 000000000000..f13794171029
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/I2cLib.h
>> @@ -0,0 +1,100 @@
>> +/** @file
>> +  Library implementation for the Designware I2C controller.
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef I2C_LIB_H_
>> +#define I2C_LIB_H_
>> +
>> +#include <Uefi/UefiBaseType.h>
>> +
>> +/**
>> +  Write to I2C bus.
>> +
>> +  @param[in]     Bus          I2C bus Id.
>> +  @param[in]     SlaveAddr    The address of slave device on the bus.
>> +  @param[in,out] Buf          Buffer that holds data to write.
>> +  @param[in,out] WriteLength  Pointer to length of buffer.
>> +
>> +  @return EFI_SUCCESS            Write successfully.
>> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
>> +  @return EFI_UNSUPPORTED        The bus is not supported.
>> +  @return EFI_NOT_READY          The device/bus is not ready.
>> +  @return EFI_TIMEOUT            Timeout why transferring data.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cWrite (
>> +  IN     UINT32 Bus,
>> +  IN     UINT32 SlaveAddr,
>> +  IN OUT UINT8  *Buf,
>> +  IN OUT UINT32 *WriteLength
>> +  );
>> +
>> +/**
>> +  Read data from I2C bus.
>> +
>> +  @param[in]     Bus          I2C bus Id.
>> +  @param[in]     SlaveAddr    The address of slave device on the bus.
>> +  @param[in]     BufCmd       Buffer where to send the command.
>> +  @param[in]     CmdLength    Pointer to length of BufCmd.
>> +  @param[in,out] Buf          Buffer where to put the read data to.
>> +  @param[in,out] ReadLength   Pointer to length of buffer.
>> +
>> +  @return EFI_SUCCESS            Read successfully.
>> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
>> +  @return EFI_UNSUPPORTED        The bus is not supported.
>> +  @return EFI_NOT_READY          The device/bus is not ready.
>> +  @return EFI_TIMEOUT            Timeout why transferring data.
>> +  @return EFI_CRC_ERROR          There are errors on receiving data.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cRead (
>> +  IN     UINT32 Bus,
>> +  IN     UINT32 SlaveAddr,
>> +  IN     UINT8  *BufCmd,
>> +  IN     UINT32 CmdLength,
>> +  IN OUT UINT8  *Buf,
>> +  IN OUT UINT32 *ReadLength
>> +  );
>> +
>> +/**
>> + Setup new transaction with I2C slave device.
>> +
>> +  @param[in] Bus      I2C bus Id.
>> +  @param[in] BusSpeed I2C bus speed in Hz.
>> +
>> +  @retval EFI_SUCCESS           Success.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cProbe (
>> +  IN UINT32 Bus,
>> +  IN UINTN  BusSpeed
>> +  );
>> +
>> +/**
>> + Setup a bus that to be used in runtime service.
>> +
>> +  @param[in] Bus I2C bus Id.
>> +
>> +  @retval EFI_SUCCESS  Success.
>> +  @retval Otherwise    Error code.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cSetupRuntime (
>> +  IN UINT32 Bus
>> +  );
>> +
>> +#endif /* I2C_LIB_H_ */
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
>> new file mode 100644
>> index 000000000000..5e7cd020223c
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.c
>> @@ -0,0 +1,883 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiDxe.h>
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DxeServicesTableLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/I2cLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeLib.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +#define I2cSync() { asm volatile ("dmb ish" : : : "memory"); }
>> +
>> +//
>> +// Runtime needs to be 64K alignment
>> +//
>> +#define RUNTIME_ADDRESS_MASK           (~(SIZE_64KB - 1))
>> +#define RUNTIME_ADDRESS_LENGTH         SIZE_64KB
>> +
>> +//
>> +// Private I2C bus data
>> +//
>> +typedef struct {
>> +  UINTN  Base;
>> +  UINT32 BusSpeed;
>> +  UINT32 RxFifo;
>> +  UINT32 TxFifo;
>> +  UINT32 PollingTime;
>> +  UINT32 Enabled;
>> +} DW_I2C_CONTEXT_T;
>> +
>> +//
>> +// I2C SCL counter macros
>> +//
>> +typedef enum {
>> +  I2cSpeedModeStandard = 0,
>> +  I2cSpeedModeFast,
>> +} I2C_SPEED_MODE;
>> +
>> +#define DW_I2C_MAXIMUM_SPEED_HZ 400000
>> +
>> +typedef enum {
>> +  I2cSclSpkLen = 0,
>> +  I2cSclHcnt,
>> +  I2cSclLcnt,
>> +} I2C_SCL_PARAM;
>> +
>> +STATIC UINT32 I2cSclParam[][3] = {
>> +  /* SPK_LEN, HCNT, LCNT */
>> +  [I2cSpeedModeStandard]   = { 10, 0x3E2, 0x47D }, // SS (Standard Speed)
>> +  [I2cSpeedModeFast]       = { 10, 0xA4,  0x13F }, // FS (Fast Speed)
>> +};
>> +
>> +STATIC BOOLEAN          mI2cRuntimeEnableArray[MAX_PLATFORM_I2C_BUS_NUM] = {FALSE};
>> +STATIC UINTN            mI2cBaseArray[MAX_PLATFORM_I2C_BUS_NUM] = {PLATFORM_I2C_REGISTER_BASE};
>> +STATIC DW_I2C_CONTEXT_T mI2cBusList[MAX_PLATFORM_I2C_BUS_NUM];
>> +STATIC UINTN            mI2cClock = 0;
>> +STATIC EFI_EVENT        mVirtualAddressChangeEvent = NULL;
>> +
>> +//
>> +// Registers
>> +//
>> +#define DW_IC_CON                       0x0
>> +#define DW_IC_CON_MASTER                BIT0
>> +#define DW_IC_CON_SPEED_STD             BIT1
>> +#define DW_IC_CON_SPEED_FAST            BIT2
>> +#define DW_IC_CON_10BITADDR_MASTER      BIT4
>> +#define DW_IC_CON_RESTART_EN            BIT5
>> +#define DW_IC_CON_SLAVE_DISABLE         BIT6
>> +#define DW_IC_TAR                       0x4
>> +#define DW_IC_TAR_10BITS                BIT12
>> +#define DW_IC_SAR                       0x8
>> +#define DW_IC_DATA_CMD                  0x10
>> +#define DW_IC_DATA_CMD_RESTART          BIT10
>> +#define DW_IC_DATA_CMD_STOP             BIT9
>> +#define DW_IC_DATA_CMD_CMD              BIT8
>> +#define DW_IC_DATA_CMD_DAT_MASK         0xFF
>> +#define DW_IC_SS_SCL_HCNT               0x14
>> +#define DW_IC_SS_SCL_LCNT               0x18
>> +#define DW_IC_FS_SCL_HCNT               0x1c
>> +#define DW_IC_FS_SCL_LCNT               0x20
>> +#define DW_IC_HS_SCL_HCNT               0x24
>> +#define DW_IC_HS_SCL_LCNT               0x28
>> +#define DW_IC_INTR_STAT                 0x2c
>> +#define DW_IC_INTR_MASK                 0x30
>> +#define DW_IC_INTR_RX_UNDER             BIT0
>> +#define DW_IC_INTR_RX_OVER              BIT1
>> +#define DW_IC_INTR_RX_FULL              BIT2
>> +#define DW_IC_INTR_TX_EMPTY             BIT4
>> +#define DW_IC_INTR_TX_ABRT              BIT6
>> +#define DW_IC_INTR_ACTIVITY             BIT8
>> +#define DW_IC_INTR_STOP_DET             BIT9
>> +#define DW_IC_INTR_START_DET            BIT10
>> +#define DW_IC_ERR_CONDITION \
>> +                (DW_IC_INTR_RX_UNDER | DW_IC_INTR_RX_OVER | DW_IC_INTR_TX_ABRT)
>> +#define DW_IC_RAW_INTR_STAT             0x34
>> +#define DW_IC_CLR_INTR                  0x40
>> +#define DW_IC_CLR_RX_UNDER              0x44
>> +#define DW_IC_CLR_RX_OVER               0x48
>> +#define DW_IC_CLR_TX_ABRT               0x54
>> +#define DW_IC_CLR_ACTIVITY              0x5c
>> +#define DW_IC_CLR_STOP_DET              0x60
>> +#define DW_IC_CLR_START_DET             0x64
>> +#define DW_IC_ENABLE                    0x6c
>> +#define DW_IC_STATUS                    0x70
>> +#define DW_IC_STATUS_ACTIVITY           BIT0
>> +#define DW_IC_STATUS_TFE                BIT2
>> +#define DW_IC_STATUS_RFNE               BIT3
>> +#define DW_IC_STATUS_MST_ACTIVITY       BIT5
>> +#define DW_IC_TXFLR                     0x74
>> +#define DW_IC_RXFLR                     0x78
>> +#define DW_IC_SDA_HOLD                  0x7c
>> +#define DW_IC_TX_ABRT_SOURCE            0x80
>> +#define DW_IC_ENABLE_STATUS             0x9c
>> +#define DW_IC_COMP_PARAM_1              0xf4
>> +#define  DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH(x) \
>> +           ((((x) >> 8) & 0xFF) + 1)
>> +#define  DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH(x) \
>> +           ((((x) >> 16) & 0xFF) + 1)
>> +#define DW_IC_COMP_TYPE                 0xfc
>> +#define SB_DW_IC_CON                    0xa8
>> +#define SB_DW_IC_SCL_TMO_CNT            0xac
>> +#define SB_DW_IC_RX_PEC                 0xb0
>> +#define SB_DW_IC_ACK                    0xb4
>> +#define SB_DW_IC_FLG                    0xb8
>> +#define SB_DW_IC_FLG_CLR                0xbc
>> +#define SB_DW_IC_INTR_STAT              0xc0
>> +#define SB_DW_IC_INTR_STAT_MASK         0xc4
>> +#define SB_DW_IC_DEBUG_SEL              0xec
>> +#define SB_DW_IC_ACK_DEBUG              0xf0
>> +#define DW_IC_FS_SPKLEN                 0xa0
>> +#define DW_IC_HS_SPKLEN                 0xa4
>> +
>> +//
>> +// Timeout interval
>> +//
>> +// The interval is equal to the 10 times the signaling period
>> +// for the highest I2C transfer speed used in the system.
>> +//
>> +#define DW_POLL_INTERVAL_US(x) (10 * (1000000 / (x)))
>> +
>> +//
>> +// Maximum timeout count
>> +//
>> +#define DW_MAX_TRANSFER_POLL_COUNT 100000 // Maximum timeout: 10s
>> +#define DW_MAX_STATUS_POLL_COUNT   100
>> +
>> +#define DW_POLL_MST_ACTIVITY_INTERVAL_US 1000 // 1ms
>> +#define DW_MAX_MST_ACTIVITY_POLL_COUNT   20
>> +
>> +/**
>> + Initialize I2C Bus
>> + **/
>> +VOID
>> +I2cHWInit (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINT32 Param;
>> +
>> +  mI2cBusList[Bus].Base = mI2cBaseArray[Bus];
>> +
>> +  Param = MmioRead32 (mI2cBusList[Bus].Base + DW_IC_COMP_PARAM_1);
>> +
>> +  mI2cBusList[Bus].PollingTime = DW_POLL_INTERVAL_US (mI2cBusList[Bus].BusSpeed);
>> +  mI2cBusList[Bus].RxFifo = DW_IC_COMP_PARAM_1_RX_BUFFER_DEPTH (Param);
>> +  mI2cBusList[Bus].TxFifo = DW_IC_COMP_PARAM_1_TX_BUFFER_DEPTH (Param);
>> +  mI2cBusList[Bus].Enabled = 0;
>> +
>> +  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d, Rx_Buffer %d, Tx_Buffer %d\n",
>> +    __FUNCTION__,
>> +    Bus,
>> +    mI2cBusList[Bus].RxFifo,
>> +    mI2cBusList[Bus].TxFifo
>> +    ));
>> +}
>> +
>> +/**
>> + Enable or disable I2C Bus
>> + */
>> +VOID
>> +I2cEnable (
>> +  UINT32 Bus,
>> +  UINT32 Enable
>> +  )
>> +{
>> +  UINT32 I2cStatusCnt;
>> +  UINTN  Base;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  I2cStatusCnt = DW_MAX_STATUS_POLL_COUNT;
>> +  mI2cBusList[Bus].Enabled = Enable;
>> +
>> +  MmioWrite32 (Base + DW_IC_ENABLE, Enable);
>> +
>> +  do {
>> +    if ((MmioRead32 (Base + DW_IC_ENABLE_STATUS) & 0x01) == Enable) {
>> +      break;
>> +    }
>> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
>> +  } while (I2cStatusCnt-- != 0);
>> +
>> +  if (I2cStatusCnt == 0) {
>> +    DEBUG ((DEBUG_ERROR, "%a: Enable/disable timeout\n", __FUNCTION__));
>> +  }
>> +
>> +  if ((Enable == 0) || (I2cStatusCnt == 0)) {
>> +    /* Unset the target adddress */
>> +    MmioWrite32 (Base + DW_IC_TAR, 0);
>> +    mI2cBusList[Bus].Enabled = 0;
>> +  }
>> +}
>> +
>> +/**
>> + Setup Slave address
>> + **/
>> +VOID
>> +I2cSetSlaveAddr (
>> +  UINT32 Bus,
>> +  UINT32 SlaveAddr
>> +  )
>> +{
>> +  UINTN  Base;
>> +  UINT32 OldEnableStatus;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  OldEnableStatus = mI2cBusList[Bus].Enabled;
>> +
>> +  I2cEnable (Bus, 0);
>> +  MmioWrite32 (Base + DW_IC_TAR, SlaveAddr);
>> +  if (OldEnableStatus != 0) {
>> +    I2cEnable (Bus, 1);
>> +  }
>> +}
>> +
>> +/**
>> + Check for errors on I2C Bus
>> + **/
>> +UINT32
>> +I2cCheckErrors (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINTN  Base;
>> +  UINT32 ErrorStatus;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +
>> +  ErrorStatus = MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_ERR_CONDITION;
>> +
>> +  if ((ErrorStatus & DW_IC_INTR_RX_UNDER) != 0) {
>> +    DEBUG ((DEBUG_ERROR, "%a: RX_UNDER error on i2c bus %d error status %08x\n",
>> +      __FUNCTION__,
>> +      Bus,
>> +      ErrorStatus
>> +      ));
>> +    MmioRead32 (Base + DW_IC_CLR_RX_UNDER);
>> +  }
>> +
>> +  if ((ErrorStatus & DW_IC_INTR_RX_OVER) != 0) {
>> +    DEBUG ((DEBUG_ERROR, "%a: RX_OVER error on i2c bus %d error status %08x\n",
>> +      __FUNCTION__,
>> +      Bus,
>> +      ErrorStatus
>> +      ));
>> +    MmioRead32 (Base + DW_IC_CLR_RX_OVER);
>> +  }
>> +
>> +  if ((ErrorStatus & DW_IC_INTR_TX_ABRT) != 0) {
>> +    DEBUG ((DEBUG_VERBOSE, "%a: TX_ABORT at source %08x\n",
>> +      __FUNCTION__,
>> +      MmioRead32 (Base + DW_IC_TX_ABRT_SOURCE)
>> +      ));
>> +    MmioRead32 (Base + DW_IC_CLR_TX_ABRT);
>> +  }
>> +
>> +  return ErrorStatus;
>> +}
>> +
>> +/**
>> + Waiting for bus to not be busy
>> + **/
>> +BOOLEAN
>> +I2cWaitBusNotBusy (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINTN Base;
>> +  UINTN PollCount;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  PollCount = DW_MAX_MST_ACTIVITY_POLL_COUNT;
>> +
>> +  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_MST_ACTIVITY) != 0) {
>> +    if (PollCount == 0) {
>> +      DEBUG ((DEBUG_VERBOSE, "%a: Timeout while waiting for bus ready\n", __FUNCTION__));
>> +      return FALSE;
>> +    }
>> +    PollCount--;
>> +    /*
>> +     * A delay isn't absolutely necessary.
>> +     * But to ensure that we don't hammer the bus constantly,
>> +     * delay for DW_POLL_MST_ACTIVITY_INTERVAL_US as with other implementation.
>> +     */
>> +    MicroSecondDelay (DW_POLL_MST_ACTIVITY_INTERVAL_US);
>> +  }
>> +
>> +  return TRUE;
>> +}
>> +
>> +/**
>> + Waiting for TX FIFO buffer available
>> + **/
>> +EFI_STATUS
>> +I2cWaitTxData (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINTN Base;
>> +  UINTN PollCount;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  PollCount = 0;
>> +
>> +  while (MmioRead32 (Base + DW_IC_TXFLR) == mI2cBusList[Bus].TxFifo) {
>> +    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
>> +      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX buffer available\n", __FUNCTION__));
>> +      return EFI_TIMEOUT;
>> +    }
>> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + Waiting for RX FIFO buffer available
>> + **/
>> +EFI_STATUS
>> +I2cWaitRxData (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINTN Base;
>> +  UINTN PollCount;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  PollCount = 0;
>> +
>> +  while ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_RFNE) == 0) {
>> +    if (PollCount++ >= DW_MAX_TRANSFER_POLL_COUNT) {
>> +      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for RX buffer available\n", __FUNCTION__));
>> +      return EFI_TIMEOUT;
>> +    }
>> +
>> +    if ((I2cCheckErrors (Bus) & DW_IC_INTR_TX_ABRT) != 0) {
>> +      return EFI_ABORTED;
>> +    }
>> +
>> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + Initialize the Designware I2C SCL Counts
>> +
>> + This functions configures SCL clock Count for Standard Speed (SS) and Fast Speed (FS) mode.
>> + **/
>> +VOID
>> +I2cSclInit (
>> +  UINT32 Bus,
>> +  UINT32 I2cClkFreq,
>> +  UINT32 I2cSpeed
>> +  )
>> +{
>> +  UINT16 IcCon;
>> +  UINTN  Base;
>> +  UINT32 I2cSpeedKhz;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  I2cSpeedKhz = I2cSpeed / 1000;
>> +
>> +  DEBUG ((DEBUG_VERBOSE, "%a: Bus %d I2cClkFreq %d I2cSpeed %d\n",
>> +    __FUNCTION__,
>> +    Bus,
>> +    I2cClkFreq,
>> +    I2cSpeed
>> +    ));
>> +
>> +  IcCon = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE | DW_IC_CON_RESTART_EN;
>> +
>> +  if (I2cSpeedKhz <= 100) {
>> +    IcCon |= DW_IC_CON_SPEED_STD;
>> +    // Standard speed mode
>> +    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeStandard][I2cSclSpkLen]);
>> +    MmioWrite32 (Base + DW_IC_SS_SCL_HCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclHcnt]);
>> +    MmioWrite32 (Base + DW_IC_SS_SCL_LCNT, I2cSclParam[I2cSpeedModeStandard][I2cSclLcnt]);
>> +  } else if (I2cSpeedKhz > 100 && I2cSpeedKhz <= 400) {
>> +    IcCon |= DW_IC_CON_SPEED_FAST;
>> +    // Fast speed mode
>> +    MmioWrite32 (Base + DW_IC_FS_SPKLEN, I2cSclParam[I2cSpeedModeFast][I2cSclSpkLen]);
>> +    MmioWrite32 (Base + DW_IC_FS_SCL_HCNT, I2cSclParam[I2cSpeedModeFast][I2cSclHcnt]);
>> +    MmioWrite32 (Base + DW_IC_FS_SCL_LCNT, I2cSclParam[I2cSpeedModeFast][I2cSclLcnt]);
>> +  }
>> +  MmioWrite32 (Base + DW_IC_CON, IcCon);
>> +}
>> +
>> +/**
>> + Initialize the designware i2c master hardware
>> + **/
>> +EFI_STATUS
>> +I2cInit (
>> +  UINT32 Bus,
>> +  UINTN  BusSpeed
>> +  )
>> +{
>> +  UINTN Base;
>> +
>> +  ASSERT (mI2cClock != 0);
>> +
>> +  mI2cBusList[Bus].BusSpeed = BusSpeed;
>> +  I2cHWInit (Bus);
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +
>> +  /* Disable the adapter and interrupt */
>> +  I2cEnable (Bus, 0);
>> +  MmioWrite32 (Base + DW_IC_INTR_MASK, 0);
>> +
>> +  /* Set standard and fast speed divider for high/low periods */
>> +  I2cSclInit (Bus, mI2cClock, BusSpeed);
>> +  MmioWrite32 (Base + DW_IC_SDA_HOLD, 0x4b);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + Wait the transaction finished
>> + **/
>> +EFI_STATUS
>> +I2cFinish (
>> +  UINT32 Bus
>> +  )
>> +{
>> +  UINTN Base;
>> +  UINTN PollCount;
>> +
>> +  Base = mI2cBusList[Bus].Base;
>> +  PollCount = 0;
>> +
>> +  /* Wait for TX FIFO empty */
>> +  do {
>> +    if ((MmioRead32 (Base + DW_IC_STATUS) & DW_IC_STATUS_TFE) != 0) {
>> +      break;
>> +    }
>> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
>> +  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
>> +
>> +  if (PollCount >= DW_MAX_TRANSFER_POLL_COUNT) {
>> +    DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for TX FIFO empty\n", __FUNCTION__));
>> +    return EFI_TIMEOUT;
>> +  }
>> +
>> +  /* Wait for STOP signal detected on the bus */
>> +  PollCount = 0;
>> +  do {
>> +    if ((MmioRead32 (Base + DW_IC_RAW_INTR_STAT) & DW_IC_INTR_STOP_DET) != 0) {
>> +      MmioRead32 (Base + DW_IC_CLR_STOP_DET);
>> +      return EFI_SUCCESS;
>> +    }
>> +    MicroSecondDelay (mI2cBusList[Bus].PollingTime);
>> +  } while (PollCount++ < DW_MAX_TRANSFER_POLL_COUNT);
>> +
>> +  DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for transaction finished\n", __FUNCTION__));
>> +  return EFI_TIMEOUT;
>> +}
>> +
>> +EFI_STATUS
>> +InternalI2cWrite (
>> +  UINT32 Bus,
>> +  UINT8  *Buf,
>> +  UINT32 *Length
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINTN      WriteCount;
>> +  UINTN      Base;
>> +
>> +  Status = EFI_SUCCESS;
>> +  Base = mI2cBusList[Bus].Base;
>> +
>> +  DEBUG ((DEBUG_VERBOSE, "%a: Write Bus %d Buf %p Length %d\n",
>> +    __FUNCTION__,
>> +    Bus,
>> +    Buf,
>> +    *Length
>> +    ));
>> +  I2cEnable (Bus, 1);
>> +
>> +  WriteCount = 0;
>> +  while ((*Length - WriteCount) != 0) {
>> +    Status = I2cWaitTxData (Bus);
>> +    if (EFI_ERROR (Status)) {
>> +      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
>> +      I2cSync ();
>> +      goto Exit;
>> +    }
>> +
>> +    if (WriteCount == *Length - 1) {
>> +      MmioWrite32 (
>> +        Base + DW_IC_DATA_CMD,
>> +        (Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK) | DW_IC_DATA_CMD_STOP
>> +        );
>> +    } else {
>> +      MmioWrite32 (
>> +        Base + DW_IC_DATA_CMD,
>> +        Buf[WriteCount] & DW_IC_DATA_CMD_DAT_MASK
>> +        );
>> +    }
>> +    I2cSync ();
>> +    WriteCount++;
>> +  }
>> +
>> +Exit:
>> +  *Length = WriteCount;
>> +  I2cFinish (Bus);
>> +  I2cWaitBusNotBusy (Bus);
>> +  I2cEnable (Bus, 0);
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +InternalI2cRead (
>> +  UINT32  Bus,
>> +  UINT8  *BufCmd,
>> +  UINT32 CmdLength,
>> +  UINT8  *Buf,
>> +  UINT32 *Length
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINTN      Base;
>> +  UINT32     CmdSend;
>> +  UINT32     TxLimit, RxLimit;
>> +  UINTN      Idx;
>> +  UINTN      Count;
>> +  UINTN      ReadCount;
>> +  UINTN      WriteCount;
>> +
>> +  Status = EFI_SUCCESS;
>> +  Base = mI2cBusList[Bus].Base;
>> +  Count = 0;
>> +
>> +  DEBUG ((DEBUG_VERBOSE, "%a: Read Bus %d Buf %p Length:%d\n",
>> +    __FUNCTION__,
>> +    Bus,
>> +    Buf,
>> +    *Length
>> +    ));
>> +
>> +  I2cEnable (Bus, 1);
>> +
>> +  /* Write command data */
>> +  WriteCount = 0;
>> +  while (CmdLength != 0) {
>> +    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
>> +    Count = CmdLength > TxLimit ? TxLimit : CmdLength;
>> +
>> +    for (Idx = 0; Idx < Count; Idx++ ) {
>> +      CmdSend = BufCmd[WriteCount++] & DW_IC_DATA_CMD_DAT_MASK;
>> +      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
>> +      I2cSync ();
>> +
>> +      if (I2cCheckErrors (Bus) != 0) {
>> +        Status = EFI_CRC_ERROR;
>> +        goto Exit;
>> +      }
>> +      CmdLength--;
>> +    }
>> +
>> +    Status = I2cWaitTxData (Bus);
>> +    if (EFI_ERROR (Status)) {
>> +      MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
>> +      I2cSync ();
>> +      goto Exit;
>> +    }
>> +  }
>> +
>> +  ReadCount = 0;
>> +  WriteCount = 0;
>> +  while ((*Length - ReadCount) != 0) {
>> +    TxLimit = mI2cBusList[Bus].TxFifo - MmioRead32 (Base + DW_IC_TXFLR);
>> +    RxLimit = mI2cBusList[Bus].RxFifo - MmioRead32 (Base + DW_IC_RXFLR);
>> +    Count = *Length - ReadCount;
>> +    Count = Count > RxLimit ? RxLimit : Count;
>> +    Count = Count > TxLimit ? TxLimit : Count;
>> +
>> +    for (Idx = 0; Idx < Count; Idx++ ) {
>> +      CmdSend = DW_IC_DATA_CMD_CMD;
>> +      if (WriteCount == *Length - 1) {
>> +        CmdSend |= DW_IC_DATA_CMD_STOP;
>> +      }
>> +      MmioWrite32 (Base + DW_IC_DATA_CMD, CmdSend);
>> +      I2cSync ();
>> +      WriteCount++;
>> +
>> +      if (I2cCheckErrors (Bus) != 0) {
>> +        DEBUG ((DEBUG_VERBOSE,
>> +          "%a: Sending reading command remaining length %d CRC error\n",
>> +          __FUNCTION__,
>> +          *Length
>> +          ));
>> +        Status = EFI_CRC_ERROR;
>> +        goto Exit;
>> +      }
>> +    }
>> +
>> +    for (Idx = 0; Idx < Count; Idx++ ) {
>> +      Status = I2cWaitRxData (Bus);
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((DEBUG_VERBOSE,
>> +          "%a: Reading remaining length %d failed to wait data\n",
>> +          __FUNCTION__,
>> +          *Length
>> +          ));
>> +
>> +        if (Status != EFI_ABORTED) {
>> +          MmioWrite32 (Base + DW_IC_DATA_CMD, DW_IC_DATA_CMD_STOP);
>> +          I2cSync ();
>> +        }
>> +
>> +        goto Exit;
>> +      }
>> +
>> +      Buf[ReadCount++] = MmioRead32 (Base + DW_IC_DATA_CMD) & DW_IC_DATA_CMD_DAT_MASK;
>> +      I2cSync ();
>> +
>> +      if (I2cCheckErrors (Bus) != 0) {
>> +        DEBUG ((DEBUG_VERBOSE, "%a: Reading remaining length %d CRC error\n",
>> +          __FUNCTION__,
>> +          *Length
>> +          ));
>> +        Status = EFI_CRC_ERROR;
>> +        goto Exit;
>> +      }
>> +    }
>> +  }
>> +
>> +Exit:
>> +  *Length = ReadCount;
>> +  I2cFinish (Bus);
>> +  I2cWaitBusNotBusy (Bus);
>> +  I2cEnable (Bus, 0);
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Write to I2C bus.
>> +
>> +  @param[in]     Bus          I2C bus Id.
>> +  @param[in]     SlaveAddr    The address of slave device on the bus.
>> +  @param[in,out] Buf          Buffer that holds data to write.
>> +  @param[in,out] WriteLength  Pointer to length of buffer.
>> +
>> +  @return EFI_SUCCESS            Write successfully.
>> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
>> +  @return EFI_UNSUPPORTED        The bus is not supported.
>> +  @return EFI_NOT_READY          The device/bus is not ready.
>> +  @return EFI_TIMEOUT            Timeout why transferring data.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cWrite (
>> +  IN     UINT32 Bus,
>> +  IN     UINT32 SlaveAddr,
>> +  IN OUT UINT8  *Buf,
>> +  IN OUT UINT32 *WriteLength
>> +  )
>> +{
>> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
>> +      || Buf == NULL
>> +      || WriteLength == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  I2cSetSlaveAddr (Bus, SlaveAddr);
>> +
>> +  return InternalI2cWrite (Bus, Buf, WriteLength);
>> +}
>> +
>> +/**
>> +  Read data from I2C bus.
>> +
>> +  @param[in]     Bus          I2C bus Id.
>> +  @param[in]     SlaveAddr    The address of slave device on the bus.
>> +  @param[in]     BufCmd       Buffer where to send the command.
>> +  @param[in]     CmdLength    Pointer to length of BufCmd.
>> +  @param[in,out] Buf          Buffer where to put the read data to.
>> +  @param[in,out] ReadLength   Pointer to length of buffer.
>> +
>> +  @return EFI_SUCCESS            Read successfully.
>> +  @return EFI_INVALID_PARAMETER  A parameter is invalid.
>> +  @return EFI_UNSUPPORTED        The bus is not supported.
>> +  @return EFI_NOT_READY          The device/bus is not ready.
>> +  @return EFI_TIMEOUT            Timeout why transferring data.
>> +  @return EFI_CRC_ERROR          There are errors on receiving data.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cRead (
>> +  IN     UINT32 Bus,
>> +  IN     UINT32 SlaveAddr,
>> +  IN     UINT8  *BufCmd,
>> +  IN     UINT32 CmdLength,
>> +  IN OUT UINT8  *Buf,
>> +  IN OUT UINT32 *ReadLength
>> +  )
>> +{
>> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
>> +      || Buf == NULL
>> +      || ReadLength == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  I2cSetSlaveAddr (Bus, SlaveAddr);
>> +
>> +  return InternalI2cRead (Bus, BufCmd, CmdLength, Buf, ReadLength);
>> +}
>> +
>> +/**
>> + Setup new transaction with I2C slave device.
>> +
>> +  @param[in] Bus      I2C bus Id.
>> +  @param[in] BusSpeed I2C bus speed in Hz.
>> +
>> +  @retval EFI_SUCCESS           Success.
>> +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cProbe (
>> +  IN UINT32 Bus,
>> +  IN UINTN  BusSpeed
>> +  )
>> +{
>> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM
>> +      || BusSpeed > DW_I2C_MAXIMUM_SPEED_HZ)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  return I2cInit (Bus, BusSpeed);
>> +}
>> +
>> +/**
>> + * Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
>> + *
>> + * This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event.
>> + * It convers pointer to new virtual address.
>> + *
>> + * @param  Event        Event whose notification function is being invoked.
>> + * @param  Context      Pointer to the notification function's context.
>> + */
>> +VOID
>> +EFIAPI
>> +I2cVirtualAddressChangeEvent (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  UINTN Count;
>> +
>> +  EfiConvertPointer (0x0, (VOID **)&mI2cBusList);
>> +  EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray);
>> +  EfiConvertPointer (0x0, (VOID **)&mI2cClock);
>> +  for (Count = 0; Count < MAX_PLATFORM_I2C_BUS_NUM; Count++) {
>> +    if (!mI2cRuntimeEnableArray[Count]) {
>> +      continue;
>> +    }
>> +    EfiConvertPointer (0x0, (VOID **)&mI2cBaseArray[Count]);
>> +    EfiConvertPointer (0x0, (VOID **)&mI2cBusList[Count].Base);
>> +  }
>> +}
>> +
>> +/**
>> + Setup a bus that to be used in runtime service.
>> +
>> +  @param[in] Bus I2C bus Id.
>> +
>> +  @retval EFI_SUCCESS  Success.
>> +  @retval Otherwise    Error code.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +I2cSetupRuntime (
>> +  IN UINT32 Bus
>> +  )
>> +{
>> +  EFI_STATUS                      Status;
>> +  EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
>> +
>> +  if (Bus >= MAX_PLATFORM_I2C_BUS_NUM) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  if (mVirtualAddressChangeEvent == NULL) {
>> +    /*
>> +     * Register for the virtual address change event
>> +     */
>> +    Status = gBS->CreateEventEx (
>> +                    EVT_NOTIFY_SIGNAL,
>> +                    TPL_NOTIFY,
>> +                    I2cVirtualAddressChangeEvent,
>> +                    NULL,
>> +                    &gEfiEventVirtualAddressChangeGuid,
>> +                    &mVirtualAddressChangeEvent
>> +                    );
>> +    ASSERT_EFI_ERROR (Status);
>> +  }
>> +
>> +  Status = gDS->GetMemorySpaceDescriptor (
>> +                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
>> +                  &Descriptor
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Status = gDS->SetMemorySpaceAttributes (
>> +                  mI2cBaseArray[Bus] & RUNTIME_ADDRESS_MASK,
>> +                  RUNTIME_ADDRESS_LENGTH,
>> +                  Descriptor.Attributes | EFI_MEMORY_RUNTIME
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  mI2cRuntimeEnableArray[Bus] = TRUE;
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +I2cLibConstructor (
>> +  VOID
>> +  )
>> +{
>> +  VOID               *Hob;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  /* Get I2C Clock from the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return EFI_NOT_FOUND;
>> +  }
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +  mI2cClock = PlatformHob->AhbClk;
>> +  ASSERT (mI2cClock != 0);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063
  2021-06-04 23:26   ` Leif Lindholm
@ 2021-06-15 16:48     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:48 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/5/21 06:26, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:06:59 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> This library adds the support for retrieving and updating system
>> datetime over real RTC PCF85063 device on Mt. Jade platform instead of
>> using virtual RTC.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                  |   2 +
>>   Platform/Ampere/JadePkg/Jade.dsc                                                      |   2 +-
>>   Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf |  44 +++
>>   Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h                   |  91 ++++++
>>   Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c                   | 317 ++++++++++++++++++++
>>   Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c   | 257 ++++++++++++++++
>>   6 files changed, 712 insertions(+), 1 deletion(-)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 6a6f72e995af..9f19f495fad2 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -84,6 +84,8 @@ [LibraryClasses.common]
>>     SystemFirmwareInterfaceLib|Silicon/Ampere/AmpereAltraPkg/Library/SystemFirmwareInterfaceLib/SystemFirmwareInterfaceLib.inf
>>     AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf
>>     TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf
>> +  I2cLib|Silicon/Ampere/AmpereAltraPkg/Library/DwI2cLib/DwI2cLib.inf
>> +  GpioLib|Silicon/Ampere/AmpereAltraPkg/Library/DwGpioLib/DwGpioLib.inf
>>     MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf
>>   
>>     #
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index f92855af99ab..f37ab1a92e44 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -73,7 +73,7 @@ [LibraryClasses]
>>     #
>>     # RTC Library: Common RTC
>>     #
>> -  RealTimeClockLib|EmbeddedPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
>> +  RealTimeClockLib|Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>>   
>>     #
>>     # Library for FailSafe support
>> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>> new file mode 100644
>> index 000000000000..1fe561cc0ec9
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.inf
>> @@ -0,0 +1,44 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                      = 0x0001001B
>> +  MODULE_TYPE                      = BASE
>> +  BASE_NAME                        = PCF85063RealTimeClockLib
>> +  FILE_GUID                        = 271569F6-5522-4006-9FF5-F07A59473AAC
>> +  LIBRARY_CLASS                    = RealTimeClockLib
>> +  VERSION_STRING                   = 1.0
>> +
>> +[Sources.common]
>> +  PCF85063.c
>> +  PCF85063.h
>> +  PCF85063RealTimeClockLib.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  ArmGenericTimerCounterLib
>> +  ArmLib
>> +  BaseLib
>> +  DebugLib
>> +  GpioLib
>> +  DxeServicesTableLib
>> +  I2cLib
>> +  TimeBaseLib
>> +  TimerLib
>> +  UefiLib
>> +  UefiRuntimeLib
>> +
>> +[Guids]
>> +  gEfiEventVirtualAddressChangeGuid
>> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
>> new file mode 100644
>> index 000000000000..03ce4d29a03f
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.h
>> @@ -0,0 +1,91 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef PCF85063_H_
>> +#define PCF85063_H_
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Library/RealTimeClockLib.h>
>> +
>> +//
>> +// I2C bus address that RTC connected to
>> +//
>> +#define I2C_RTC_BUS_ADDRESS        1
>> +
>> +//
>> +// I2C RTC bus speed
>> +//
>> +#define I2C_RTC_BUS_SPEED          100000
>> +
>> +//
>> +// I2C chip address that RTC connected to
>> +//
>> +#define I2C_RTC_CHIP_ADDRESS       0x51
>> +
>> +//
>> +// The GPI PIN that tell if RTC can be access
>> +//
>> +#define I2C_RTC_ACCESS_GPIO_PIN    28
>> +
>> +/**
>> + * Returns the current time and date information of the hardware platform.
>> + *
>> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER Time is NULL.
>> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformGetTime (
>> +  OUT EFI_TIME *Time
>> +  );
>> +
>> +/**
>> + * Set the time and date information to the hardware platform.
>> + *
>> + * @param  Time                  A pointer to storage to set the current time to hardware platform.
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER Time is NULL.
>> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformSetTime (
>> +  IN EFI_TIME *Time
>> +  );
>> +
>> +/**
>> + * Callback function for hardware platform to convert data pointers to virtual address
>> + */
>> +VOID
>> +EFIAPI
>> +PlatformVirtualAddressChangeEvent (
>> +  VOID
>> +  );
>> +
>> +/**
>> + * Callback function for hardware platform to initialize private data
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval Others                The error status indicates the error
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformInitialize (
>> +  VOID
>> +  );
>> +
>> +#endif /* PCF85063_H_ */
>> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
>> new file mode 100644
>> index 000000000000..f9fa125d9d7e
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063.c
>> @@ -0,0 +1,317 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/GpioLib.h>
>> +#include <Library/I2cLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +
>> +#include "PCF85063.h"
>> +
>> +#define RTC_TIMEOUT_WAIT_ACCESS        100000 /* 100 miliseconds */
>> +#define RTC_DEFAULT_MIN_YEAR           2000
>> +#define RTC_DEFAULT_MAX_YEAR           2099
>> +
>> +#define RTC_ADDR                       0x4
>> +#define RTC_DATA_BUF_LEN               8
>> +
>> +/**
>> + * PCF85063 register offsets
>> + */
>> +#define PCF85063_OFFSET_SEC            0x0
>> +#define PCF85063_OFFSET_MIN            0x1
>> +#define PCF85063_OFFSET_HR             0x2
>> +#define PCF85063_OFFSET_DAY            0x3
>> +#define PCF85063_OFFSET_WKD            0x4
>> +#define PCF85063_OFFSET_MON            0x5
>> +#define PCF85063_OFFSET_YEA            0x6
>> +
>> +/**
>> + * PCF85063 encoding macros
>> + */
>> +#define PCF85063_SEC_ENC(s) (((((s) / 10) & 0x7) << 4) | (((s) % 10) & 0xf))
>> +#define PCF85063_MIN_ENC(m) (((((m) / 10) & 0x7) << 4) | (((m) % 10) & 0xf))
>> +#define PCF85063_HR_ENC(h)  (((((h) / 10) & 0x3) << 4) | (((h) % 10) & 0xf))
>> +#define PCF85063_DAY_ENC(d) (((((d) / 10) & 0x3) << 4) | (((d) % 10) & 0xf))
>> +#define PCF85063_WKD_ENC(w) ((w) & 0x7)
>> +#define PCF85063_MON_ENC(m) (((((m) / 10) & 0x1) << 4) | (((m) % 10) & 0xf))
>> +#define PCF85063_YEA_ENC(y) (((((y) / 10) & 0xf) << 4) | (((y) % 10) & 0xf))
>> +
>> +/**
>> + * PCF85063 decoding macros
>> + */
>> +#define PCF85063_SEC_DEC(s) (((((s) & 0x70) >> 4) * 10) + ((s) & 0xf))
>> +#define PCF85063_MIN_DEC(m) (((((m) & 0x70) >> 4) * 10) + ((m) & 0xf))
>> +#define PCF85063_HR_DEC(h)  (((((h) & 0x30) >> 4) * 10) + ((h) & 0xf))
>> +#define PCF85063_DAY_DEC(d) (((((d) & 0x30) >> 4)* 10) + ((d) & 0xf))
> *twitch*
> Please add that space before '*' like on all other lines.

Thanks. Will fix it in the v3.

Best regards,

Nhi

>
> With that:
> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
>
> /
>      Leif
>
>> +#define PCF85063_WKD_DEC(w) ((w) & 0x7)
>> +#define PCF85063_MON_DEC(m) (((((m) & 0x10) >> 4) * 10) + ((m) & 0xf))
>> +#define PCF85063_YEA_DEC(y) (((((y) & 0xf0) >> 4) * 10) + ((y) & 0xf))
>> +
>> +/* Buffer pointers to convert Vir2Phys and Phy2Vir */
>> +STATIC volatile UINT64 RtcBufVir;
>> +STATIC volatile UINT64 RtcBufPhy;
>> +
>> +STATIC
>> +EFI_STATUS
>> +RtcI2cWaitAccess (
>> +  VOID
>> +  )
>> +{
>> +  INTN Timeout;
>> +
>> +  Timeout = RTC_TIMEOUT_WAIT_ACCESS;
>> +  while ((GpioReadBit (I2C_RTC_ACCESS_GPIO_PIN) != 0) && (Timeout > 0)) {
>> +    MicroSecondDelay (100);
>> +    Timeout -= 100;
>> +  }
>> +
>> +  if (Timeout <= 0) {
>> +    DEBUG ((DEBUG_ERROR, "%a: Timeout while waiting access RTC\n", __FUNCTION__));
>> +    return EFI_TIMEOUT;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +RtcI2cRead (
>> +  IN     UINT8  Addr,
>> +  IN OUT UINT64 Data,
>> +  IN     UINT32 DataLen
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     TmpLen;
>> +
>> +  if (EFI_ERROR (RtcI2cWaitAccess ())) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  //
>> +  // Send the slave address for read
>> +  //
>> +  TmpLen = 1;
>> +  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, (UINT8 *)&Addr, &TmpLen);
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  //
>> +  // Read back the time
>> +  //
>> +  Status = I2cRead (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, NULL, 0, (UINT8 *)Data, &DataLen);
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +RtcI2cWrite (
>> +  IN UINT8  Addr,
>> +  IN UINT64 Data,
>> +  IN UINT32 DataLen
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT8      TmpBuf[RTC_DATA_BUF_LEN + 1];
>> +  UINT32     TmpLen;
>> +
>> +  if (EFI_ERROR (RtcI2cWaitAccess ())) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  if (DataLen > sizeof (TmpBuf) - 1) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  Status = I2cProbe (I2C_RTC_BUS_ADDRESS, I2C_RTC_BUS_SPEED);
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  //
>> +  // The first byte is the address
>> +  //
>> +  TmpBuf[0] = Addr;
>> +  TmpLen = DataLen + 1;
>> +  CopyMem ((VOID *)(TmpBuf + 1), (VOID *)Data, DataLen);
>> +
>> +  Status = I2cWrite (I2C_RTC_BUS_ADDRESS, I2C_RTC_CHIP_ADDRESS, TmpBuf, &TmpLen);
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + * Returns the current time and date information of the hardware platform.
>> + *
>> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER Time is NULL.
>> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformGetTime (
>> +  OUT EFI_TIME *Time
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT8      *Data;
>> +
>> +  if (Time == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  Status = RtcI2cRead (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
>> +
>> +  Data = (UINT8 *)RtcBufVir;
>> +  if (Status == EFI_SUCCESS) {
>> +    Time->Second = PCF85063_SEC_DEC (Data[PCF85063_OFFSET_SEC]);
>> +    Time->Minute = PCF85063_MIN_DEC (Data[PCF85063_OFFSET_MIN]);
>> +    Time->Hour   = PCF85063_HR_DEC (Data[PCF85063_OFFSET_HR]);
>> +    Time->Day    = PCF85063_DAY_DEC (Data[PCF85063_OFFSET_DAY]);
>> +    Time->Month  = PCF85063_MON_DEC (Data[PCF85063_OFFSET_MON]);
>> +    Time->Year   = PCF85063_YEA_DEC (Data[PCF85063_OFFSET_YEA]);
>> +    Time->Year  += RTC_DEFAULT_MIN_YEAR;
>> +    if (Time->Year > RTC_DEFAULT_MAX_YEAR) {
>> +      Time->Year = RTC_DEFAULT_MAX_YEAR;
>> +    }
>> +    if (Time->Year < RTC_DEFAULT_MIN_YEAR) {
>> +      Time->Year = RTC_DEFAULT_MIN_YEAR;
>> +    }
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> + * Set the time and date information to the hardware platform.
>> + *
>> + * @param  Time                  A pointer to storage to set the current time to hardware platform.
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER Time is NULL.
>> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
>> + **/
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformSetTime (
>> +  IN EFI_TIME *Time
>> +  )
>> +{
>> +  UINT8 *Data;
>> +
>> +  if (Time == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  if (Time->Year < RTC_DEFAULT_MIN_YEAR ||
>> +      Time->Year > RTC_DEFAULT_MAX_YEAR)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  Data = (UINT8 *)RtcBufVir;
>> +  Data[PCF85063_OFFSET_SEC] = PCF85063_SEC_ENC (Time->Second);
>> +  Data[PCF85063_OFFSET_MIN] = PCF85063_MIN_ENC (Time->Minute);
>> +  Data[PCF85063_OFFSET_HR]  = PCF85063_HR_ENC (Time->Hour);
>> +  Data[PCF85063_OFFSET_DAY] = PCF85063_DAY_ENC (Time->Day);
>> +  Data[PCF85063_OFFSET_MON] = PCF85063_MON_ENC (Time->Month);
>> +  Data[PCF85063_OFFSET_YEA] = PCF85063_YEA_ENC (Time->Year - RTC_DEFAULT_MIN_YEAR);
>> +
>> +  return RtcI2cWrite (RTC_ADDR, RtcBufVir, RTC_DATA_BUF_LEN);
>> +}
>> +
>> +/**
>> + * Callback function for hardware platform to convert data pointers to virtual address
>> + */
>> +VOID
>> +EFIAPI
>> +PlatformVirtualAddressChangeEvent (
>> +  VOID
>> +  )
>> +{
>> +  EfiConvertPointer (0x0, (VOID **)&RtcBufVir);
>> +}
>> +
>> +/**
>> + * Callback function for hardware platform to initialize private data
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval Others                The error status indicates the error
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +PlatformInitialize (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  /*
>> +   * Allocate the buffer for RTC data
>> +   * The buffer can be accessible after ExitBootServices
>> +   */
>> +  RtcBufVir = (UINT64)AllocateRuntimeZeroPool (RTC_DATA_BUF_LEN);
>> +  ASSERT_EFI_ERROR (RtcBufVir);
>> +  RtcBufPhy = (UINT64)RtcBufVir;
>> +
>> +  Status = I2cSetupRuntime (I2C_RTC_BUS_ADDRESS);
>> +  ASSERT_EFI_ERROR (Status);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((
>> +      DEBUG_ERROR,
>> +      "%a:%d I2cSetupRuntime() failed - %r \n",
>> +      __FUNCTION__,
>> +      __LINE__,
>> +      Status
>> +      ));
>> +    return Status;
>> +  }
>> +
>> +  Status = GpioSetupRuntime (I2C_RTC_ACCESS_GPIO_PIN);
>> +  ASSERT_EFI_ERROR (Status);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((
>> +      DEBUG_ERROR,
>> +      "%a:%d GpioSetupRuntime() failed - %r \n",
>> +      __FUNCTION__,
>> +      __LINE__,
>> +      Status
>> +      ));
>> +    return Status;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
>> new file mode 100755
>> index 000000000000..ef8c71e92c18
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PCF85063RealTimeClockLib/PCF85063RealTimeClockLib.c
>> @@ -0,0 +1,257 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiDxe.h>
>> +#include <Uefi.h>
>> +
>> +#include <Guid/EventGroup.h>
>> +#include <Library/ArmGenericTimerCounterLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DxeServicesTableLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/RealTimeClockLib.h>
>> +#include <Library/TimeBaseLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Protocol/RealTimeClock.h>
>> +
>> +#include "PCF85063.h"
>> +
>> +#define TICKS_PER_SEC     (ArmGenericTimerGetTimerFreq ())
>> +
>> +STATIC EFI_EVENT          mVirtualAddressChangeEvent = NULL;
>> +
>> +STATIC UINT64             mLastSavedSystemCount = 0;
>> +STATIC UINT64             mLastSavedTimeEpoch = 0;
>> +
>> +/**
>> + * Returns the current time and date information, and the time-keeping capabilities
>> + * of the hardware platform.
>> + *
>> + * @param  Time                  A pointer to storage to receive a snapshot of the current time.
>> + * @param  Capabilities          An optional pointer to a buffer to receive the real time clock
>> + *                               device's capabilities.
>> + *
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER Time is NULL.
>> + * @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +LibGetTime (
>> +  OUT EFI_TIME                *Time,
>> +  OUT EFI_TIME_CAPABILITIES   *Capabilities
>> +  )
>> +{
>> +  EFI_STATUS    Status;
>> +  UINT64        CurrentSystemCount;
>> +  UINT64        TimeElapsed;
>> +  UINTN         EpochSeconds;
>> +
>> +  if ((mLastSavedTimeEpoch == 0) || EfiAtRuntime ()) {
>> +    Status = PlatformGetTime (Time);
>> +    if (EFI_ERROR (Status)) {
>> +      // Failed to read platform RTC so create fake time
>> +      Time->Second = 0;
>> +      Time->Minute = 0;
>> +      Time->Hour = 10;
>> +      Time->Day = 1;
>> +      Time->Month = 1;
>> +      Time->Year = 2017;
>> +    }
>> +
>> +    EpochSeconds = EfiTimeToEpoch (Time);
>> +    if (!EfiAtRuntime ()) {
>> +      mLastSavedTimeEpoch = EpochSeconds;
>> +      mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
>> +    }
>> +  } else {
>> +    CurrentSystemCount = ArmGenericTimerGetSystemCount ();
>> +    if (CurrentSystemCount >= mLastSavedSystemCount) {
>> +      TimeElapsed = (CurrentSystemCount - mLastSavedSystemCount) / MultU64x32 (1, TICKS_PER_SEC);
>> +      EpochSeconds = mLastSavedTimeEpoch + TimeElapsed;
>> +    } else {
>> +      // System counter overflow 64 bits
>> +      // Call GetTime again to read the date from RTC HW, not using generic timer system counter
>> +      mLastSavedTimeEpoch = 0;
>> +      return LibGetTime (Time, Capabilities);
>> +    }
>> +  }
>> +
>> +  // Adjust for the correct timezone
>> +  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
>> +    EpochSeconds += Time->TimeZone * SEC_PER_MIN;
>> +  }
>> +
>> +  // Adjust for the correct period
>> +  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
>> +    // Convert to adjusted time, i.e. spring forwards one hour
>> +    EpochSeconds += SEC_PER_HOUR;
>> +  }
>> +
>> +  EpochToEfiTime (EpochSeconds, Time);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + * Sets the current local time and date information.
>> + *
>> + * @param  Time                  A pointer to the current time.
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + * @retval EFI_INVALID_PARAMETER A time field is out of range.
>> + * @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +LibSetTime (
>> +  IN EFI_TIME                *Time
>> +  )
>> +{
>> +  EFI_STATUS    Status;
>> +  UINTN         EpochSeconds;
>> +
>> +  EpochSeconds = EfiTimeToEpoch (Time);
>> +
>> +  // Adjust for the correct time zone, i.e. convert to UTC time zone
>> +  if (Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) {
>> +    EpochSeconds -= Time->TimeZone * SEC_PER_MIN;
>> +  }
>> +
>> +  // Adjust for the correct period, i.e. fall back one hour
>> +  if ((Time->Daylight & EFI_TIME_IN_DAYLIGHT) == EFI_TIME_IN_DAYLIGHT) {
>> +    EpochSeconds -= SEC_PER_HOUR;
>> +  }
>> +
>> +  EpochToEfiTime (EpochSeconds, Time);
>> +
>> +  Status = PlatformSetTime (Time);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  if (!EfiAtRuntime ()) {
>> +    mLastSavedTimeEpoch = EpochSeconds;
>> +    mLastSavedSystemCount = ArmGenericTimerGetSystemCount ();
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> + * Returns the current wakeup alarm clock setting.
>> + *
>> + * @param  Enabled               Indicates if the alarm is currently enabled or disabled.
>> + * @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
>> + * @param  Time                  The current alarm setting.
>> + *
>> + * @retval EFI_SUCCESS           The alarm settings were returned.
>> + * @retval EFI_INVALID_PARAMETER Any parameter is NULL.
>> + * @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +LibGetWakeupTime (
>> +  OUT BOOLEAN     *Enabled,
>> +  OUT BOOLEAN     *Pending,
>> +  OUT EFI_TIME    *Time
>> +  )
>> +{
>> +  return EFI_UNSUPPORTED;
>> +}
>> +
>> +/**
>> + * Sets the system wakeup alarm clock time.
>> + *
>> + * @param  Enabled               Enable or disable the wakeup alarm.
>> + * @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
>> + *
>> + * @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
>> + *                               Enable is FALSE, then the wakeup alarm was disabled.
>> + * @retval EFI_INVALID_PARAMETER A time field is out of range.
>> + * @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
>> + * @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +LibSetWakeupTime (
>> +  IN BOOLEAN      Enabled,
>> +  OUT EFI_TIME    *Time
>> +  )
>> +{
>> +  return EFI_UNSUPPORTED;
>> +}
>> +
>> +/**
>> +  Fixup internal data so that EFI can be call in virtual mode.
>> +  Call the passed in Child Notify event and convert any pointers in
>> +  lib to virtual mode.
>> +
>> +  @param[in]    Event   The Event that is being processed
>> +  @param[in]    Context Event Context
>> +**/
>> +VOID
>> +EFIAPI
>> +LibRtcVirtualNotifyEvent (
>> +  IN EFI_EVENT        Event,
>> +  IN VOID             *Context
>> +  )
>> +{
>> +  //
>> +  // Only needed if you are going to support the OS calling RTC functions in virtual mode.
>> +  // You will need to call EfiConvertPointer (). To convert any stored physical addresses
>> +  // to virtual address. After the OS transitions to calling in virtual mode, all future
>> +  // runtime calls will be made in virtual mode.
>> +  //
>> +  PlatformVirtualAddressChangeEvent ();
>> +}
>> +
>> +/**
>> + * This is the declaration of an EFI image entry point. This can be the entry point to an application
>> + * written to this specification, an EFI boot service driver, or an EFI runtime driver.
>> + *
>> + * @param  ImageHandle           Handle that identifies the loaded image.
>> + * @param  SystemTable           System Table for this image.
>> + *
>> + * @retval EFI_SUCCESS           The operation completed successfully.
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +LibRtcInitialize (
>> +  IN EFI_HANDLE                            ImageHandle,
>> +  IN EFI_SYSTEM_TABLE                      *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS    Status;
>> +
>> +  Status = PlatformInitialize ();
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Register for the virtual address change event
>> +  //
>> +  Status = gBS->CreateEventEx (
>> +                  EVT_NOTIFY_SIGNAL,
>> +                  TPL_NOTIFY,
>> +                  LibRtcVirtualNotifyEvent,
>> +                  NULL,
>> +                  &gEfiEventVirtualAddressChangeGuid,
>> +                  &mVirtualAddressChangeEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support
  2021-06-04 23:27   ` Leif Lindholm
@ 2021-06-15 16:48     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:48 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/5/21 06:27, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:00 +0700, Nhi Pham wrote:
>> From: Quan Nguyen <quan@os.amperecomputing.com>
>>
>> BootProgress will send 32-bit UEFI Status Code via doorbell to report
>> its progress status.
>> Currently support reporting Progress Status Code and Error Status Code
>> only. Other types of Status Code are ignored.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
> This looks like something that would be a good target to commonalise
> between platforms in the future. But for now:

Yes, I'm also interested in contributing this feature in the future as 
we need a standard mechanism for boot progress reporting.

Best regards,

Nhi

> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
>
> /
>      Leif
>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                                     |   2 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                                         |   2 +
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf   |  51 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf |  49 +++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c     | 211 ++++++++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c   | 210 +++++++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni   |  16 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni |  18 ++
>>   8 files changed, 559 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 9f19f495fad2..9f75da6f05ad 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -529,6 +529,7 @@ [Components.common]
>>     }
>>     MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
>>     MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>>   
>>     #
>>     # DXE Phase modules
>> @@ -539,6 +540,7 @@ [Components.common]
>>     }
>>     MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>>     MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>>   
>>     #
>>     # PCD
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 80a86d7c1156..1857296a8ea5 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -102,6 +102,7 @@ [FV.FVMAIN_COMPACT]
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>>     INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>>     INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>>     INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>> @@ -149,6 +150,7 @@ [FV.FvMain]
>>     INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
>>     INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>>     INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>>   
>>     #
>>     # PI DXE Drivers producing Architectural Protocols (EFI Services)
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>> new file mode 100644
>> index 000000000000..2211a213a6df
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.inf
>> @@ -0,0 +1,51 @@
>> +## @file
>> +#  This module installs Boot Progress Dxe.
>> +#
>> +#  This module registers report status code listener to report boot progress
>> +#  to SMpro.
>> +#
>> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = BootProgressDxe
>> +  MODULE_UNI_FILE                = BootProgressDxe.uni
>> +  FILE_GUID                      = 6E12F248-F0C1-11EA-B37C-9798918A2163
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = BootProgressDxeEntryPoint
>> +
>> +#
>> +# The following information is for reference only and not required by the build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = AARCH64
>> +#
>> +
>> +[Sources]
>> +  BootProgressDxe.c
>> +
>> +[Packages]
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +
>> +[LibraryClasses]
>> +  AmpereCpuLib
>> +  BaseLib
>> +  DebugLib
>> +  DxeServicesLib
>> +  SystemFirmwareInterfaceLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +  UefiRuntimeServicesTableLib
>> +
>> +[Protocols]
>> +  gEfiRscHandlerProtocolGuid                    ## CONSUMES
>> +
>> +[Depex]
>> +  gEfiRscHandlerProtocolGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>> new file mode 100644
>> index 000000000000..1dd0ec31ac37
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>> @@ -0,0 +1,49 @@
>> +## @file
>> +#  Boot Progress Pei Module.
>> +#
>> +#  Updates to SCP with Boot Progress information during boot.
>> +#
>> +#  This module register report status code listener to collect boot progress
>> +#  information and keep SCP posted.
>> +#
>> +#  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +#  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = BootProgressPeim
>> +  MODULE_UNI_FILE                = BootProgressPeim.uni
>> +  FILE_GUID                      = 2E8A3B3E-F26C-11EA-BDE5-6726AD8F88BD
>> +  MODULE_TYPE                    = PEIM
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = BootProgressPeiEntryPoint
>> +
>> +#
>> +# The following information is for reference only and not required by the build tools.
>> +#
>> +#  VALID_ARCHITECTURES           = AARCH64
>> +#
>> +
>> +[Sources]
>> +  BootProgressPeim.c
>> +
>> +[Packages]
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  DebugLib
>> +  PeiServicesLib
>> +  PeimEntryPoint
>> +  SystemFirmwareInterfaceLib
>> +
>> +[Ppis]
>> +  gEfiPeiRscHandlerPpiGuid                      ## CONSUMES
>> +
>> +[Depex]
>> +  gEfiPeiRscHandlerPpiGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
>> new file mode 100644
>> index 000000000000..f87a4d53179f
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.c
>> @@ -0,0 +1,211 @@
>> +/** @file
>> +
>> +  This module installs Boot Progress Dxe that report boot progress to SMpro.
>> +
>> +  This module registers report status code listener to report boot progress
>> +  to SMpro.
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiDxe.h>
>> +
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DxeServicesLib.h>
>> +#include <Library/SystemFirmwareInterfaceLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Pi/PiStatusCode.h>
>> +#include <Protocol/ReportStatusCodeHandler.h>
>> +
>> +typedef struct {
>> +  UINT8                 Byte;
>> +  EFI_STATUS_CODE_VALUE Value;
>> +} STATUS_CODE_TO_CHECKPOINT;
>> +
>> +enum BOOT_PROGRESS_STATE {
>> +  BOOT_NOTSTART = 0,
>> +  BOOT_START    = 1,
>> +  BOOT_COMPLETE = 2,
>> +  BOOT_FAILED   = 3,
>> +};
>> +
>> +UINT32 DxeProgressCode[] = {
>> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),                     // DXE Core is started
>> +  (EFI_COMPUTING_UNIT_CHIPSET | EFI_CHIPSET_PC_DXE_HB_INIT),                    // PCI host bridge initialization
>> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT),                 // Boot Device Selection (BDS) phase is started
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_BEGIN_CONNECTING_DRIVERS),     // Driver connecting is started
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_INIT),                                           // PCI Bus initialization is started
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_HPC_INIT),                                      // PCI Bus Hot Plug Controller Initialization
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_BUS_ENUM),                                      // PCI Bus Enumeration
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PCI_RES_ALLOC),                                     // PCI Bus Request Resources
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_ENABLE),                                         // PCI Bus Assign Resources
>> +  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_INIT),                               // Console Output devices connect
>> +  (EFI_PERIPHERAL_KEYBOARD | EFI_P_PC_INIT),                                    // Console input devices connect
>> +  (EFI_IO_BUS_LPC | EFI_IOB_PC_INIT),                                           // Super IO Initialization
>> +  (EFI_IO_BUS_USB | EFI_IOB_PC_INIT),                                           // USB initialization is started
>> +  (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),                                          // USB Reset
>> +  (EFI_IO_BUS_USB | EFI_IOB_PC_DETECT),                                         // USB Detect
>> +  (EFI_IO_BUS_USB | EFI_IOB_PC_ENABLE),                                         // USB Enable
>> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_INIT),                                          // SCSI initialization is started
>> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_RESET),                                         // SCSI Reset
>> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_DETECT),                                        // SCSI Detect
>> +  (EFI_IO_BUS_SCSI | EFI_IOB_PC_ENABLE),                                        // SCSI Enable
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VERIFYING_PASSWORD),           // Setup Verifying Password
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_USER_SETUP),                          // Start of Setup
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT),                          // Setup Input Wait
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT),          // Ready To Boot event
>> +  (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES),            // Exit Boot Services event
>> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_SET_VIRTUAL_ADDRESS_MAP),    // Runtime Set Virtual Address MAP Begin
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_VIRTUAL_ADDRESS_CHANGE_EVENT), // Runtime Set Virtual Address MAP End
>> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM),               // System Reset
>> +  (EFI_IO_BUS_USB | EFI_IOB_PC_HOTPLUG),                                        // USB hot plug
>> +  (EFI_IO_BUS_PCI | EFI_IOB_PC_HOTPLUG),                                        // PCI bus hot plug
>> +  0                                                                             // Must ended by 0
>> +};
>> +
>> +UINT32 DxeErrorCode[] = {
>> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_EC_NO_ARCH),                   // Some of the Architectural Protocols are not available
>> +  (EFI_IO_BUS_PCI | EFI_IOB_EC_RESOURCE_CONFLICT),                        // PCI resource allocation error. Out of Resources
>> +  (EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_NOT_DETECTED),                 // No Console Output Devices are found
>> +  (EFI_PERIPHERAL_KEYBOARD | EFI_P_EC_NOT_DETECTED),                      // No Console Input Devices are found
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_INVALID_PASSWORD),       // Invalid password
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_LOAD_ERROR), // Error loading Boot Option (LoadImage returned error)
>> +  (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_EC_BOOT_OPTION_FAILED),     // Boot Option is failed (StartImage returned error)
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_UPDATE_FAIL),             // Flash update is failed
>> +  (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),  // Reset protocol is not available
>> +  0                                                                       // Must end by 0
>> +};
>> +
>> +EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
>> +
>> +STATIC UINT8 mBootstate = BOOT_START;
>> +
>> +STATIC
>> +BOOLEAN
>> +StatusCodeFilter (
>> +  UINT32                *Map,
>> +  EFI_STATUS_CODE_VALUE Value
>> +  )
>> +{
>> +  UINTN Index = 0;
>> +
>> +  while (Map[Index] != 0) {
>> +    if (Map[Index] == Value) {
>> +      return TRUE;
>> +    }
>> +    Index++;
>> +  }
>> +  return FALSE;
>> +}
>> +
>> +/**
>> +  Report status code listener of Boot Progress Dxe.
>> +
>> +  @param[in]  CodeType            Indicates the type of status code being reported.
>> +  @param[in]  Value               Describes the current status of a hardware or software entity.
>> +                                  This included information about the class and subclass that is used to
>> +                                  classify the entity as well as an operation.
>> +  @param[in]  Instance            The enumeration of a hardware or software entity within
>> +                                  the system. Valid instance numbers start with 1.
>> +  @param[in]  CallerId            This optional parameter may be used to identify the caller.
>> +                                  This parameter allows the status code driver to apply different rules to
>> +                                  different callers.
>> +  @param[in]  Data                This optional parameter may be used to pass additional data.
>> +
>> +  @retval EFI_SUCCESS             Status code is what we expected.
>> +  @retval EFI_UNSUPPORTED         Status code not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +BootProgressListenerDxe (
>> +  IN EFI_STATUS_CODE_TYPE  CodeType,
>> +  IN EFI_STATUS_CODE_VALUE Value,
>> +  IN UINT32                Instance,
>> +  IN EFI_GUID              *CallerId,
>> +  IN EFI_STATUS_CODE_DATA  *Data
>> +  )
>> +{
>> +  BOOLEAN IsProgress = FALSE;
>> +  BOOLEAN IsError = FALSE;
>> +
>> +  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
>> +    IsProgress = StatusCodeFilter (DxeProgressCode, Value);
>> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
>> +    IsError = StatusCodeFilter (DxeErrorCode, Value);
>> +  } else {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  if (!IsProgress && !IsError) {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  DEBUG ((
>> +    DEBUG_INFO,
>> +    "BootProgressDxe: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
>> +    CodeType,
>> +    Value,
>> +    Instance,
>> +    CallerId,
>> +    Data
>> +    ));
>> +
>> +  if (IsError) {
>> +    mBootstate = BOOT_FAILED;
>> +  } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_READY_TO_BOOT_EVENT)) {
>> +    /* Set boot complete when reach to ReadyToBoot event */
>> +    mBootstate = BOOT_COMPLETE;
>> +  }
>> +
>> +  MailboxMsgSetBootProgress (0, mBootstate, Value);
>> +
>> +  if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES) &&
>> +      mRscHandlerProtocol != NULL)
>> +  {
>> +    mRscHandlerProtocol->Unregister (BootProgressListenerDxe);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +
>> +/**
>> +  The module Entry Point of the Firmware Performance Data Table DXE driver.
>> +
>> +  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
>> +  @param[in]  SystemTable    A pointer to the EFI System Table.
>> +
>> +  @retval EFI_SUCCESS    The entry point is executed successfully.
>> +  @retval Other          Some error occurs when executing this entry point.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +BootProgressDxeEntryPoint (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  //
>> +  // Get Report Status Code Handler Protocol.
>> +  //
>> +  Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **)&mRscHandlerProtocol);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  //
>> +  // Register report status code listener for OS Loader load and start.
>> +  //
>> +  if (!EFI_ERROR (Status)) {
>> +    Status = mRscHandlerProtocol->Register (BootProgressListenerDxe, TPL_HIGH_LEVEL);
>> +  }
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
>> new file mode 100644
>> index 000000000000..c677e27a00ce
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.c
>> @@ -0,0 +1,210 @@
>> +/** @file
>> +
>> +  This module installs Boot Progress Pei to report boot progress to SMpro.
>> +
>> +  This module registers report status code listener to report boot progress
>> +  to SMpro.
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiPei.h>
>> +
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/PeiServicesLib.h>
>> +#include <Library/SystemFirmwareInterfaceLib.h>
>> +#include <Pi/PiStatusCode.h>
>> +#include <Ppi/ReportStatusCodeHandler.h>
>> +
>> +enum BOOT_PROGRESS_STATE {
>> +  BOOT_NOTSTART = 0,
>> +  BOOT_START    = 1,
>> +  BOOT_COMPLETE = 2,
>> +  BOOT_FAILED   = 3,
>> +};
>> +
>> +UINT32 PeiProgressStatusCode[] = {
>> +  // Regular boot
>> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_ENTRY_POINT),         // PEI Core is started
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_POWER_ON_INIT), // Pre-memory CPU initialization is started
>> +  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_PC_INSTALL_PEI_MEMORY),     // Memory Installed
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_PC_INIT_BEGIN),       // CPU post-memory initialization is started
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_CACHE_INIT),    // CPU post-memory initialization. Cache initialization
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_AP_INIT),       // CPU post-memory initialization. Application Processor(s) (AP) initialization
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_BSP_SELECT),    // CPU post-memory initialization. Boot Strap Processor (BSP) selection
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT),      // CPU post-memory initialization. System Management Mode (SMM) initialization
>> +  // DXE IPL is started
>> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT), // DXE IPL is started
>> +  // DXE Core is started
>> +  (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT),     // DXE Core is started
>> +  // Recovery
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_AUTO),  // Recovery condition triggered by firmware (Auto recovery)
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_USER),  // Recovery condition triggered by user (Forced recovery)
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN), // Recovery process started
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD),   // Recovery firmware image is found
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START),  // Recovery firmware image is loaded
>> +  // S3
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_S3_BOOT_SCRIPT), // S3 Boot Script execution
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE),        // OS S3 wake vector call
>> +  0                                                         // Must end with 0
>> +};
>> +
>> +UINT32 PeiErrorStatusCode[] = {
>> +  // Regular boot
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_TYPE),       // Memory initialization error. Invalid memory type
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SPEED),      // Memory initialization error. Incompatible memory speed
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_SPD_FAIL),           // Memory initialization error. SPD reading has failed
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_INVALID_SIZE),       // Memory initialization error. Invalid memory size
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_MISMATCH),           // Memory initialization error. Memory modules do not match
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_DETECTED),      // Memory initialization error. No usable memory detected
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_NONE_USEFUL),        // Memory initialization error. No usable memory detected
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_EC_NON_SPECIFIC),              // Unspecified memory initialization error.
>> +  (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_EC_MEMORY_NOT_INSTALLED), // Memory not installed
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_TYPE),   // Invalid CPU type
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INVALID_SPEED),  // Invalid CPU Speed
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_MISMATCH),       // CPU mismatch
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_SELF_TEST),      // CPU self test failed
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_CACHE),          // possible CPU cache error
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_EC_INTERNAL),       // Internal CPU error
>> +  (EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_EC_NON_SPECIFIC),      // Internal CPU error
>> +  (EFI_SOFTWARE_PEI_SERVICE | EFI_SW_PS_EC_RESET_NOT_AVAILABLE),     // reset PPI is not available
>> +  // Recovery
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND),     // Recovery PPI is not available
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE),        // Recovery capsule is not found
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_INVALID_CAPSULE_DESCRIPTOR), // Invalid recovery capsule
>> +  // S3 Resume
>> +  (EFI_COMPUTING_UNIT_MEMORY | EFI_CU_MEMORY_EC_S3_RESUME_FAIL),     // S3 Resume Failed
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND), // S3 Resume PPI not found
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_BOOT_SCRIPT_ERROR),    // S3 Resume Boot Script Error
>> +  (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_OS_WAKE_ERROR),        // S3 OS Wake Error
>> +  0
>> +};
>> +
>> +// Should always be BOOT_START when start
>> +STATIC UINT8 mBootstate = BOOT_START;
>> +
>> +STATIC
>> +BOOLEAN
>> +StatusCodeFilter (
>> +  UINT32                *Map,
>> +  EFI_STATUS_CODE_VALUE Value
>> +  )
>> +{
>> +  UINTN Index = 0;
>> +
>> +  while (Map[Index] != 0) {
>> +    if (Map[Index] == Value) {
>> +      return TRUE;
>> +    }
>> +    Index++;
>> +  }
>> +
>> +  return FALSE;
>> +}
>> +
>> +/**
>> +  Report status code listener for PEI. This is used to record the boot progress info
>> +  and report it to SMpro.
>> +
>> +  @param[in]  PeiServices         An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
>> +  @param[in]  CodeType            Indicates the type of status code being reported.
>> +  @param[in]  Value               Describes the current status of a hardware or software entity.
>> +                                  This included information about the class and subclass that is used to
>> +                                  classify the entity as well as an operation.
>> +  @param[in]  Instance            The enumeration of a hardware or software entity within
>> +                                  the system. Valid instance numbers start with 1.
>> +  @param[in]  CallerId            This optional parameter may be used to identify the caller.
>> +                                  This parameter allows the status code driver to apply different rules to
>> +                                  different callers.
>> +  @param[in]  Data                This optional parameter may be used to pass additional data.
>> +
>> +  @retval EFI_SUCCESS             Status code is what we expected.
>> +  @retval EFI_UNSUPPORTED         Status code not supported.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +BootProgressListenerPei (
>> +  IN       CONST EFI_PEI_SERVICES **PeiServices,
>> +  IN       EFI_STATUS_CODE_TYPE   CodeType,
>> +  IN       EFI_STATUS_CODE_VALUE  Value,
>> +  IN       UINT32                 Instance,
>> +  IN CONST EFI_GUID               *CallerId,
>> +  IN CONST EFI_STATUS_CODE_DATA   *Data
>> +  )
>> +{
>> +  BOOLEAN IsProgress = FALSE;
>> +  BOOLEAN IsError = FALSE;
>> +
>> +  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {
>> +    IsProgress = StatusCodeFilter (PeiProgressStatusCode, Value);
>> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {
>> +    IsError = StatusCodeFilter (PeiErrorStatusCode, Value);
>> +  } else {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  // No interested status found
>> +  if (!IsProgress && !IsError) {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  DEBUG ((
>> +    DEBUG_INFO,
>> +    "BootProgressPeim: CodeType=0x%X Value=0x%X Instance=0x%X CallerIdGuid=%g Data=%p\n",
>> +    CodeType,
>> +    Value,
>> +    Instance,
>> +    CallerId,
>> +    Data
>> +    ));
>> +
>> +  if (IsError) {
>> +    mBootstate = BOOT_FAILED;
>> +  }
>> +
>> +  MailboxMsgSetBootProgress (0, mBootstate, Value);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Main entry for Boot Progress PEIM.
>> +
>> +  This routine is to register report status code listener for Boot Progress PEIM.
>> +
>> +  @param[in]  FileHandle              Handle of the file being invoked.
>> +  @param[in]  PeiServices             Pointer to PEI Services table.
>> +
>> +  @retval EFI_SUCCESS Report status code listener is registered successfully.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +BootProgressPeiEntryPoint (
>> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
>> +  IN CONST EFI_PEI_SERVICES    **PeiServices
>> +  )
>> +{
>> +  EFI_STATUS              Status;
>> +  EFI_PEI_RSC_HANDLER_PPI *RscHandler;
>> +
>> +  Status = PeiServicesLocatePpi (
>> +             &gEfiPeiRscHandlerPpiGuid,
>> +             0,
>> +             NULL,
>> +             (VOID **)&RscHandler
>> +             );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  if (!EFI_ERROR (Status)) {
>> +    Status = RscHandler->Register (BootProgressListenerPei);
>> +  }
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
>> new file mode 100644
>> index 000000000000..492e85404631
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressDxe/BootProgressDxe.uni
>> @@ -0,0 +1,16 @@
>> +//
>> +// This module installs Boot Progress Dxe that report boot progress to SMpro.
>> +//
>> +// This module registers report status code listener to report boot progress
>> +// for SMpro.
>> +//
>> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +//
>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>> +//
>> +//
>> +
>> +
>> +#string STR_MODULE_ABSTRACT             #language en-US "Installs Boot Progress Driver"
>> +
>> +#string STR_MODULE_DESCRIPTION          #language en-US "This module registers report status code listener to collect and report boot progress to SMpro."
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
>> new file mode 100644
>> index 000000000000..0371fc4f9a80
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.uni
>> @@ -0,0 +1,18 @@
>> +//
>> +// Boot Progress Pei Module.
>> +//
>> +// Updates to SCP with Boot Progress information during boot
>> +//
>> +// This module register report status code listener to collect boot progress
>> +// information and keep SCP posted.
>> +//
>> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +//
>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>> +//
>> +//
>> +
>> +
>> +#string STR_MODULE_ABSTRACT             #language en-US "Boot Progress Pei Module."
>> +
>> +#string STR_MODULE_DESCRIPTION          #language en-US "Updates SCP with boot progress information during boot. This module register report status code listener to collect boot progress information and post to SCP."
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables
  2021-06-04 23:36   ` Leif Lindholm
@ 2021-06-15 16:48     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:48 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/5/21 06:36, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:01 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> Non-volatile variables now can be stored on flash. MM communication
>> protocol is used to access storage on flash.
>>
>> Included in this change are:
>> * FlashPei module is used to compare saved UUID with firmware's
>>    UEFI_UUID on each boot. If UUIDs match, data is stored to RAM.
>>    Otherwise fill the storage with default value from NVRAM FV.
>> * FlashLib provide APIs to access flash through MM Communication
>>    protocol
>> * FlashFvbDxe installs gEfiFirmwareVolumeBlock protocol which will be
>>    used by the variable services to get/set variables.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                  |   3 +
>>   Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec              |   3 +
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc              |  11 +-
>>   Platform/Ampere/JadePkg/Jade.dsc                                  |   1 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                  |  62 ++-
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf |  54 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf       |  51 ++
>>   Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf       |  36 ++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h          |  42 ++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c   | 525 ++++++++++++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c         | 283 +++++++++++
>>   Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c         | 358 +++++++++++++
>>   12 files changed, 1425 insertions(+), 4 deletions(-)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> index be827dd19a96..d5b12a81e9bf 100644
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> @@ -37,6 +37,9 @@ [LibraryClasses]
>>     ##  @libraryclass  Defines a set of methods to communicate with secure parition over MM interface.
>>     MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/MmCommunicationLib.h
>>   
>> +  ##  @libraryclass  Defines a set of methods to access flash memory.
>> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>> +
>>     ##  @libraryclass  Defines a set of methods to generate random numbers by using Hardware RNG.
>>     TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h
>>   
>> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> index 6ebdf7db0a57..26e020715290 100755
>> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> @@ -44,3 +44,6 @@ [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
>>     # Firmware Volume Pcds
>>     #
>>     gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
>> +
>> +  # NVRam Pcds
>> +  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 9f75da6f05ad..65973569a41d 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -14,6 +14,7 @@ [BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
>>   
>>   [BuildOptions]
>>     GCC:RELEASE_*_*_CC_FLAGS  = -DMDEPKG_NDEBUG
>> +  GCC:*_*_*_CC_FLAGS = -DUEFI_UUID=$(UEFI_UUID)
> This isn't obvious enough. I'm a bear of very little brain, and I
> could possibly figure out what's happening here, given time, but
> please put a proper description in commit message (and possibly here?
> whatever makes sense).

Thanks, Leif. I will use a PCD instead of build option flag like above 
and will update the commit message to explain how it works.

Best regards,

Nhi

>
>>   
>>   [LibraryClasses.common]
>>   !if $(TARGET) == RELEASE
>> @@ -224,6 +225,7 @@ [LibraryClasses.common.DXE_DRIVER]
>>     SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
>>     PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
>>     MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
>> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>>   
>>   [LibraryClasses.common.UEFI_APPLICATION]
>>     UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiTianoCustomDecompressLib.inf
>> @@ -254,6 +256,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER]
>>   
>>     EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
>>     ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
>> +  FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>>   
>>   [LibraryClasses.ARM,LibraryClasses.AARCH64]
>>     #
>> @@ -500,6 +503,8 @@ [PcdsDynamicDefault.common]
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|0x0
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|0x0
>>   
>> +  gAmpereTokenSpaceGuid.PcdNvramErased|FALSE
>> +
>>   ################################################################################
>>   #
>>   # Component Section - list of all EDK II Component Entries defined by this Platform
>> @@ -520,8 +525,10 @@ [Components.common]
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>>     ArmPkg/Drivers/CpuPei/CpuPei.inf
>>     UefiCpuPkg/CpuIoPei/CpuIoPei.inf
>> +  MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
>>     MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>>     MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf {
>>       <LibraryClasses>
>> @@ -575,9 +582,9 @@ [Components.common]
>>     #
>>     # Environment Variables Protocol
>>     #
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>> +  MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>>     MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf {
>> -    <PcdsFixedAtBuild>
>> -      gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable|TRUE
>>       <LibraryClasses>
>>         BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
>>         TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index f37ab1a92e44..9b9a5d0bad0f 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -52,6 +52,7 @@ [Defines]
>>     DEFINE EDK2_SKIP_PEICORE       = TRUE
>>     DEFINE SECURE_BOOT_ENABLE      = FALSE
>>     DEFINE INCLUDE_TFTP_COMMAND    = TRUE
>> +  DEFINE UEFI_UUID               = 84BC921F-9D4A-4D1D-A1A1-1AE13EDD07E5
> This is a horrible name for a UUID. What is it meant to identify?
>
>>     #
>>     # Network definition
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 1857296a8ea5..375455086d0b 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -26,7 +26,7 @@ [FD.BL33_JADE_UEFI]
>>   ErasePolarity = 1
>>   
>>   # This one is tricky, it must be: BlockSize * NumBlocks = Size
>> -BlockSize     = 0x10000
>> +BlockSize     = 0x10000|gAmpereTokenSpaceGuid.PcdFvBlockSize
>>   NumBlocks     = 0x7C
>>   
>>   ################################################################################
>> @@ -56,8 +56,61 @@ [FD.BL33_JADE_UEFI]
>>   
>>   #
>>   # NV Variables
>> -# T.B.D
> Ah. If I can make a retroactive comment - could this be introduced as
> "Placeholder" rather than "T.B.D."?
>
> /
>      Leif
>
>> +# Offset: 0x00740000
>> +# Size:   0x00080000
>>   #
>> +0x00740000|0x00030000
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
>> +DATA = {
>> +  ## This is the EFI_FIRMWARE_VOLUME_HEADER
>> +  # ZeroVector []
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  # FileSystemGuid: gEfiSystemNvDataFvGuid         =
>> +  #   { 0xFFF12B8D, 0x7696, 0x4C8B,
>> +  #     { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }}
>> +  0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C,
>> +  0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50,
>> +  # FvLength: 0x80000
>> +  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  # Signature "_FVH"       # Attributes
>> +  0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00,
>> +  # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision
>> +  0x48, 0x00, 0x2D, 0x09, 0x00, 0x00, 0x00, 0x02,
>> +  # Blockmap[0]: 0x2 Blocks * 0x40000 Bytes / Block
>> +  0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
>> +  # Blockmap[1]: End
>> +  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>> +  ## This is the VARIABLE_STORE_HEADER
>> +  # It is compatible with SECURE_BOOT_ENABLE == FALSE as well.
>> +  # Signature: gEfiAuthenticatedVariableGuid =
>> +  #   { 0xaaf32c78, 0x947b, 0x439a,
>> +  #     { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }}
>> +  0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43,
>> +  0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92,
>> +  # Size: 0x30000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) -
>> +  #         0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x2FFB8
>> +  # This can speed up the Variable Dispatch a bit.
>> +  0xB8, 0xFF, 0x02, 0x00,
>> +  # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32
>> +  0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
>> +}
>> +
>> +0x00770000|0x00010000
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
>> +DATA = {
>> +  # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid =
>> +  #  { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95 }}
>> +  0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49,
>> +  0xa0, 0xce, 0x65,  0x0, 0xfd, 0x9f, 0x1b, 0x95,
>> +  # Crc:UINT32            #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved
>> +  0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF,
>> +  # WriteQueueSize: UINT64 Size: 0x10000 - 0x20 (FTW_WORKING_HEADER) = 0xFFE0
>> +  0xE0, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
>> +}
>> +
>> +0x00780000|0x00040000
>> +gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
>>   
>>   ################################################################################
>>   #
>> @@ -102,9 +155,11 @@ [FV.FVMAIN_COMPACT]
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/BootProgress/BootProgressPeim/BootProgressPeim.inf
>>     INF ArmPkg/Drivers/CpuPei/CpuPei.inf
>>     INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf
>> +  INF MdeModulePkg/Universal/FaultTolerantWritePei/FaultTolerantWritePei.inf
>>     INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
>>     INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf
>>     INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf
>> @@ -144,6 +199,7 @@ [FV.FvMain]
>>     INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf
>>     INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationDxe/MmCommunication.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>>   }
>>   
>>     INF MdeModulePkg/Core/Dxe/DxeMain.inf
>> @@ -173,6 +229,8 @@ [FV.FvMain]
>>     # Environment Variables Protocol
>>     #
>>     INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf
>> +  INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>>   
>>     #
>>     # Multiple Console IO support
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>> new file mode 100644
>> index 000000000000..782278615094
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.inf
>> @@ -0,0 +1,54 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = FlashFvbDxe
>> +  FILE_GUID                      = 9E6EA240-DF80-11EA-8B6E-0800200C9A66
>> +  MODULE_TYPE                    = DXE_RUNTIME_DRIVER
>> +  VERSION_STRING                 = 0.1
>> +  ENTRY_POINT                    = FlashFvbDxeInitialize
>> +
>> +[Sources]
>> +  FlashFvbDxe.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  DebugLib
>> +  FlashLib
>> +  PcdLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiRuntimeLib
>> +
>> +[FixedPcd]
>> +  gAmpereTokenSpaceGuid.PcdFvBlockSize
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
>> +
>> +[Pcd]
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
>> +
>> +[Guids]
>> +  gEfiEventVirtualAddressChangeGuid
>> +  gSpiNorMmGuid
>> +
>> +[Protocols]
>> +  gEfiFirmwareVolumeBlockProtocolGuid             ## PRODUCES
>> +  gEfiMmCommunicationProtocolGuid                 ## CONSUMES
>> +
>> +[Depex]
>> +  gEfiMmCommunicationProtocolGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>> new file mode 100644
>> index 000000000000..a4eaf5039bb0
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>> @@ -0,0 +1,51 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = FlashPei
>> +  FILE_GUID                      = 967CFBD0-DF81-11EA-8B6E-0800200C9A66
>> +  MODULE_TYPE                    = PEIM
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = FlashPeiEntryPoint
>> +
>> +[Sources]
>> +  FlashPei.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  ArmSmcLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  MmCommunicationLib
>> +  PcdLib
>> +  PeimEntryPoint
>> +
>> +[Guids]
>> +  gSpiNorMmGuid
>> +
>> +[FixedPcd]
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
>> +
>> +[Pcd]
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase64
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase64
>> +
>> +  gAmpereTokenSpaceGuid.PcdNvramErased
>> +
>> +[Depex]
>> +  TRUE
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>> new file mode 100644
>> index 000000000000..2d5003d1af17
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf
>> @@ -0,0 +1,36 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                   = 0x0001001B
>> +  BASE_NAME                     = FlashLib
>> +  FILE_GUID                     = 9E9D093D-6484-45AE-BA49-0745AA0BB481
>> +  MODULE_TYPE                   = DXE_DRIVER
>> +  VERSION_STRING                = 0.1
>> +  LIBRARY_CLASS                 = FlashLib
>> +  CONSTRUCTOR                   = FlashLibConstructor
>> +
>> +[Sources.common]
>> +  FlashLib.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseMemoryLib
>> +  DebugLib
>> +  MemoryAllocationLib
>> +
>> +[Guids]
>> +  gSpiNorMmGuid
>> +
>> +[Protocols]
>> +  gEfiMmCommunicationProtocolGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>> new file mode 100644
>> index 000000000000..9207dee643a5
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>> @@ -0,0 +1,42 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef FLASH_LIB_H_
>> +#define FLASH_LIB_H_
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashGetNvRamInfo (
>> +  OUT UINT64 *NvRamBase,
>> +  OUT UINT32 *NvRamSize
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashEraseCommand (
>> +  IN UINT8  *pBlockAddress,
>> +  IN UINT32 Length
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashProgramCommand (
>> +  IN     UINT8 *pByteAddress,
>> +  IN     UINT8 *Byte,
>> +  IN OUT UINTN *Length
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashReadCommand (
>> +  IN     UINT8 *pByteAddress,
>> +  OUT    UINT8 *Byte,
>> +  IN OUT UINTN *Length
>> +  );
>> +
>> +#endif /* FLASH_LIB_H_ */
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
>> new file mode 100644
>> index 000000000000..dcd92151b7d2
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashFvbDxe/FlashFvbDxe.c
>> @@ -0,0 +1,525 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/DebugLib.h>
>> +#include <Library/FlashLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeLib.h>
>> +#include <Protocol/FirmwareVolumeBlock.h>
>> +
>> +//
>> +// These temporary buffers are used to calculate and convert linear virtual
>> +// to physical address
>> +//
>> +STATIC UINT64 mNvFlashBase;
>> +STATIC UINT32 mNvFlashSize;
>> +STATIC UINT32 mFlashBlockSize;
>> +STATIC UINT64 mNvStorageBase;
>> +STATIC UINT64 mNvStorageSize;
>> +
>> +/**
>> +  Fixup internal data so that EFI can be call in virtual mode.
>> +  Call the passed in Child Notify event and convert any pointers in
>> +  lib to virtual mode.
>> +
>> +  @param[in]    Event   The Event that is being processed
>> +  @param[in]    Context Event Context
>> +**/
>> +VOID
>> +EFIAPI
>> +FlashFvbAddressChangeEvent (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  EfiConvertPointer (0x0, (VOID **)&mNvStorageBase);
>> +}
>> +
>> +/**
>> +  The GetAttributes() function retrieves the attributes and
>> +  current settings of the block.
>> +
>> +  @param This       Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the
>> +                    attributes and current settings are
>> +                    returned. Type EFI_FVB_ATTRIBUTES_2 is defined
>> +                    in EFI_FIRMWARE_VOLUME_HEADER.
>> +
>> +  @retval EFI_SUCCESS The firmware volume attributes were
>> +                      returned.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeGetAttributes (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  OUT      EFI_FVB_ATTRIBUTES_2                *Attributes
>> +  )
>> +{
>> +  ASSERT (Attributes != NULL);
>> +
>> +  *Attributes = EFI_FVB2_READ_ENABLED_CAP   | // Reads may be enabled
>> +                EFI_FVB2_READ_STATUS        | // Reads are currently enabled
>> +                EFI_FVB2_WRITE_STATUS       | // Writes are currently enabled
>> +                EFI_FVB2_WRITE_ENABLED_CAP  | // Writes may be enabled
>> +                EFI_FVB2_STICKY_WRITE       | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY
>> +                EFI_FVB2_MEMORY_MAPPED      | // It is memory mapped
>> +                EFI_FVB2_ALIGNMENT          |
>> +                EFI_FVB2_ERASE_POLARITY;      // After erasure all bits take this value (i.e. '1')
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  The SetAttributes() function sets configurable firmware volume
>> +  attributes and returns the new settings of the firmware volume.
>> +
>> +  @param This         Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Attributes   On input, Attributes is a pointer to
>> +                      EFI_FVB_ATTRIBUTES_2 that contains the
>> +                      desired firmware volume settings. On
>> +                      successful return, it contains the new
>> +                      settings of the firmware volume. Type
>> +                      EFI_FVB_ATTRIBUTES_2 is defined in
>> +                      EFI_FIRMWARE_VOLUME_HEADER.
>> +
>> +  @retval EFI_SUCCESS           The firmware volume attributes were returned.
>> +
>> +  @retval EFI_INVALID_PARAMETER The attributes requested are in
>> +                                conflict with the capabilities
>> +                                as declared in the firmware
>> +                                volume header.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeSetAttributes (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  IN OUT   EFI_FVB_ATTRIBUTES_2                *Attributes
>> +  )
>> +{
>> +  return EFI_SUCCESS;  // ignore for now
>> +}
>> +
>> +/**
>> +  The GetPhysicalAddress() function retrieves the base address of
>> +  a memory-mapped firmware volume. This function should be called
>> +  only for memory-mapped firmware volumes.
>> +
>> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Address  Pointer to a caller-allocated
>> +                  EFI_PHYSICAL_ADDRESS that, on successful
>> +                  return from GetPhysicalAddress(), contains the
>> +                  base address of the firmware volume.
>> +
>> +  @retval EFI_SUCCESS       The firmware volume base address was returned.
>> +
>> +  @retval EFI_UNSUPPORTED   The firmware volume is not memory mapped.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeGetPhysicalAddress (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  OUT      EFI_PHYSICAL_ADDRESS                *Address
>> +  )
>> +{
>> +  ASSERT (Address != NULL);
>> +
>> +  *Address = (EFI_PHYSICAL_ADDRESS)mNvStorageBase;
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  The GetBlockSize() function retrieves the size of the requested
>> +  block. It also returns the number of additional blocks with
>> +  the identical size. The GetBlockSize() function is used to
>> +  retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER).
>> +
>> +
>> +  @param This           Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Lba            Indicates the block for which to return the size.
>> +
>> +  @param BlockSize      Pointer to a caller-allocated UINTN in which
>> +                        the size of the block is returned.
>> +
>> +  @param NumberOfBlocks Pointer to a caller-allocated UINTN in
>> +                        which the number of consecutive blocks,
>> +                        starting with Lba, is returned. All
>> +                        blocks in this range have a size of
>> +                        BlockSize.
>> +
>> +
>> +  @retval EFI_SUCCESS             The firmware volume base address was returned.
>> +
>> +  @retval EFI_INVALID_PARAMETER   The requested LBA is out of range.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeGetBlockSize (
>> +  IN  CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  IN        EFI_LBA                             Lba,
>> +  OUT       UINTN                               *BlockSize,
>> +  OUT       UINTN                               *NumberOfBlocks
>> +  )
>> +{
>> +  UINTN TotalNvStorageBlocks;
>> +
>> +  ASSERT (BlockSize != NULL);
>> +  ASSERT (NumberOfBlocks != NULL);
>> +
>> +  TotalNvStorageBlocks = mNvStorageSize / mFlashBlockSize;
>> +
>> +  if (TotalNvStorageBlocks <= (UINTN)Lba) {
>> +    DEBUG ((DEBUG_ERROR, "The requested LBA is out of range\n"));
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  *NumberOfBlocks = TotalNvStorageBlocks - (UINTN)Lba;
>> +  *BlockSize = mFlashBlockSize;
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Reads the specified number of bytes into a buffer from the specified block.
>> +
>> +  The Read() function reads the requested number of bytes from the
>> +  requested block and stores them in the provided buffer.
>> +  Implementations should be mindful that the firmware volume
>> +  might be in the ReadDisabled state. If it is in this state,
>> +  the Read() function must return the status code
>> +  EFI_ACCESS_DENIED without modifying the contents of the
>> +  buffer. The Read() function must also prevent spanning block
>> +  boundaries. If a read is requested that would span a block
>> +  boundary, the read must read up to the boundary but not
>> +  beyond. The output parameter NumBytes must be set to correctly
>> +  indicate the number of bytes actually read. The caller must be
>> +  aware that a read may be partially completed.
>> +
>> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Lba      The starting logical block index
>> +                  from which to read.
>> +
>> +  @param Offset   Offset into the block at which to begin reading.
>> +
>> +  @param NumBytes Pointer to a UINTN. At entry, *NumBytes
>> +                  contains the total size of the buffer. At
>> +                  exit, *NumBytes contains the total number of
>> +                  bytes read.
>> +
>> +  @param Buffer   Pointer to a caller-allocated buffer that will
>> +                  be used to hold the data that is read.
>> +
>> +  @retval EFI_SUCCESS         The firmware volume was read successfully,
>> +                              and contents are in Buffer.
>> +
>> +  @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA
>> +                              boundary. On output, NumBytes
>> +                              contains the total number of bytes
>> +                              returned in Buffer.
>> +
>> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
>> +                              ReadDisabled state.
>> +
>> +  @retval EFI_DEVICE_ERROR    The block device is not
>> +                              functioning correctly and could
>> +                              not be read.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeRead (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  IN       EFI_LBA                             Lba,
>> +  IN       UINTN                               Offset,
>> +  IN OUT   UINTN                               *NumBytes,
>> +  IN OUT   UINT8                               *Buffer
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  ASSERT (NumBytes != NULL);
>> +  ASSERT (Buffer != NULL);
>> +
>> +  if (Offset + *NumBytes > mFlashBlockSize) {
>> +    return EFI_BAD_BUFFER_SIZE;
>> +  }
>> +
>> +  Status = FlashReadCommand (
>> +             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
>> +             Buffer,
>> +             NumBytes
>> +             );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Failed to do flash read\n"));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Writes the specified number of bytes from the input buffer to the block.
>> +
>> +  The Write() function writes the specified number of bytes from
>> +  the provided buffer to the specified block and offset. If the
>> +  firmware volume is sticky write, the caller must ensure that
>> +  all the bits of the specified range to write are in the
>> +  EFI_FVB_ERASE_POLARITY state before calling the Write()
>> +  function, or else the result will be unpredictable. This
>> +  unpredictability arises because, for a sticky-write firmware
>> +  volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY
>> +  state but cannot flip it back again.  Before calling the
>> +  Write() function,  it is recommended for the caller to first call
>> +  the EraseBlocks() function to erase the specified block to
>> +  write. A block erase cycle will transition bits from the
>> +  (NOT)EFI_FVB_ERASE_POLARITY state back to the
>> +  EFI_FVB_ERASE_POLARITY state. Implementations should be
>> +  mindful that the firmware volume might be in the WriteDisabled
>> +  state. If it is in this state, the Write() function must
>> +  return the status code EFI_ACCESS_DENIED without modifying the
>> +  contents of the firmware volume. The Write() function must
>> +  also prevent spanning block boundaries. If a write is
>> +  requested that spans a block boundary, the write must store up
>> +  to the boundary but not beyond. The output parameter NumBytes
>> +  must be set to correctly indicate the number of bytes actually
>> +  written. The caller must be aware that a write may be
>> +  partially completed. All writes, partial or otherwise, must be
>> +  fully flushed to the hardware before the Write() service
>> +  returns.
>> +
>> +  @param This     Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance.
>> +
>> +  @param Lba      The starting logical block index to write to.
>> +
>> +  @param Offset   Offset into the block at which to begin writing.
>> +
>> +  @param NumBytes The pointer to a UINTN. At entry, *NumBytes
>> +                  contains the total size of the buffer. At
>> +                  exit, *NumBytes contains the total number of
>> +                  bytes actually written.
>> +
>> +  @param Buffer   The pointer to a caller-allocated buffer that
>> +                  contains the source for the write.
>> +
>> +  @retval EFI_SUCCESS         The firmware volume was written successfully.
>> +
>> +  @retval EFI_BAD_BUFFER_SIZE The write was attempted across an
>> +                              LBA boundary. On output, NumBytes
>> +                              contains the total number of bytes
>> +                              actually written.
>> +
>> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
>> +                              WriteDisabled state.
>> +
>> +  @retval EFI_DEVICE_ERROR    The block device is malfunctioning
>> +                              and could not be written.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeWrite (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  IN       EFI_LBA                             Lba,
>> +  IN       UINTN                               Offset,
>> +  IN OUT   UINTN                               *NumBytes,
>> +  IN       UINT8                               *Buffer
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  ASSERT (NumBytes != NULL);
>> +  ASSERT (Buffer != NULL);
>> +
>> +  if (Offset + *NumBytes > mFlashBlockSize) {
>> +    return EFI_BAD_BUFFER_SIZE;
>> +  }
>> +
>> +  Status = FlashProgramCommand (
>> +             (UINT8 *)(mNvFlashBase + Lba * mFlashBlockSize + Offset),
>> +             Buffer,
>> +             NumBytes
>> +             );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Failed to do flash program\n"));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  Erases and initializes a firmware volume block.
>> +
>> +  The EraseBlocks() function erases one or more blocks as denoted
>> +  by the variable argument list. The entire parameter list of
>> +  blocks must be verified before erasing any blocks. If a block is
>> +  requested that does not exist within the associated firmware
>> +  volume (it has a larger index than the last block of the
>> +  firmware volume), the EraseBlocks() function must return the
>> +  status code EFI_INVALID_PARAMETER without modifying the contents
>> +  of the firmware volume. Implementations should be mindful that
>> +  the firmware volume might be in the WriteDisabled state. If it
>> +  is in this state, the EraseBlocks() function must return the
>> +  status code EFI_ACCESS_DENIED without modifying the contents of
>> +  the firmware volume. All calls to EraseBlocks() must be fully
>> +  flushed to the hardware before the EraseBlocks() service
>> +  returns.
>> +
>> +  @param This   Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
>> +                instance.
>> +
>> +  @param ...    The variable argument list is a list of tuples.
>> +                Each tuple describes a range of LBAs to erase
>> +                and consists of the following:
>> +                - An EFI_LBA that indicates the starting LBA
>> +                - A UINTN that indicates the number of blocks to
>> +                  erase.
>> +
>> +                The list is terminated with an
>> +                EFI_LBA_LIST_TERMINATOR. For example, the
>> +                following indicates that two ranges of blocks
>> +                (5-7 and 10-11) are to be erased: EraseBlocks
>> +                (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR);
>> +
>> +  @retval EFI_SUCCESS The erase request successfully
>> +                      completed.
>> +
>> +  @retval EFI_ACCESS_DENIED   The firmware volume is in the
>> +                              WriteDisabled state.
>> +  @retval EFI_DEVICE_ERROR  The block device is not functioning
>> +                            correctly and could not be written.
>> +                            The firmware device may have been
>> +                            partially erased.
>> +  @retval EFI_INVALID_PARAMETER One or more of the LBAs listed
>> +                                in the variable argument list do
>> +                                not exist in the firmware volume.
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeErase (
>> +  IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
>> +  ...
>> +  )
>> +{
>> +  VA_LIST    Args;
>> +  EFI_LBA    Start;
>> +  UINTN      Length;
>> +  EFI_STATUS Status;
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  VA_START (Args, This);
>> +
>> +  for (Start = VA_ARG (Args, EFI_LBA);
>> +       Start != EFI_LBA_LIST_TERMINATOR;
>> +       Start = VA_ARG (Args, EFI_LBA))
>> +  {
>> +    Length = VA_ARG (Args, UINTN);
>> +    Status = FlashEraseCommand (
>> +               (UINT8 *)(mNvFlashBase + Start * mFlashBlockSize),
>> +               Length * mFlashBlockSize
>> +               );
>> +  }
>> +
>> +  VA_END (Args);
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Failed to do flash erase\n"));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL mFlashFvbProtocol = {
>> +  FlashFvbDxeGetAttributes,
>> +  FlashFvbDxeSetAttributes,
>> +  FlashFvbDxeGetPhysicalAddress,
>> +  FlashFvbDxeGetBlockSize,
>> +  FlashFvbDxeRead,
>> +  FlashFvbDxeWrite,
>> +  FlashFvbDxeErase
>> +};
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashFvbDxeInitialize (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  EFI_HANDLE FvbHandle = NULL;
>> +  EFI_EVENT  VirtualAddressChangeEvent;
>> +
>> +  // Get NV store FV info
>> +  mFlashBlockSize = FixedPcdGet32 (PcdFvBlockSize);
>> +  mNvStorageBase = PcdGet64 (PcdFlashNvStorageVariableBase64);
>> +  mNvStorageSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
>> +                   FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
>> +                   FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
>> +
>> +  DEBUG ((
>> +    DEBUG_INFO,
>> +    "%a: Using NV store FV in-memory copy at 0x%lx with size 0x%x\n",
>> +    __FUNCTION__,
>> +    mNvStorageBase,
>> +    mNvStorageSize
>> +    ));
>> +
>> +  // Get NV Flash information
>> +  Status = FlashGetNvRamInfo ((UINT64 *)&mNvFlashBase, (UINT32 *)&mNvFlashSize);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "%a: Failed to get Flash info\n", __FUNCTION__));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  if (mNvFlashSize >= (mNvStorageSize * 2)) {
>> +    DEBUG ((DEBUG_INFO, "%a: NV store on Flash is valid\n", __FUNCTION__));
>> +  } else {
>> +    DEBUG ((DEBUG_ERROR, "%a: NV store on Flash is invalid\n", __FUNCTION__));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  Status = gBS->CreateEventEx (
>> +                  EVT_NOTIFY_SIGNAL,
>> +                  TPL_NOTIFY,
>> +                  FlashFvbAddressChangeEvent,
>> +                  NULL,
>> +                  &gEfiEventVirtualAddressChangeGuid,
>> +                  &VirtualAddressChangeEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  Status = gBS->InstallMultipleProtocolInterfaces (
>> +                  &FvbHandle,
>> +                  &gEfiFirmwareVolumeBlockProtocolGuid,
>> +                  &mFlashFvbProtocol,
>> +                  NULL
>> +                  );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Failed to install Firmware Volume Block protocol\n"));
>> +    return Status;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
>> new file mode 100644
>> index 000000000000..6bfbbbebaa85
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.c
>> @@ -0,0 +1,283 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiPei.h>
>> +#include <Uefi.h>
>> +
>> +#include <Library/ArmSmcLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MmCommunicationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PeimEntryPoint.h>
>> +#include <MmLib.h>
>> +
>> +// Convert to string
>> +#define _STR(x)          #x
>> +
>> +// Make sure the argument is expanded before converting to string
>> +#define STR(x)          _STR(x)
>> +
>> +// Use dynamic UEFI_UUID of each build time
>> +#define UEFI_UUID_BUILD      STR(UEFI_UUID)
>> +
>> +EFI_MM_COMM_REQUEST mEfiMmSpiNorReq;
>> +
>> +STATIC CHAR8 mBuildUuid[sizeof (UEFI_UUID_BUILD)];
>> +STATIC CHAR8 mStoredUuid[sizeof (UEFI_UUID_BUILD)];
>> +
>> +STATIC
>> +EFI_STATUS
>> +UefiMmCreateSpiNorReq (
>> +  VOID   *Data,
>> +  UINT64 Size
>> +  )
>> +{
>> +  CopyGuid (&mEfiMmSpiNorReq.EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
>> +  mEfiMmSpiNorReq.EfiMmHdr.MsgLength = Size;
>> +
>> +  if (Size != 0) {
>> +    ASSERT (Data);
>> +    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
>> +
>> +    CopyMem (mEfiMmSpiNorReq.PayLoad.Data, Data, Size);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Entry point function for the PEIM
>> +
>> +  @param FileHandle      Handle of the file being invoked.
>> +  @param PeiServices     Describes the list of possible PEI Services.
>> +
>> +  @return EFI_SUCCESS    If we installed our PPI
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +FlashPeiEntryPoint (
>> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
>> +  IN CONST EFI_PEI_SERVICES    **PeiServices
>> +  )
>> +{
>> +  UINT64                               FWNvRamStartOffset;
>> +  EFI_STATUS                           Status;
>> +  EFI_MM_COMMUNICATE_SPINOR_RES        *MmSpiNorRes;
>> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
>> +  UINT64                               MmData[5];
>> +  UINTN                                Size;
>> +  VOID                                 *NvRamAddress;
>> +  UINTN                                NvRamSize;
>> +
>> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
>> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNV2InfoRes;
>> +  UINT64                               NV2Base, NV2Size;
>> +#endif
>> +
>> +  NvRamAddress = (VOID *)PcdGet64 (PcdFlashNvStorageVariableBase64);
>> +  NvRamSize = FixedPcdGet32 (PcdFlashNvStorageVariableSize) +
>> +              FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) +
>> +              FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize);
>> +
>> +  /* Find out about the start offset of NVRAM to be passed to SMC */
>> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
>> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +  Status = MmCommunicationCommunicate (
>> +             (VOID *)&mEfiMmSpiNorReq,
>> +             &Size
>> +             );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +  if (MmSpiNorNVInfoRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +    /* Old FW so just exit */
>> +    return EFI_SUCCESS;
>> +  }
>> +  FWNvRamStartOffset = MmSpiNorNVInfoRes->NVBase;
>> +
>> +  CopyMem ((VOID *)mBuildUuid, (VOID *)UEFI_UUID_BUILD, sizeof (UEFI_UUID_BUILD));
>> +  if (MmSpiNorNVInfoRes->NVSize < (NvRamSize * 2 + sizeof (mBuildUuid))) {
>> +    /* NVRAM size provided by FW is not enough */
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  /* We stored BIOS UUID build at the offset NVRAM_SIZE * 2 */
>> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +  MmData[0] = MM_SPINOR_FUNC_READ;
>> +  MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
>> +  MmData[2] = (UINT64)sizeof (mStoredUuid);
>> +  MmData[3] = (UINT64)mStoredUuid;
>> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +  Status = MmCommunicationCommunicate (
>> +             (VOID *)&mEfiMmSpiNorReq,
>> +             &Size
>> +             );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +    return Status;
>> +  }
>> +
>> +  if (CompareMem ((VOID *)mStoredUuid, (VOID *)mBuildUuid, sizeof (mBuildUuid))) {
>> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +    MmData[0] = MM_SPINOR_FUNC_ERASE;
>> +    MmData[1] = (UINT64)FWNvRamStartOffset;
>> +    MmData[2] = (UINT64)(NvRamSize * 2);
>> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = MmCommunicationCommunicate (
>> +               (VOID *)&mEfiMmSpiNorReq,
>> +               &Size
>> +               );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      return Status;
>> +    }
>> +
>> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
>> +    MmData[1] = (UINT64)FWNvRamStartOffset;
>> +    MmData[2] = (UINT64)(NvRamSize * 2);
>> +    MmData[3] = (UINT64)NvRamAddress;
>> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = MmCommunicationCommunicate (
>> +               (VOID *)&mEfiMmSpiNorReq,
>> +               &Size
>> +               );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      return Status;
>> +    }
>> +
>> +    /* Update UUID */
>> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +    MmData[0] = MM_SPINOR_FUNC_ERASE;
>> +    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
>> +    MmData[2] = (UINT64)sizeof (mBuildUuid);
>> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = MmCommunicationCommunicate (
>> +               (VOID *)&mEfiMmSpiNorReq,
>> +               &Size
>> +               );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      return Status;
>> +    }
>> +
>> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
>> +    MmData[1] = (UINT64)(FWNvRamStartOffset + NvRamSize * 2);
>> +    MmData[2] = (UINT64)sizeof (mBuildUuid);
>> +    MmData[3] = (UINT64)mBuildUuid;
>> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = MmCommunicationCommunicate (
>> +               (VOID *)&mEfiMmSpiNorReq,
>> +               &Size
>> +               );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      return Status;
>> +    }
>> +    DEBUG ((DEBUG_INFO, "UUID Changed, Update Storage with FV NVRAM\n"));
>> +
>> +    /* Indicate that NVRAM was cleared */
>> +    PcdSetBoolS (PcdNvramErased, TRUE);
>> +  } else {
>> +    /* Copy the stored NVRAM to RAM */
>> +    ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +    MmData[0] = MM_SPINOR_FUNC_READ;
>> +    MmData[1] = (UINT64)FWNvRamStartOffset;
>> +    MmData[2] = (UINT64)(NvRamSize * 2);
>> +    MmData[3] = (UINT64)NvRamAddress;
>> +    UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = MmCommunicationCommunicate (
>> +               (VOID *)&mEfiMmSpiNorReq,
>> +               &Size
>> +               );
>> +    ASSERT_EFI_ERROR (Status);
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      return Status;
>> +    }
>> +    DEBUG ((DEBUG_INFO, "Identical UUID, copy stored NVRAM to RAM\n"));
>> +  }
>> +
>> +#if defined(RAM_BLOCKIO_START_ADDRESS) && defined(RAM_BLOCKIO_SIZE)
>> +  /* Find out about the start offset of NVRAM2 to be passed to SMC */
>> +  ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM2_INFO;
>> +  UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +  Status = MmCommunicationCommunicate (
>> +             (VOID *)&mEfiMmSpiNorReq,
>> +             &Size
>> +             );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  MmSpiNorNV2InfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +  if (MmSpiNorNV2InfoRes->Status == MM_SPINOR_RES_SUCCESS) {
>> +    NV2Base = MmSpiNorNV2InfoRes->NVBase;
>> +    NV2Size = MmSpiNorNV2InfoRes->NVSize;
>> +    /* Make sure the requested size is smaller than allocated */
>> +    if (RAM_BLOCKIO_SIZE <= NV2Size) {
>> +      /* Copy the ramdisk image to RAM */
>> +      ZeroMem ((VOID *)MmData, sizeof (MmData));
>> +      MmData[0] = MM_SPINOR_FUNC_READ;
>> +      MmData[1] = (UINT64)NV2Base; /* Start virtual address */
>> +      MmData[2] = (UINT64)RAM_BLOCKIO_SIZE;
>> +      MmData[3] = (UINT64)RAM_BLOCKIO_START_ADDRESS;
>> +      UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +
>> +      Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +      Status = MmCommunicationCommunicate (
>> +                 (VOID *)&mEfiMmSpiNorReq,
>> +                 &Size
>> +                 );
>> +      ASSERT_EFI_ERROR (Status);
>> +
>> +      MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mEfiMmSpiNorReq.PayLoad;
>> +      ASSERT (MmSpiNorRes->Status == MM_SPINOR_RES_SUCCESS);
>> +    }
>> +
>> +    BuildMemoryAllocationHob (
>> +      (EFI_PHYSICAL_ADDRESS)RAM_BLOCKIO_START_ADDRESS,
>> +      EFI_SIZE_TO_PAGES (RAM_BLOCKIO_SIZE) * EFI_PAGE_SIZE,
>> +      EfiLoaderData
>> +      );
>> +  }
>> +#endif
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
>> new file mode 100644
>> index 000000000000..cd77aed3cfe1
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c
>> @@ -0,0 +1,358 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/FlashLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <MmLib.h>
>> +#include <Protocol/MmCommunication.h>
>> +
>> +STATIC EFI_MM_COMMUNICATION_PROTOCOL *mMmCommunicationProtocol = NULL;
>> +STATIC EFI_MM_COMM_REQUEST           *mCommBuffer              = NULL;
>> +
>> +BOOLEAN mIsEfiRuntime;
>> +UINT8   *mTmpBufVirt;
>> +UINT8   *mTmpBufPhy;
>> +
>> +/**
>> +  This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
>> +  event. It converts a pointer to a new virtual address.
>> +
>> +  @param  Event        Event whose notification function is being invoked.
>> +  @param  Context      Pointer to the notification function's context
>> +
>> +**/
>> +VOID
>> +EFIAPI
>> +FlashLibAddressChangeEvent (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  gRT->ConvertPointer (0x0, (VOID **)&mTmpBufVirt);
>> +  gRT->ConvertPointer (0x0, (VOID **)&mCommBuffer);
>> +  gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol);
>> +
>> +  mIsEfiRuntime = TRUE;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashLibConstructor (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_EVENT  VirtualAddressChangeEvent = NULL;
>> +  EFI_STATUS Status = EFI_SUCCESS;
>> +
>> +  mCommBuffer = AllocateRuntimeZeroPool (sizeof (EFI_MM_COMM_REQUEST));
>> +  ASSERT (mCommBuffer != NULL);
>> +
>> +  mTmpBufPhy = AllocateRuntimeZeroPool (EFI_MM_MAX_TMP_BUF_SIZE);
>> +  mTmpBufVirt = mTmpBufPhy;
>> +  ASSERT (mTmpBufPhy != NULL);
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiMmCommunicationProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&mMmCommunicationProtocol
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  Status = gBS->CreateEvent (
>> +                  EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
>> +                  TPL_CALLBACK,
>> +                  FlashLibAddressChangeEvent,
>> +                  NULL,
>> +                  &VirtualAddressChangeEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +FlashMmCommunicate (
>> +  IN OUT VOID  *CommBuffer,
>> +  IN OUT UINTN *CommSize
>> +  )
>> +{
>> +  if (mMmCommunicationProtocol == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  return mMmCommunicationProtocol->Communicate (
>> +                                     mMmCommunicationProtocol,
>> +                                     CommBuffer,
>> +                                     CommSize
>> +                                     );
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +UefiMmCreateSpiNorReq (
>> +  IN VOID   *Data,
>> +  IN UINT64 Size
>> +  )
>> +{
>> +  if (mCommBuffer == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  CopyGuid (&mCommBuffer->EfiMmHdr.HeaderGuid, &gSpiNorMmGuid);
>> +  mCommBuffer->EfiMmHdr.MsgLength = Size;
>> +
>> +  if (Size != 0) {
>> +    ASSERT (Data);
>> +    ASSERT (Size <= EFI_MM_MAX_PAYLOAD_SIZE);
>> +
>> +    CopyMem (mCommBuffer->PayLoad.Data, Data, Size);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Convert Virtual Address to Physical Address at Runtime Services
>> +
>> +  @param  VirtualPtr          Virtual Address Pointer
>> +  @param  Size                Total bytes of the buffer
>> +
>> +  @retval Ptr                 Return the pointer of the converted address
>> +
>> +**/
>> +STATIC
>> +UINT8 *
>> +ConvertVirtualToPhysical (
>> +  IN UINT8 *VirtualPtr,
>> +  IN UINTN Size
>> +  )
>> +{
>> +  if (mIsEfiRuntime) {
>> +    ASSERT (VirtualPtr != NULL);
>> +    CopyMem ((VOID *)mTmpBufVirt, (VOID *)VirtualPtr, Size);
>> +    return (UINT8 *)mTmpBufPhy;
>> +  }
>> +
>> +  return (UINT8 *)VirtualPtr;
>> +}
>> +
>> +/**
>> +  Convert Physical Address to Virtual Address at Runtime Services
>> +
>> +  @param  VirtualPtr          Physical Address Pointer
>> +  @param  Size                Total bytes of the buffer
>> +
>> +**/
>> +STATIC
>> +VOID
>> +ConvertPhysicaltoVirtual (
>> +  IN UINT8 *PhysicalPtr,
>> +  IN UINTN Size
>> +  )
>> +{
>> +  if (mIsEfiRuntime) {
>> +    ASSERT (PhysicalPtr != NULL);
>> +    CopyMem ((VOID *)PhysicalPtr, (VOID *)mTmpBufVirt, Size);
>> +  }
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashGetNvRamInfo (
>> +  OUT UINT64 *NvRamBase,
>> +  OUT UINT32 *NvRamSize
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *MmSpiNorNVInfoRes;
>> +  EFI_STATUS                           Status;
>> +  UINT64                               MmData[5];
>> +  UINTN                                Size;
>> +
>> +  MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO;
>> +
>> +  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +  Status = FlashMmCommunicate (
>> +             mCommBuffer,
>> +             &Size
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  MmSpiNorNVInfoRes = (EFI_MM_COMMUNICATE_SPINOR_NVINFO_RES *)&mCommBuffer->PayLoad;
>> +  if (MmSpiNorNVInfoRes->Status == MM_SPINOR_RES_SUCCESS) {
>> +    *NvRamBase = MmSpiNorNVInfoRes->NVBase;
>> +    *NvRamSize = MmSpiNorNVInfoRes->NVSize;
>> +    DEBUG ((DEBUG_INFO, "NVInfo Base 0x%llx, Size 0x%lx\n", *NvRamBase, *NvRamSize));
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashEraseCommand (
>> +  IN UINT8  *pBlockAddress,
>> +  IN UINT32 Length
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
>> +  EFI_STATUS                    Status;
>> +  UINT64                        MmData[5];
>> +  UINTN                         Size;
>> +
>> +  ASSERT (pBlockAddress != NULL);
>> +
>> +  MmData[0] = MM_SPINOR_FUNC_ERASE;
>> +  MmData[1] = (UINT64)pBlockAddress;
>> +  MmData[2] = Length;
>> +
>> +  Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +  Status = FlashMmCommunicate (
>> +             mCommBuffer,
>> +             &Size
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
>> +  if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +    DEBUG ((DEBUG_ERROR, "Flash Erase: Device error %llx\n", MmSpiNorRes->Status));
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashProgramCommand (
>> +  IN     UINT8 *pByteAddress,
>> +  IN     UINT8 *Byte,
>> +  IN OUT UINTN *Length
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
>> +  EFI_STATUS                    Status;
>> +  UINT64                        MmData[5];
>> +  UINTN                         Remain, Size, NumWrite;
>> +  UINTN                         Count = 0;
>> +
>> +  ASSERT (pByteAddress != NULL);
>> +  ASSERT (Byte != NULL);
>> +  ASSERT (Length != NULL);
>> +
>> +  Remain = *Length;
>> +  while (Remain > 0) {
>> +    NumWrite = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
>> +
>> +    MmData[0] = MM_SPINOR_FUNC_WRITE;
>> +    MmData[1] = (UINT64)pByteAddress;
>> +    MmData[2] = NumWrite;
>> +    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumWrite);
>> +
>> +    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = FlashMmCommunicate (
>> +               mCommBuffer,
>> +               &Size
>> +               );
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      DEBUG ((DEBUG_ERROR, "Flash program: Device error 0x%llx\n", MmSpiNorRes->Status));
>> +      return EFI_DEVICE_ERROR;
>> +    }
>> +
>> +    Remain -= NumWrite;
>> +    Count += NumWrite;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +FlashReadCommand (
>> +  IN     UINT8 *pByteAddress,
>> +  OUT    UINT8 *Byte,
>> +  IN OUT UINTN *Length
>> +  )
>> +{
>> +  EFI_MM_COMMUNICATE_SPINOR_RES *MmSpiNorRes;
>> +  EFI_STATUS                    Status;
>> +  UINT64                        MmData[5];
>> +  UINTN                         Remain, Size, NumRead;
>> +  UINTN                         Count = 0;
>> +
>> +  ASSERT (pByteAddress != NULL);
>> +  ASSERT (Byte != NULL);
>> +  ASSERT (Length != NULL);
>> +
>> +  Remain = *Length;
>> +  while (Remain > 0) {
>> +    NumRead = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : Remain;
>> +
>> +    MmData[0] = MM_SPINOR_FUNC_READ;
>> +    MmData[1] = (UINT64)pByteAddress;
>> +    MmData[2] = NumRead;
>> +    MmData[3] = (UINT64)ConvertVirtualToPhysical (Byte + Count, NumRead);
>> +
>> +    Status = UefiMmCreateSpiNorReq ((VOID *)&MmData, sizeof (MmData));
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +
>> +    Size = sizeof (EFI_MM_COMM_HEADER_NOPAYLOAD) + sizeof (MmData);
>> +    Status = FlashMmCommunicate (
>> +               mCommBuffer,
>> +               &Size
>> +               );
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +
>> +    MmSpiNorRes = (EFI_MM_COMMUNICATE_SPINOR_RES *)&mCommBuffer->PayLoad;
>> +    if (MmSpiNorRes->Status != MM_SPINOR_RES_SUCCESS) {
>> +      DEBUG ((DEBUG_ERROR, "Flash Read: Device error %llx\n", MmSpiNorRes->Status));
>> +      return EFI_DEVICE_ERROR;
>> +    }
>> +
>> +    ConvertPhysicaltoVirtual (Byte + Count, NumRead);
>> +    Remain -= NumRead;
>> +    Count += NumRead;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support
  2021-06-04 23:50   ` Leif Lindholm
@ 2021-06-15 16:49     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:49 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Thang Nguyen, Chuong Tran, Phong Vo, Michael D Kinney,
	Ard Biesheuvel, Nate DeSimone

On 6/5/21 06:50, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:05 +0700, Nhi Pham wrote:
>> Add various ACPI tables for the Mt. Jade platform including: DSDT, SPCR,
>> DBG2, GTDT, FACP, SSDT, MADT, PPTT, PCCT, SLIT, SRAT, and NFIT.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> Contents of ACPI tables not reviewed.
> Creation modes on many of these files are incorrect (as commented on
> cover letter).

Thanks for catching that. Will correct them in the v3.

Best regards,

Nhi

> Address this, and you can have:
> Acked-by: Leif Lindholm <leif@nuviainc.com>
>
> /
>      Leif
>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |    8 +
>>   Platform/Ampere/JadePkg/Jade.dsc                                    |   23 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                    |    8 +
>>   Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf                   |   20 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf |   75 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf |   44 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h          |  121 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h          |   49 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h      |   76 +
>>   Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h                  |   37 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c          |  457 ++
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c          |  445 ++
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c          |  351 ++
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c          |  599 +++
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c          |  196 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c   |  178 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c          |  378 ++
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c          |  190 +
>>   Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c          |  274 +
>>   Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi                       | 5639 ++++++++++++++++++++
>>   Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi                       | 5639 ++++++++++++++++++++
>>   Platform/Ampere/JadePkg/AcpiTables/CPU.asi                          |  127 +
>>   Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl                         |  575 ++
>>   Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi                     |  217 +
>>   Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi                 |  681 +++
>>   Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi                       | 2078 ++++++++
>>   Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi                       | 2087 ++++++++
>>   Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi                       | 1303 +++++
>>   Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi                       | 1303 +++++
>>   Platform/Ampere/JadePkg/AcpiTables/PMU.asi                          |   10 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc            |   33 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc            |   87 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl             |  165 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc            |   87 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc            |  180 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl             |  330 ++
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl             |   17 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc            |   81 +
>>   Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl             |   15 +
>>   39 files changed, 24183 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 3c47099b8edc..11f50f2f09cd 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -466,6 +466,14 @@ [PcdsFixedAtBuild.common]
>>     #
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
>>   
>> +  #
>> +  # ACPI table
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId|"Ampere"
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId|0x2020206172746C41 # Altra
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId|0x2E504D41 # AMP.
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision|0x01000013
>> +
>>     #
>>     # Enable strict image permissions for all images. (This applies
>>     # only to images that were built with >= 4 KB section alignment.)
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index 9b9a5d0bad0f..0f9d0adbd34e 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -81,12 +81,24 @@ [LibraryClasses]
>>     #
>>     FailSafeLib|Platform/Ampere/AmperePlatformPkg/Library/FailSafeLib/FailSafeLib.inf
>>   
>> +  #
>> +  # ACPI Libraries
>> +  #
>> +  AcpiLib|EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
>> +  AcpiHelperLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf
>> +  AcpiPccLib|Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf
>> +
>>   ################################################################################
>>   #
>>   # Specific Platform Pcds
>>   #
>>   ################################################################################
>>   [PcdsFeatureFlag.common]
>> +  #
>> +  # Activate AcpiSdtProtocol
>> +  #
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
>> +
>>   [PcdsFixedAtBuild.common]
>>   
>>   !if $(SECURE_BOOT_ENABLE) == TRUE
>> @@ -108,3 +120,14 @@ [Components.common]
>>     # FailSafe and Watchdog Timer
>>     #
>>     Platform/Ampere/AmperePlatformPkg/Drivers/FailSafeDxe/FailSafeDxe.inf
>> +
>> +  #
>> +  # ACPI
>> +  #
>> +  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf {
>> +    <PcdsFixedAtBuild>
>> +      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2B
>> +  }
>> +  Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> +  Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> +  Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 375455086d0b..2c6f9fac76fd 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -289,4 +289,12 @@ [FV.FvMain]
>>     #
>>   !include NetworkPkg/Network.fdf.inc
>>   
>> +  #
>> +  # ACPI
>> +  #
>> +  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> +  INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> +  INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> +
>>   !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> new file mode 100644
>> index 000000000000..1cf632f8a406
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>> @@ -0,0 +1,20 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = JadeAcpiTables
>> +  FILE_GUID                      = 5ADDBC13-8634-480C-9B94-671B7855CDB8
>> +  MODULE_TYPE                    = USER_DEFINED
>> +  VERSION_STRING                 = 1.0
>> +
>> +[Sources]
>> +  Dsdt.asl
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> new file mode 100644
>> index 000000000000..a1a323eee472
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.inf
>> @@ -0,0 +1,75 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = AcpiPlatformDxe
>> +  FILE_GUID                      = CDA4ED56-6960-4092-885D-FEF37D29093E
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = AcpiPlatformDxeInitialize
>> +
>> +[Sources.common]
>> +  AcpiApei.c
>> +  AcpiApei.h
>> +  AcpiDsdt.c
>> +  AcpiMadt.c
>> +  AcpiNfit.c
>> +  AcpiPcct.c
>> +  AcpiPptt.c
>> +  AcpiPlatform.h
>> +  AcpiPlatformDxe.c
>> +  AcpiSlit.c
>> +  AcpiSrat.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  AcpiHelperLib
>> +  AcpiLib
>> +  AcpiPccLib
>> +  AmpereCpuLib
>> +  BaseLib
>> +  DebugLib
>> +  FlashLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +  UefiRuntimeServicesTableLib
>> +
>> +[Pcd]
>> +  gArmPlatformTokenSpaceGuid.PcdCoreCount
>> +  gArmPlatformTokenSpaceGuid.PcdClusterCount
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemId
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemTableId
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorId
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision
>> +  gAmpereTokenSpaceGuid.PcdPmproDbBaseReg
>> +  gAmpereTokenSpaceGuid.PcdSmproDbBaseReg
>> +
>> +[Guids]
>> +  gArmMpCoreInfoGuid
>> +  gEfiAcpiTableGuid
>> +  gEfiEventReadyToBootGuid
>> +  gPlatformHobGuid
>> +
>> +[Protocols]
>> +  gEfiAcpiTableProtocolGuid                     ## ALWAYS_CONSUMED
>> +  gEfiAcpiSdtProtocolGuid
>> +  gEfiPciRootBridgeIoProtocolGuid
>> +
>> +[Depex]
>> +  gEfiAcpiTableProtocolGuid
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> new file mode 100644
>> index 000000000000..acc4092c650d
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>> @@ -0,0 +1,44 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = AcpiCommonTables
>> +  FILE_GUID                      = CEFA2AEB-357E-4F48-8066-EA950853056E
>> +  MODULE_TYPE                    = USER_DEFINED
>> +  VERSION_STRING                 = 1.0
>> +
>> +[Sources]
>> +  Bert.aslc
>> +  Dbg2.aslc
>> +  Einj.asl
>> +  Fadt.aslc
>> +  Gtdt.aslc
>> +  Hest.asl
>> +  Sdei.asl
>> +  Spcr.aslc
>> +  Ssdt.asl
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +
>> +[FixedPcd]
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase            ## CONSUMES
>> +  gArmPlatformTokenSpaceGuid.PL011UartInterrupt                   ## CONSUMES
>> +  gArmPlatformTokenSpaceGuid.PcdWatchdogCount                     ## CONSUMES
>> +
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultOemRevision        ## CONSUMES
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdAcpiDefaultCreatorRevision    ## CONSUMES
>> +
>> +  gArmPlatformTokenSpaceGuid.PcdSerialDbgRegisterBase             ## CONSUMES
>> +  gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate                 ## CONSUMES
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
>> new file mode 100644
>> index 000000000000..c207142459ad
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.h
>> @@ -0,0 +1,121 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef ACPI_APEI_H_
>> +#define ACPI_APEI_H_
>> +
>> +#include <Base.h>
>> +#include <IndustryStandard/Acpi63.h>
>> +#include <Library/AcpiHelperLib.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Platform/Ac01.h>
>> +#include <Protocol/AcpiTable.h>
>> +
>> +#pragma pack(1)
>> +#define BERT_MSG_SIZE                0x2C
>> +#define BERT_ERROR_TYPE              0x7F
>> +#define BERT_UEFI_FAILURE            5
>> +#define RAS_2P_TYPE                  0x03
>> +#define BERT_DEFAULT_ERROR_SEVERITY  0x1
>> +#define GENERIC_ERROR_DATA_REVISION  0x300
>> +
>> +
>> +#define PLAT_CRASH_ITERATOR_SIZE     0x398
>> +#define SMPRO_CRASH_SIZE             0x800
>> +#define PMPRO_CRASH_SIZE             0x800
>> +#define HEST_NUM_ENTRIES_PER_SOC     3
>> +
>> +#define CURRENT_BERT_VERSION         0x10
>> +#define BERT_FLASH_OFFSET            0x91B30000ULL
>> +#define BERT_DDR_OFFSET              0x88230000ULL
>> +#define BERT_DDR_LENGTH              0x50000
>> +
>> +typedef struct {
>> +  UINT8  Type;
>> +  UINT8  SubType;
>> +  UINT16 Instance;
>> +  CHAR8  Msg[BERT_MSG_SIZE];
>> +} APEI_BERT_ERROR_DATA;
>> +
>> +typedef struct {
>> +  APEI_BERT_ERROR_DATA Vendor;
>> +  UINT8                BertRev;
>> +  UINT8                S0PmproRegisters[PMPRO_CRASH_SIZE];
>> +  UINT8                S0SmproRegisters[SMPRO_CRASH_SIZE];
>> +  UINT8                S1PmproRegisters[PMPRO_CRASH_SIZE];
>> +  UINT8                S1SmproRegisters[SMPRO_CRASH_SIZE];
>> +  UINT8                AtfDump[PLATFORM_CPU_MAX_NUM_CORES * PLAT_CRASH_ITERATOR_SIZE];
>> +} APEI_CRASH_DUMP_DATA;
>> +
>> +typedef struct {
>> +  EFI_ACPI_6_3_GENERIC_ERROR_STATUS_STRUCTURE     Ges;
>> +  EFI_ACPI_6_3_GENERIC_ERROR_DATA_ENTRY_STRUCTURE Ged;
>> +  APEI_CRASH_DUMP_DATA                            Bed;
>> +} APEI_CRASH_DUMP_BERT_ERROR;
>> +#pragma pack()
>> +
>> +VOID
>> +EFIAPI
>> +CreateDefaultBertData (
>> +  APEI_BERT_ERROR_DATA *Data
>> +  );
>> +
>> +VOID
>> +EFIAPI
>> +WrapBertErrorData (
>> +  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
>> +  );
>> +
>> +VOID
>> +EFIAPI
>> +PullBertSpinorData (
>> +  APEI_CRASH_DUMP_DATA *BertErrorData
>> +  );
>> +
>> +VOID
>> +EFIAPI
>> +AdjustBERTRegionLen (
>> +  UINT32 Len
>> +  );
>> +
>> +BOOLEAN
>> +EFIAPI
>> +IsBertEnabled (
>> +  VOID
>> +  );
>> +
>> +VOID
>> +EFIAPI
>> +WriteDDRBertTable (
>> +  APEI_CRASH_DUMP_BERT_ERROR *Data
>> +  );
>> +
>> +VOID
>> +WriteSpinorDefaultBertTable (
>> +  APEI_CRASH_DUMP_DATA *SpiRefrenceData
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +AcpiApeiUpdate (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +AcpiPopulateBert (
>> +  VOID
>> +  );
>> +
>> +#endif /* ACPI_APEI_H_ */
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
>> new file mode 100644
>> index 000000000000..920579281dd5
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.h
>> @@ -0,0 +1,49 @@
>> +/** @file
>> +
>> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef ACPI_NFIT_H_
>> +#define ACPI_NFIT_H_
>> +
>> +#include <Platform/Ac01.h>
>> +
>> +#define NVDIMM_SK0          0
>> +#define NVDIMM_SK1          1
>> +#define NVDIMM_NUM_PER_SK   (PLATFORM_NVDIMM_MCU_MAX_PER_SK * PLATFORM_NVDIMM_NUM_MAX_PER_MCU)
>> +#define ONE_GB              (1024 * 1024 * 1024)
>> +
>> +enum NvdimmMode {
>> +  NVDIMM_DISABLED   = 0,
>> +  NVDIMM_NON_HASHED = 1,
>> +  NVDIMM_HASHED     = 2
>> +};
>> +
>> +typedef struct {
>> +  BOOLEAN Enabled;
>> +  UINT64  NvdSize;
>> +  UINT32  DeviceHandle;
>> +  UINT16  PhysId;
>> +  UINT8   InterleaveWays;
>> +  UINT64  RegionOffset;
>> +  UINT16  VendorId;
>> +  UINT16  DeviceId;
>> +  UINT16  RevisionId;
>> +  UINT16  SubVendorId;
>> +  UINT16  SubDeviceId;
>> +  UINT16  SubRevisionId;
>> +  UINT32  SerialNumber;
>> +} NVDIMM_INFO;
>> +
>> +typedef struct {
>> +  UINT8       NvdRegionNum;
>> +  UINT8       NvdRegionId[PLATFORM_NVDIMM_REGION_MAX_PER_SK];
>> +  UINT8       NvdMode;
>> +  UINT8       NvdNum;
>> +  NVDIMM_INFO NvdInfo[NVDIMM_NUM_PER_SK];
>> +} NVDIMM_DATA;
>> +
>> +#endif
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
>> new file mode 100644
>> index 000000000000..ce4d9b8440b8
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatform.h
>> @@ -0,0 +1,76 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef ACPI_PLATFORM_H_
>> +#define ACPI_PLATFORM_H_
>> +
>> +#include <Uefi.h>
>> +
>> +#include <AcpiHeader.h>
>> +#include <Guid/EventGroup.h>
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <IndustryStandard/Acpi63.h>
>> +#include <Library/ArmLib/ArmLibPrivate.h>
>> +#include <Library/AcpiHelperLib.h>
>> +#include <Library/AcpiLib.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DevicePathLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/PrintLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Platform/Ac01.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Protocol/AcpiTable.h>
>> +
>> +EFI_STATUS
>> +AcpiPatchDsdtTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallMadtTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallNfitTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiPcctInit (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallPcctTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallPpttTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallSlitTable (
>> +  VOID
>> +  );
>> +
>> +EFI_STATUS
>> +AcpiInstallSratTable (
>> +  VOID
>> +  );
>> +
>> +#endif /* ACPI_PLATFORM_H_ */
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
>> new file mode 100644
>> index 000000000000..d604b712d8c8
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/AcpiHeader.h
>> @@ -0,0 +1,37 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef ACPI_HEADER_H_
>> +#define ACPI_HEADER_H_
>> +
>> +#include <IndustryStandard/Acpi.h>
>> +
>> +//
>> +// ACPI table information used to initialize tables.
>> +//
>> +#define EFI_ACPI_OEM_ID           {'A','m','p','e','r','e'}
>> +#define EFI_ACPI_OEM_TABLE_ID     SIGNATURE_64('A','l','t','r','a',' ',' ',' ')
>> +#define EFI_ACPI_OEM_REVISION     FixedPcdGet32 (PcdAcpiDefaultOemRevision)
>> +#define EFI_ACPI_CREATOR_ID       SIGNATURE_32('A','M','P','.')
>> +#define EFI_ACPI_CREATOR_REVISION FixedPcdGet32 (PcdAcpiDefaultCreatorRevision)
>> +
>> +// A macro to initialise the common header part of EFI ACPI tables as defined by
>> +// EFI_ACPI_DESCRIPTION_HEADER structure.
>> +#define __ACPI_HEADER(Signature, Type, Revision) {                \
>> +    Signature,                /* UINT32  Signature */       \
>> +    sizeof (Type),            /* UINT32  Length */          \
>> +    Revision,                 /* UINT8   Revision */        \
>> +    0,                        /* UINT8   Checksum */        \
>> +    EFI_ACPI_OEM_ID,          /* UINT8   OemId[6] */        \
>> +    EFI_ACPI_OEM_TABLE_ID,    /* UINT64  OemTableId */      \
>> +    EFI_ACPI_OEM_REVISION,    /* UINT32  OemRevision */     \
>> +    EFI_ACPI_CREATOR_ID,      /* UINT32  CreatorId */       \
>> +    EFI_ACPI_CREATOR_REVISION /* UINT32  CreatorRevision */ \
>> +  }
>> +
>> +#endif /* ACPI_HEADER_H_ */
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
>> new file mode 100644
>> index 000000000000..fa188c7776db
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiApei.c
>> @@ -0,0 +1,457 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/AcpiHelperLib.h>
>> +#include <Library/FlashLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <NVParamDef.h>
>> +
>> +#include "AcpiApei.h"
>> +
>> +UINT8 AMPERE_GUID[16] = {0x8d, 0x89, 0xed, 0xe8, 0x16, 0xdf, 0xcc, 0x43, 0x8e, 0xcc, 0x54, 0xf0, 0x60, 0xef, 0x15, 0x7f};
>> +CHAR8 DEFAULT_BERT_REBOOT_MSG[BERT_MSG_SIZE] = "Unknown reboot reason";
>> +
>> +STATIC VOID
>> +AcpiApeiUninstallTable (
>> +  UINT32 Signature
>> +  )
>> +{
>> +  EFI_STATUS              Status;
>> +  EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
>> +  EFI_ACPI_SDT_PROTOCOL   *AcpiTableSdtProtocol;
>> +  EFI_ACPI_SDT_HEADER     *Table;
>> +  EFI_ACPI_TABLE_VERSION  TableVersion;
>> +  UINTN                   TableKey;
>> +  UINTN                   Idx;
>> +
>> +  /*
>> +   * Get access to ACPI tables
>> +   */
>> +  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **)&AcpiTableProtocol);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table protocol\n", __FUNCTION__, __LINE__));
>> +    return;
>> +  }
>> +
>> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to locate ACPI table support protocol\n", __FUNCTION__, __LINE__));
>> +    return;
>> +  }
>> +
>> +  /*
>> +   * Search for ACPI Table Signature
>> +   */
>> +  for (Idx = 0; ; Idx++) {
>> +    Status = AcpiTableSdtProtocol->GetAcpiTable (Idx, &Table, &TableVersion, &TableKey);
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "%a:%d: Unable to get ACPI table index %d \n", __FUNCTION__, __LINE__, Idx));
>> +      return;
>> +    } else if (Table->Signature == Signature) {
>> +      break;
>> +    }
>> +  }
>> +
>> +  /*
>> +   * Uninstall ACPI Table
>> +   */
>> +  Status = AcpiTableProtocol->UninstallAcpiTable (AcpiTableProtocol, TableKey);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "%a:%d: Unable to uninstall table\n", __FUNCTION__, __LINE__));
>> +  }
>> +}
>> +
>> +VOID
>> +AdjustBERTRegionLen (
>> +  UINT32 Len
>> +  )
>> +{
>> +  UINT32                                      Signature = EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE;
>> +  EFI_STATUS                                  Status;
>> +  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableSdtProtocol = NULL;
>> +  EFI_ACPI_TABLE_VERSION                      TableVersion;
>> +  UINTN                                       TableKey;
>> +  UINTN                                       Idx;
>> +  EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER *Table;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiSdtProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableSdtProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
>> +    return;
>> +  }
>> +
>> +  /*
>> +   * Search for ACPI Table Signature
>> +   */
>> +  for (Idx = 0; ; Idx++) {
>> +    Status = AcpiTableSdtProtocol->GetAcpiTable (
>> +                                     Idx,
>> +                                     (EFI_ACPI_SDT_HEADER **)&Table,
>> +                                     &TableVersion,
>> +                                     &TableKey
>> +                                     );
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "APEI: Unable to get ACPI table index:%d\n", Idx));
>> +      return;
>> +    } else if (Table->Header.Signature == Signature) {
>> +      break;
>> +    }
>> +  }
>> +
>> +  /*
>> +   * Adjust Boot Error Region Length
>> +   */
>> +  Table->BootErrorRegionLength = Len;
>> +
>> +  AcpiTableChecksum ((UINT8 *)Table, Table->Header.Length);
>> +}
>> +
>> +/*
>> + * Retrieve Bert data from SPI NOR
>> + */
>> +VOID
>> +PullBertSpinorData (
>> +  APEI_CRASH_DUMP_DATA *BertErrorData
>> +  )
>> +{
>> +  UINTN Length;
>> +
>> +  Length = sizeof (*BertErrorData);
>> +
>> +  FlashReadCommand (
>> +    (UINT8 *)BERT_FLASH_OFFSET,
>> +    (UINT8 *)BertErrorData,
>> +    &Length
>> +    );
>> +}
>> +
>> +/*
>> + * wrap raw bert error data
>> + *
>> + * @param  IN  BertErrorData     Bert Error record to be wrapped
>> + * @param  OUT WrappedError      Generic error data for OS to consume.
>> + */
>> +VOID
>> +WrapBertErrorData (
>> +  APEI_CRASH_DUMP_BERT_ERROR *WrappedError
>> +  )
>> +{
>> +  UINT32 CrashSize;
>> +
>> +  CrashSize = PLAT_CRASH_ITERATOR_SIZE *
>> +              GetNumberOfSupportedSockets () *
>> +              GetMaximumNumberOfCores ();
>> +  CrashSize += 2 * (SMPRO_CRASH_SIZE + PMPRO_CRASH_SIZE);
>> +  CrashSize += sizeof (WrappedError->Bed.Vendor) + sizeof (WrappedError->Bed.BertRev);
>> +
>> +  WrappedError->Ges.BlockStatus.ErrorDataEntryCount = 1;
>> +  WrappedError->Ges.BlockStatus.UncorrectableErrorValid = 1;
>> +  WrappedError->Ged.ErrorSeverity = BERT_DEFAULT_ERROR_SEVERITY;
>> +  WrappedError->Ged.Revision = GENERIC_ERROR_DATA_REVISION;
>> +
>> +  if (WrappedError->Bed.Vendor.Type == RAS_2P_TYPE ||
>> +      (WrappedError->Bed.Vendor.Type == BERT_ERROR_TYPE &&
>> +       (WrappedError->Bed.Vendor.SubType == 0 ||
>> +        WrappedError->Bed.Vendor.SubType == BERT_UEFI_FAILURE)))
>> +  {
>> +    WrappedError->Ged.ErrorDataLength = sizeof (WrappedError->Bed.Vendor) +
>> +                                        sizeof (WrappedError->Bed.BertRev);
>> +    WrappedError->Ges.DataLength = sizeof (WrappedError->Bed.Vendor) +
>> +                                   sizeof (WrappedError->Bed.BertRev) +
>> +                                   sizeof (WrappedError->Ged);
>> +    AdjustBERTRegionLen (
>> +      sizeof (WrappedError->Bed.Vendor) +
>> +      sizeof (WrappedError->Bed.BertRev) +
>> +      sizeof (WrappedError->Ged) +
>> +      sizeof (WrappedError->Ges)
>> +      );
>> +  } else {
>> +    WrappedError->Ged.ErrorDataLength = CrashSize;
>> +    WrappedError->Ges.DataLength = CrashSize + sizeof (WrappedError->Ged);
>> +    AdjustBERTRegionLen (
>> +      CrashSize +
>> +      sizeof (WrappedError->Ged) +
>> +      sizeof (WrappedError->Ges)
>> +      );
>> +  }
>> +  CopyMem (
>> +    WrappedError->Ged.SectionType,
>> +    AMPERE_GUID,
>> +    sizeof (AMPERE_GUID)
>> +    );
>> +}
>> +
>> +
>> +/*
>> + * create default bert error
>> + * Msg: Unknown reboot reason
>> + */
>> +VOID
>> +CreateDefaultBertData (
>> +  APEI_BERT_ERROR_DATA *Data
>> +  )
>> +{
>> +  Data->Type = BERT_ERROR_TYPE;
>> +  AsciiStrCpyS (
>> +    Data->Msg,
>> +    BERT_MSG_SIZE,
>> +    DEFAULT_BERT_REBOOT_MSG
>> +    );
>> +}
>> +
>> +/*
>> + * Ensures BertErrorData In SPINOR matches
>> + * the record produced by CreateDefaultBertData.
>> + * @param  Bed    Crash dump Data
>> + */
>> +VOID
>> +WriteSpinorDefaultBertTable (
>> +  APEI_CRASH_DUMP_DATA *Bed
>> +  )
>> +{
>> +  UINT8                BertRev;
>> +  UINTN                Length;
>> +  UINT64               Offset;
>> +  UINT32               MsgDiff;
>> +  APEI_BERT_ERROR_DATA DefaultData = {0};
>> +
>> +  CreateDefaultBertData (&DefaultData);
>> +  if ((Bed->Vendor.Type != DefaultData.Type)) {
>> +    Offset = BERT_FLASH_OFFSET +
>> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
>> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Type);
>> +    Length = sizeof (DefaultData.Type);
>> +    FlashEraseCommand ((UINT8 *)Offset, Length);
>> +    FlashProgramCommand (
>> +      (UINT8 *)Offset,
>> +      (UINT8 *)&(DefaultData.Type),
>> +      &Length
>> +      );
>> +  }
>> +
>> +  if ((Bed->Vendor.SubType != DefaultData.SubType)) {
>> +    Offset = BERT_FLASH_OFFSET +
>> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
>> +             OFFSET_OF (APEI_BERT_ERROR_DATA, SubType);
>> +    Length = sizeof (DefaultData.SubType);
>> +    FlashEraseCommand ((UINT8 *)Offset, Length);
>> +    FlashProgramCommand (
>> +      (UINT8 *)Offset,
>> +      (UINT8 *)&(DefaultData.SubType),
>> +      &Length
>> +      );
>> +  }
>> +
>> +  if ((Bed->Vendor.Instance != DefaultData.Instance)) {
>> +    Offset = BERT_FLASH_OFFSET +
>> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
>> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Instance);
>> +    Length = sizeof (DefaultData.Instance);
>> +    FlashEraseCommand ((UINT8 *)Offset, Length);
>> +    FlashProgramCommand (
>> +      (UINT8 *)Offset,
>> +      (UINT8 *)&(DefaultData.Instance),
>> +      &Length
>> +      );
>> +  }
>> +
>> +  MsgDiff = AsciiStrnCmp (Bed->Vendor.Msg, DefaultData.Msg, BERT_MSG_SIZE);
>> +  if (MsgDiff != 0) {
>> +    Offset = BERT_FLASH_OFFSET +
>> +             OFFSET_OF (APEI_CRASH_DUMP_DATA, Vendor) +
>> +             OFFSET_OF (APEI_BERT_ERROR_DATA, Msg);
>> +    Length = sizeof (DefaultData.Msg);
>> +    FlashEraseCommand ((UINT8 *)Offset, Length);
>> +    FlashProgramCommand (
>> +      (UINT8 *)Offset,
>> +      (UINT8 *)&(DefaultData.Msg),
>> +      &Length
>> +      );
>> +  }
>> +
>> +  if (Bed->BertRev != CURRENT_BERT_VERSION) {
>> +    Offset = BERT_FLASH_OFFSET + OFFSET_OF (APEI_CRASH_DUMP_DATA, BertRev);
>> +    Length = sizeof (Bed->BertRev);
>> +    BertRev = CURRENT_BERT_VERSION;
>> +    FlashEraseCommand ((UINT8 *)Offset, Length);
>> +    FlashProgramCommand ((UINT8 *)Offset, (UINT8 *)&BertRev, &Length);
>> +  }
>> +
>> +}
>> +
>> +/*
>> + * Checks Status of NV_SI_RAS_BERT_ENABLED
>> + * Returns TRUE if enabled and FALSE if disabled
>> + */
>> +BOOLEAN
>> +IsBertEnabled (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +
>> +  Status = NVParamGet (
>> +             NV_SI_RAS_BERT_ENABLED,
>> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +             &Value
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    // BERT is enabled by default
>> +    return TRUE;
>> +  }
>> +
>> +  return (Value != 0) ? TRUE : FALSE;
>> +}
>> +
>> +/*
>> + * Write bert table to DDR
>> + */
>> +VOID
>> +WriteDDRBertTable (
>> +  APEI_CRASH_DUMP_BERT_ERROR *Data
>> +  )
>> +{
>> +  VOID *Blk = (VOID *)BERT_DDR_OFFSET;
>> +
>> +  /*
>> +   * writing sizeof data to ddr produces alignment error
>> +   * this is a temporary workaround
>> +   */
>> +  CopyMem (Blk, Data, BERT_DDR_LENGTH);
>> +}
>> +
>> +/*
>> + * Update Bert Table
>> + */
>> +EFI_STATUS
>> +AcpiPopulateBert (
>> +  VOID
>> +  )
>> +{
>> +  APEI_CRASH_DUMP_BERT_ERROR *DDRError;
>> +
>> +  DDRError =
>> +    (APEI_CRASH_DUMP_BERT_ERROR *)
>> +    AllocateZeroPool (sizeof (APEI_CRASH_DUMP_BERT_ERROR));
>> +
>> +  if (DDRError == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  if (IsBertEnabled ()) {
>> +    PullBertSpinorData (&(DDRError->Bed));
>> +    if ((DDRError->Bed.BertRev == CURRENT_BERT_VERSION)) {
>> +      WrapBertErrorData (DDRError);
>> +      WriteDDRBertTable (DDRError);
>> +    }
>> +    WriteSpinorDefaultBertTable (&(DDRError->Bed));
>> +  }
>> +
>> +  FreePool (DDRError);
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/*
>> + * Checks Status of NV_SI_RAS_SDEI_ENABLED
>> + * Returns TRUE if enabled and FALSE if disabled or error occurred
>> + */
>> +BOOLEAN
>> +IsSdeiEnabled (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  UINT32     Value;
>> +
>> +  Status = NVParamGet (
>> +             NV_SI_RAS_SDEI_ENABLED,
>> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +             &Value
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    // SDEI is disabled by default
>> +    return FALSE;
>> +  }
>> +
>> +  return (Value != 0) ? TRUE : FALSE;
>> +}
>> +
>> +STATIC
>> +VOID
>> +AcpiApeiHestUpdateTable1P (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS                                      Status;
>> +  EFI_ACPI_SDT_PROTOCOL                           *AcpiTableSdtProtocol = NULL;
>> +  EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_HEADER *HestTablePointer;
>> +  EFI_ACPI_TABLE_VERSION                          TableVersion;
>> +  UINTN                                           TableKey;
>> +  UINTN                                           Idx;
>> +
>> +  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **)&AcpiTableSdtProtocol);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "APEI: Unable to locate ACPI table support protocol\n"));
>> +    return;
>> +  }
>> +
>> +  /*
>> +   * Search for ACPI Table Signature
>> +   */
>> +  for (Idx = 0; ; Idx++) {
>> +    Status = AcpiTableSdtProtocol->GetAcpiTable (
>> +                                     Idx,
>> +                                     (EFI_ACPI_SDT_HEADER **)&HestTablePointer,
>> +                                     &TableVersion,
>> +                                     &TableKey
>> +                                     );
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "APEI: Unable to get HEST table"));
>> +      return;
>> +    } else if (HestTablePointer->Header.Signature ==
>> +               EFI_ACPI_6_3_HARDWARE_ERROR_SOURCE_TABLE_SIGNATURE)
>> +    {
>> +      break;
>> +    }
>> +  }
>> +
>> +  HestTablePointer->ErrorSourceCount -= HEST_NUM_ENTRIES_PER_SOC;
>> +  HestTablePointer->Header.Length -=
>> +    (HEST_NUM_ENTRIES_PER_SOC *
>> +     sizeof (EFI_ACPI_6_3_GENERIC_HARDWARE_ERROR_SOURCE_VERSION_2_STRUCTURE));
>> +
>> +  AcpiTableChecksum ((UINT8 *)HestTablePointer, HestTablePointer->Header.Length);
>> +}
>> +
>> +/*
>> + * Update APEI
>> + *
>> + */
>> +EFI_STATUS
>> +EFIAPI
>> +AcpiApeiUpdate (
>> +  VOID
>> +  )
>> +{
>> +  if (!IsSlaveSocketActive ()) {
>> +    AcpiApeiHestUpdateTable1P ();
>> +  }
>> +
>> +  if (!IsSdeiEnabled ()) {
>> +    AcpiApeiUninstallTable (EFI_ACPI_6_3_SOFTWARE_DELEGATED_EXCEPTIONS_INTERFACE_TABLE_SIGNATURE);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
>> new file mode 100644
>> index 000000000000..7881044104e4
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiDsdt.c
>> @@ -0,0 +1,445 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Protocol/PciRootBridgeIo.h>
>> +#include <Library/NVParamLib.h>
>> +#include <NVParamDef.h>
>> +
>> +#include "AcpiNfit.h"
>> +#include "AcpiPlatform.h"
>> +
>> +#define PCIE_DEVICE_CONTROL_OFFSET                      0x078
>> +#define PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN        0x08
>> +#define PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN         0x04
>> +#define PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN     0x02
>> +#define PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN          0x01
>> +
>> +#define PCIE_ROOT_ERR_CMD_OFFSET                        0x12C
>> +#define PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN        0x4
>> +#define PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN    0x2
>> +#define PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN         0x1
>> +
>> +#define PCIE_MAX_DEVICE_PER_ROOT_PORT 8
>> +
>> +STATIC VOID
>> +AcpiPatchCmn600 (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
>> +  UINTN Index;
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.CMN%1X._STA", Index);
>> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
>> +    } else {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    }
>> +  }
>> +}
>> +
>> +STATIC VOID
>> +AcpiPatchDmc620 (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
>> +  UINTN              Index, Index1;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  UINT32             McuMask;
>> +  VOID               *Hob;
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    McuMask = PlatformHob->DramInfo.McuMask[Index];
>> +    for (Index1 = 0; Index1 < sizeof (McuMask) * 8; Index1++) {
>> +      AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.MC%1X%1X._STA", Index, Index1);
>> +      if (McuMask & (0x1 << Index1)) {
>> +        AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
>> +      } else {
>> +        AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +      }
>> +    }
>> +  }
>> +}
>> +
>> +STATIC VOID
>> +AcpiPatchNvdimm (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8              NodePath[MAX_ACPI_NODE_PATH];
>> +  UINTN              NvdRegionNumSK0, NvdRegionNumSK1, NvdRegionNum, Count;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  VOID               *Hob;
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  NvdRegionNumSK0 = 0;
>> +  NvdRegionNumSK1 = 0;
>> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +    if (PlatformHob->DramInfo.NvdRegion[Count] > 0) {
>> +      if (PlatformHob->DramInfo.Socket[Count] == 0) {
>> +        NvdRegionNumSK0++;
>> +      } else {
>> +        NvdRegionNumSK1++;
>> +      }
>> +    }
>> +  }
>> +  NvdRegionNum = NvdRegionNumSK0 + NvdRegionNumSK1;
>> +
>> +  /* Disable NVDIMM Root Device */
>> +  if (NvdRegionNum == 0) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR._STA");
>> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +  }
>> +  /* Update NVDIMM Device _STA for SK0 */
>> +  if (NvdRegionNumSK0 == 0) {
>> +    /* Disable NVD1/2 */
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
>> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
>> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +  } else if (NvdRegionNumSK0 == 1) {
>> +    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK0] == NVDIMM_NON_HASHED) {
>> +      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
>> +            PlatformHob->DramInfo.Socket[Count] == 0)
>> +        {
>> +          if (PlatformHob->DramInfo.Base[Count] ==
>> +              PLATFORM_NVDIMM_SK0_NHASHED_REGION0)
>> +          {
>> +            /* Disable NVD2 */
>> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD2._STA");
>> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +          } else if (PlatformHob->DramInfo.Base[Count] ==
>> +                     PLATFORM_NVDIMM_SK0_NHASHED_REGION1)
>> +          {
>> +            /* Disable NVD1 */
>> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD1._STA");
>> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +          }
>> +        }
>> +      }
>> +    }
>> +  }
>> +  /* Update NVDIMM Device _STA for SK1 */
>> +  if (NvdRegionNumSK1 == 0) {
>> +    /* Disable NVD3/4 */
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
>> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
>> +    AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +  } else if (NvdRegionNumSK1 == 1) {
>> +    if (PlatformHob->DramInfo.NvdimmMode[NVDIMM_SK1] == NVDIMM_NON_HASHED) {
>> +      for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +        if (PlatformHob->DramInfo.NvdRegion[Count] > 0 &&
>> +            PlatformHob->DramInfo.Socket[Count] == 1)
>> +        {
>> +          if (PlatformHob->DramInfo.Base[Count] ==
>> +              PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
>> +          {
>> +            /* Disable NVD4 */
>> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD4._STA");
>> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +          } else if (PlatformHob->DramInfo.Base[Count] ==
>> +                     PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
>> +          {
>> +            /* Disable NVD3 */
>> +            AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.NVDR.NVD3._STA");
>> +            AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +          }
>> +        }
>> +      }
>> +    }
>> +  }
>> +}
>> +
>> +STATIC VOID
>> +AcpiPatchHwmon (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
>> +  UINT8 Index;
>> +
>> +  // PCC Hardware Monitor Devices
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index);
>> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
>> +    } else {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    }
>> +  }
>> +
>> +  // Ampere Altra SoC Hardware Monitor Devices
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.HM0%1X._STA", Index + 2);
>> +    if (GetNumberOfActiveCPMsPerSocket (Index) > 0) {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
>> +    } else {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    }
>> +  }
>> +}
>> +
>> +STATIC VOID
>> +AcpiPatchDsu (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
>> +  UINTN Index;
>> +
>> +  for (Index = 0; Index < PLATFORM_CPU_MAX_NUM_CORES; Index += PLATFORM_CPU_NUM_CORES_PER_CPM) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.DU%2X._STA", Index / PLATFORM_CPU_NUM_CORES_PER_CPM);
>> +    if (IsCpuEnabled (Index)) {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0xf);
>> +    } else {
>> +      AcpiDSDTSetNodeStatusValue (NodePath, 0x0);
>> +    }
>> +  }
>> +}
>> +
>> +VOID
>> +AcpiPatchPcieNuma (
>> +  VOID
>> +  )
>> +{
>> +  CHAR8 NodePath[MAX_ACPI_NODE_PATH];
>> +  UINTN Index;
>> +  UINTN NumaIdx;
>> +  UINTN NumPciePort;
>> +  UINTN NumaAssignment[3][16] = {
>> +    { 0, 0, 0, 0, 0, 0, 0, 0,   // Monolithic Node 0 (S0)
>> +      1, 1, 1, 1, 1, 1, 1, 1 }, // Monolithic Node 1 (S1)
>> +    { 0, 1, 0, 1, 0, 0, 1, 1,   // Hemisphere Node 0, 1 (S0)
>> +      2, 3, 2, 3, 2, 2, 3, 3 }, // Hemisphere Node 2, 3 (S1)
>> +    { 0, 2, 1, 3, 1, 1, 3, 3,   // Quadrant Node 0, 1, 2, 3 (S0)
>> +      4, 6, 5, 7, 5, 5, 7, 7 }, // Quadrant Node 4, 5, 6, 7 (S1)
>> +  };
>> +
>> +  switch (CpuGetSubNumaMode ()) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    NumaIdx = 0;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    NumaIdx = 1;
>> +    break;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    NumaIdx = 2;
>> +    break;
>> +
>> +  default:
>> +    NumaIdx = 0;
>> +    break;
>> +  }
>> +
>> +  if (IsSlaveSocketActive ()) {
>> +    NumPciePort = 16; // 16 ports total (8 per socket)
>> +  } else {
>> +    NumPciePort = 8;  // 8 ports total
>> +  }
>> +
>> +  for (Index = 0; Index < NumPciePort; Index++) {
>> +    AsciiSPrint (NodePath, sizeof (NodePath), "\\_SB.PCI%X._PXM", Index);
>> +    AcpiDSDTSetNodeStatusValue (NodePath, NumaAssignment[NumaIdx][Index]);
>> +  }
>> +}
>> +
>> +EFI_STATUS
>> +AcpiPatchPcieAerFwFirst (
>> +  VOID
>> +  )
>> +{
>> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS Address;
>> +  EFI_ACPI_SDT_PROTOCOL                       *AcpiTableProtocol;
>> +  EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL             *PciRootBridgeIo;
>> +  EFI_HANDLE                                  *HandleBuffer;
>> +  UINTN                                       HandleCount;
>> +  EFI_ACPI_HANDLE                             TableHandle;
>> +  EFI_ACPI_HANDLE                             ChildHandle;
>> +  EFI_ACPI_DATA_TYPE                          DataType;
>> +  UINTN                                       DataSize;
>> +  CHAR8                                       ObjectPath[8];
>> +  EFI_STATUS                                  Status;
>> +  UINT32                                      AerFwFirstConfigValue;
>> +  UINT32                                      RegData;
>> +  UINT16                                      Device;
>> +  UINT32                                      Index;
>> +  UINT8                                       *Data;
>> +
>> +  //
>> +  // Check if PCIe AER Firmware First should be enabled
>> +  //
>> +  Status = NVParamGet (
>> +             NV_SI_RAS_PCIE_AER_FW_FIRST,
>> +             NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +             &AerFwFirstConfigValue
>> +             );
>> +  if (EFI_ERROR (Status)) {
>> +    Status = NVParamGet (
>> +               NV_SI_RO_BOARD_PCIE_AER_FW_FIRST,
>> +               NV_PERM_ATF | NV_PERM_BIOS | NV_PERM_MANU | NV_PERM_BMC,
>> +               &AerFwFirstConfigValue
>> +               );
>> +    if (EFI_ERROR (Status)) {
>> +      AerFwFirstConfigValue = 0;
>> +    }
>> +  }
>> +
>> +  if (AerFwFirstConfigValue == 0) {
>> +    //
>> +    // By default, the PCIe AER FW-First (ACPI Object "AERF") is set to 0
>> +    // in the DSDT table.
>> +    //
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiSdtProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n"));
>> +    return Status;
>> +  }
>> +
>> +  Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle);
>> +  if (EFI_ERROR (Status)) {
>> +    AcpiTableProtocol->Close (TableHandle);
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Update Name Object "AERF" (PCIe AER Firmware-First) if it is enabled.
>> +  //
>> +  AsciiSPrint (ObjectPath, sizeof (ObjectPath), "\\AERF");
>> +  Status = AcpiTableProtocol->FindPath (TableHandle, ObjectPath, &ChildHandle);
>> +  ASSERT_EFI_ERROR (Status);
>> +  if (!EFI_ERROR (Status)) {
>> +    Status = AcpiTableProtocol->GetOption (
>> +                                  ChildHandle,
>> +                                  0,
>> +                                  &DataType,
>> +                                  (VOID *)&Data,
>> +                                  &DataSize
>> +                                  );
>> +    ASSERT_EFI_ERROR (Status);
>> +    if (!EFI_ERROR (Status)
>> +        && Data[0] == AML_NAME_OP
>> +        && (Data[5] == AML_ZERO_OP || Data[5] == AML_ONE_OP))
>> +    {
>> +      Data[5] = 1; // Enable PCIe AER Firmware-First
>> +    }
>> +  }
>> +
>> +  AcpiTableProtocol->Close (TableHandle);
>> +  AcpiDSDTUpdateChecksum (AcpiTableProtocol);
>> +
>> +  //
>> +  // For PCIe AER Firmware First, PCIe capability registers need
>> +  // to be updated to allow Firmware to detect AER errors.
>> +  //
>> +
>> +  HandleCount = 0;
>> +  HandleBuffer = NULL;
>> +  PciRootBridgeIo = NULL;
>> +
>> +  Status = gBS->LocateHandleBuffer (
>> +                  ByProtocol,
>> +                  &gEfiPciRootBridgeIoProtocolGuid,
>> +                  NULL,
>> +                  &HandleCount,
>> +                  &HandleBuffer
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Loop through each root complex
>> +  //
>> +  for (Index = 0; Index < HandleCount; Index++) {
>> +    Status = gBS->HandleProtocol (
>> +                    HandleBuffer[Index],
>> +                    &gEfiPciRootBridgeIoProtocolGuid,
>> +                    (VOID **)&PciRootBridgeIo
>> +                    );
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +
>> +    //
>> +    // Loop through each root port
>> +    //
>> +    for (Device = 1; Device <= PCIE_MAX_DEVICE_PER_ROOT_PORT; Device++) {
>> +      Address.Bus = 0;
>> +      Address.Device = Device;
>> +      Address.Function = 0;
>> +      Address.Register = 0;
>> +
>> +      Address.ExtendedRegister = PCIE_DEVICE_CONTROL_OFFSET;
>> +      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
>> +
>> +      if (RegData == 0xFFFFFFFF) {
>> +        continue;
>> +      }
>> +
>> +      RegData |= PCIE_DEVICE_CONTROL_UNSUPPORT_REQ_REP_EN
>> +                 | PCIE_DEVICE_CONTROL_FATAL_ERR_REPORT_EN
>> +                 | PCIE_DEVICE_CONTROL_NON_FATAL_ERR_REPORT_EN
>> +                 | PCIE_DEVICE_CONTROL_CORR_ERR_REPORT_EN;
>> +
>> +      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
>> +
>> +      RegData = 0;
>> +      Address.ExtendedRegister = PCIE_ROOT_ERR_CMD_OFFSET;
>> +      PciRootBridgeIo->Pci.Read (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
>> +
>> +      RegData |= PCIE_ROOT_ERR_CMD_FATAL_ERR_REPORTING_EN
>> +                 | PCIE_ROOT_ERR_CMD_NON_FATAL_ERR_REPORTING_EN
>> +                 | PCIE_ROOT_ERR_CMD_CORR_ERR_REPORTING_EN;
>> +
>> +      PciRootBridgeIo->Pci.Write (PciRootBridgeIo, EfiPciWidthUint32, *((UINT64 *)&Address), 1, &RegData);
>> +    }
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiPatchDsdtTable (
>> +  VOID
>> +  )
>> +{
>> +  AcpiPatchCmn600 ();
>> +  AcpiPatchDmc620 ();
>> +  AcpiPatchDsu ();
>> +  AcpiPatchHwmon ();
>> +  AcpiPatchNvdimm ();
>> +  AcpiPatchPcieNuma ();
>> +  AcpiPatchPcieAerFwFirst ();
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
>> new file mode 100644
>> index 000000000000..1d1643abd299
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiMadt.c
>> @@ -0,0 +1,351 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "AcpiPlatform.h"
>> +
>> +EFI_ACPI_6_3_GIC_ITS_STRUCTURE GicItsTemplate = {
>> +  EFI_ACPI_6_3_GIC_ITS,
>> +  sizeof (EFI_ACPI_6_3_GIC_ITS_STRUCTURE),
>> +  EFI_ACPI_RESERVED_WORD,
>> +  0, /* GicItsId */
>> +  0, /* PhysicalBaseAddress */
>> +  0, /* Reserved2 */
>> +};
>> +
>> +EFI_ACPI_6_3_GICR_STRUCTURE GicRTemplate = {
>> +  EFI_ACPI_6_3_GICR,
>> +  sizeof (EFI_ACPI_6_3_GICR_STRUCTURE),
>> +  EFI_ACPI_RESERVED_WORD,
>> +  GICR_MASTER_BASE_REG, /* DiscoveryRangeBaseAddress */
>> +  0x1000000,            /* DiscoveryRangeLength */
>> +};
>> +
>> +EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE GicDTemplate = {
>> +  EFI_ACPI_6_3_GICD,
>> +  sizeof (EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE),
>> +  EFI_ACPI_RESERVED_WORD,
>> +  0,             /* GicDistHwId */
>> +  GICD_BASE_REG, /* GicDistBase */
>> +  0,             /* GicDistVector */
>> +  0x3,           /* GicVersion */
>> +  {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE}
>> +};
>> +
>> +EFI_ACPI_6_3_GIC_STRUCTURE GiccTemplate = {
>> +  EFI_ACPI_6_3_GIC,
>> +  sizeof (EFI_ACPI_6_3_GIC_STRUCTURE),
>> +  EFI_ACPI_RESERVED_WORD,
>> +  0, /* GicId */
>> +  0, /* AcpiCpuUid */
>> +  0, /* Flags */
>> +  0,
>> +  23, /* PmuIrq */
>> +  0,
>> +  0,
>> +  0,
>> +  0,
>> +  25, /* GsivId */
>> +  0,  /* GicRBase */
>> +  0,  /* Mpidr */
>> +  0,  /* ProcessorPowerEfficiencyClass */
>> +  0,  /* Reserved2 */
>> +  21, /* SPE irq */
>> +};
>> +
>> +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER MADTTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,
>> +    0, /* need fill in */
>> +    EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION
>> +    ),
>> +};
>> +
>> +UINT32 Ac01CoreOrderMonolithic[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
>> +  36, 52, 40, 56, 32, 48, 44, 60,
>> +  20, 68, 24, 72, 16, 64, 28, 76,
>> +  4, 8, 0, 12, 38, 54, 42, 58,
>> +  34, 50, 46, 62, 22, 70, 26, 74,
>> +  18, 66, 30, 78, 6, 10, 2, 14,
>> +  37, 53, 41, 57, 33, 49, 45, 61,
>> +  21, 69, 25, 73, 17, 65, 29, 77,
>> +  5, 9, 1, 13, 39, 55, 43, 59,
>> +  35, 51, 47, 63, 23, 71, 27, 75,
>> +  19, 67, 31, 79, 7, 11, 3, 15,
>> +};
>> +
>> +UINT32 Ac01CoreOrderHemisphere[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
>> +  32, 48, 16, 64, 36, 52, 0, 20,
>> +  68, 4, 34, 50, 18, 66, 38, 54,
>> +  2, 22, 70, 6, 33, 49, 17, 65,
>> +  37, 53, 1, 21, 69, 5, 35, 51,
>> +  19, 67, 39, 55, 3, 23, 71, 7,
>> +  44, 60, 28, 76, 40, 56, 12, 24,
>> +  72, 8, 46, 62, 30, 78, 42, 58,
>> +  14, 26, 74, 10, 45, 61, 29, 77,
>> +  41, 57, 13, 25, 73, 9, 47, 63,
>> +  31, 79, 43, 59, 15, 27, 75, 11,
>> +};
>> +
>> +UINT32 Ac01CoreOrderQuadrant[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM] = {
>> +  16, 32, 0, 20, 4, 18, 34, 2,
>> +  22, 6, 17, 33, 1, 21, 5, 19,
>> +  35, 3, 23, 7, 48, 64, 52, 68,
>> +  36, 50, 66, 54, 70, 38, 49, 65,
>> +  53, 69, 37, 51, 67, 55, 71, 39,
>> +  28, 44, 12, 24, 8, 30, 46, 14,
>> +  26, 10, 29, 45, 13, 25, 9, 31,
>> +  47, 15, 27, 11, 60, 76, 56, 72,
>> +  40, 62, 78, 58, 74, 42, 61, 77,
>> +  57, 73, 41, 63, 79, 59, 75, 43,
>> +};
>> +
>> +EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *MadtTablePointer;
>> +
>> +UINT32 *
>> +CpuGetCoreOrder (
>> +  VOID
>> +  )
>> +{
>> +  UINT8              SubNumaMode;
>> +
>> +  SubNumaMode = CpuGetSubNumaMode ();
>> +  switch (SubNumaMode) {
>> +  case SUBNUMA_MODE_MONOLITHIC:
>> +    return (UINT32 *)&Ac01CoreOrderMonolithic;
>> +
>> +  case SUBNUMA_MODE_HEMISPHERE:
>> +    return (UINT32 *)&Ac01CoreOrderHemisphere;
>> +
>> +  case SUBNUMA_MODE_QUADRANT:
>> +    return (UINT32 *)&Ac01CoreOrderQuadrant;
>> +
>> +  default:
>> +    // Should never reach here
>> +    ASSERT (FALSE);
>> +    return NULL;
>> +  }
>> +
>> +  return NULL;
>> +}
>> +
>> +UINT32
>> +AcpiInstallMadtProcessorNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 CpuId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GIC_STRUCTURE *MadtProcessorEntryPointer = EntryPointer;
>> +  UINT32                     SocketId;
>> +  UINT32                     ClusterId;
>> +  UINTN                      Size;
>> +
>> +  Size = sizeof (GiccTemplate);
>> +  CopyMem (MadtProcessorEntryPointer, &GiccTemplate, Size);
>> +
>> +  SocketId = SOCKET_ID (CpuId);
>> +  ClusterId = CLUSTER_ID (CpuId);
>> +
>> +  //
>> +  // GICv2 compatibility mode is not supported.
>> +  // Hence, set GIC's CPU Interface Number to 0.
>> +  //
>> +  MadtProcessorEntryPointer->CPUInterfaceNumber = 0;
>> +  MadtProcessorEntryPointer->AcpiProcessorUid =
>> +    (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
>> +    (ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM);
>> +  MadtProcessorEntryPointer->Flags = 1;
>> +  MadtProcessorEntryPointer->MPIDR =
>> +    (((ClusterId << 8) + (CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM)) << 8);
>> +  MadtProcessorEntryPointer->MPIDR += (((UINT64)SocketId) << 32);
>> +
>> +  return Size;
>> +}
>> +
>> +UINT32
>> +AcpiInstallMadtGicD (
>> +  VOID *EntryPointer
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GIC_DISTRIBUTOR_STRUCTURE *GicDEntryPointer = EntryPointer;
>> +  UINTN                                  Size;
>> +
>> +  Size = sizeof (GicDTemplate);
>> +  CopyMem (GicDEntryPointer, &GicDTemplate, Size);
>> +
>> +  return Size;
>> +}
>> +
>> +UINT32
>> +AcpiInstallMadtGicR (
>> +  VOID   *EntryPointer,
>> +  UINT32 SocketId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GICR_STRUCTURE *GicREntryPointer = EntryPointer;
>> +  UINTN                       Size;
>> +
>> +  /*
>> +   * If the Slave socket is not present, discard the Slave socket
>> +   * GIC redistributor region
>> +   */
>> +  if (SocketId == 1 && !IsSlaveSocketActive ()) {
>> +    return 0;
>> +  }
>> +
>> +  Size = sizeof (GicRTemplate);
>> +  CopyMem (GicREntryPointer, &GicRTemplate, Size);
>> +
>> +  if (SocketId == 1) {
>> +    GicREntryPointer->DiscoveryRangeBaseAddress = GICR_SLAVE_BASE_REG;
>> +  }
>> +
>> +  return Size;
>> +}
>> +
>> +UINT32
>> +AcpiInstallMadtGicIts (
>> +  VOID   *EntryPointer,
>> +  UINT32 Index
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GIC_ITS_STRUCTURE *GicItsEntryPointer = EntryPointer;
>> +  UINTN                          Size, Offset;
>> +  UINT64                         GicBase = GICD_BASE_REG;
>> +  UINT32                         ItsId = Index;
>> +
>> +  if (Index > SOCKET0_LAST_RC) { /* Socket 1, Index: 8-15 */
>> +    GicBase = GICD_SLAVE_BASE_REG;
>> +    Index -= (SOCKET0_LAST_RC + 1); /* Socket 1, Index:8 -> RCA0 */
>> +  }
>> +  Size = sizeof (GicItsTemplate);
>> +  CopyMem (GicItsEntryPointer, &GicItsTemplate, Size);
>> +  Offset = 0x40000 + Index * 0x20000;
>> +  GicItsEntryPointer->GicItsId = ItsId;
>> +  GicItsEntryPointer->PhysicalBaseAddress = Offset + GicBase;
>> +
>> +  return Size;
>> +}
>> +
>> +/*
>> + *  Install MADT table.
>> + */
>> +EFI_STATUS
>> +AcpiInstallMadtTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GIC_STRUCTURE *GiccEntryPointer = NULL;
>> +  EFI_ACPI_TABLE_PROTOCOL    *AcpiTableProtocol;
>> +  UINTN                      MadtTableKey  = 0;
>> +  INTN                       Index;
>> +  EFI_STATUS                 Status;
>> +  UINTN                      Size;
>> +  UINT32                     *CoreOrder;
>> +  UINT32                     SktMaxCoreNum;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Size = sizeof (MADTTableHeaderTemplate) +
>> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (GiccTemplate)) +
>> +          sizeof (GicDTemplate) +
>> +          (PLATFORM_CPU_MAX_SOCKET * sizeof (GicRTemplate)) +
>> +          ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsTemplate));
>> +  if (IsSlaveSocketActive ()) {
>> +    Size += ((SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsTemplate));
>> +  } else if (!IsSlaveSocketPresent ()) {
>> +    Size += 2 * sizeof (GicItsTemplate); /* RCA0/1 */
>> +  }
>> +
>> +  MadtTablePointer =
>> +    (EFI_ACPI_6_3_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER *)AllocateZeroPool (Size);
>> +  if (MadtTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  GiccEntryPointer =
>> +    (EFI_ACPI_6_3_GIC_STRUCTURE *)((UINT64)MadtTablePointer +
>> +                                    sizeof (MADTTableHeaderTemplate));
>> +
>> +  /* Install Gic interface for each processor */
>> +  Size = 0;
>> +  CoreOrder = CpuGetCoreOrder ();
>> +  ASSERT (CoreOrder != NULL);
>> +  SktMaxCoreNum = PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +  for (Index = 0; Index < SktMaxCoreNum; Index++) {
>> +    if (IsCpuEnabled (CoreOrder[Index])) {
>> +      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index]);
>> +    }
>> +  }
>> +
>> +  for (Index = 0; Index < SktMaxCoreNum; Index++) {
>> +    if (IsCpuEnabled (CoreOrder[Index] + SktMaxCoreNum)) {
>> +      Size += AcpiInstallMadtProcessorNode ((VOID *)((UINT64)GiccEntryPointer + Size), CoreOrder[Index] + SktMaxCoreNum);
>> +    }
>> +  }
>> +
>> +  /* Install Gic Distributor */
>> +  Size += AcpiInstallMadtGicD ((VOID *)((UINT64)GiccEntryPointer + Size));
>> +
>> +  /* Install Gic Redistributor */
>> +  for (Index = 0; Index < PLATFORM_CPU_MAX_SOCKET; Index++) {
>> +    Size += AcpiInstallMadtGicR ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
>> +  }
>> +
>> +  /* Install Gic ITS */
>> +  if (!IsSlaveSocketPresent ()) {
>> +    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
>> +      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
>> +    }
>> +  }
>> +  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
>> +    Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
>> +  }
>> +  if (IsSlaveSocketActive ()) {
>> +    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
>> +      Size += AcpiInstallMadtGicIts ((VOID *)((UINT64)GiccEntryPointer + Size), Index);
>> +    }
>> +  }
>> +  CopyMem (
>> +    MadtTablePointer,
>> +    &MADTTableHeaderTemplate,
>> +    sizeof (MADTTableHeaderTemplate)
>> +    );
>> +
>> +  Size += sizeof (MADTTableHeaderTemplate);
>> +  MadtTablePointer->Header.Length = Size;
>> +  CopyMem (
>> +    MadtTablePointer->Header.OemId,
>> +    PcdGetPtr (PcdAcpiDefaultOemId),
>> +    sizeof (MadtTablePointer->Header.OemId)
>> +    );
>> +
>> +  AcpiTableChecksum (
>> +    (UINT8 *)MadtTablePointer,
>> +    MadtTablePointer->Header.Length
>> +    );
>> +
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)MadtTablePointer,
>> +                                MadtTablePointer->Header.Length,
>> +                                &MadtTableKey
>> +                                );
>> +  FreePool ((VOID *)MadtTablePointer);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
>> new file mode 100644
>> index 000000000000..d13ac3514e11
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiNfit.c
>> @@ -0,0 +1,599 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "AcpiNfit.h"
>> +#include "AcpiPlatform.h"
>> +
>> +EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE NfitSPATemplate = {
>> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE_TYPE,
>> +  sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE),
>> +  0,                                                                // The uniue index - need to be filled.
>> +  0,                                                                // The flags - need to be filled.
>> +  0,                                                                // Reserved.
>> +  0,                                                                // Proximity domain - need to be filled.
>> +  EFI_ACPI_6_3_NFIT_GUID_BYTE_ADDRESSABLE_PERSISTENT_MEMORY_REGION, // PM range type.
>> +  0,                                                                // Start address - need to be filled.
>> +  0,                                                                // Size - need to be filled.
>> +  EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB |
>> +  EFI_MEMORY_WP | EFI_MEMORY_UCE, // attribute - need to be filled.
>> +};
>> +
>> +EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE NvdimmControlRegionTemplate = {
>> +  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE_TYPE,
>> +  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE),
>> +  0,   // The unique index - need to be filled.
>> +  0,   // The vendor id - need to be filled.
>> +  0,   // The device id - need to be filled.
>> +  0,   // The revision - need to be filled.
>> +  0,   // The subsystem nvdimm id - need to be filled.
>> +  0,   // The subsystem nvdimm device id - need to be filled.
>> +  0,   // The subsystem revision - need to be filled.
>> +  0,   // The valid field.
>> +  0,   // The manufacturing location - not valid.
>> +  0,   // The manufacturing date - not valid.
>> +  {0}, // Reserved.
>> +  0,   // The serial number - need to be filled.
>> +  0,   // The region format interface code - dummy value.
>> +  0,   // The number of block control windows.
>> +  0,   // The size of block control windows.
>> +  0,   // The Command Register Offset in Block Control Window.
>> +  0,   // The Size of Command Register in Block Control Windows.
>> +  0,   // The Status Register Offset in Block Control Window.
>> +  0,   // Size of Status Register in Block Control Windows.
>> +  0,   // The NVDIMM Control Region Flag.
>> +  {0}, // Reserved.
>> +};
>> +
>> +EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE NvdimmRegionMappingTemplate = {
>> +  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE_TYPE,
>> +  sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE),
>> +  {0}, // _ADR of the NVDIMM device - need to be filled.
>> +  0,   // Dimm smbios handle index - need to be filled.
>> +  0,   // The unique region index - need to be filled.
>> +  0,   // The SPA range index - need to be filled.
>> +  0,   // The control region index - need to be filled.
>> +  0,   // The region size - need to be filled.
>> +  0,   // The region offset - need to be filled.
>> +  0,   // The region base - need to be filled.
>> +  0,   // The interleave structure index - need to be filled.
>> +  0,   // The interleave ways - need to be filled.
>> +  0,   // NVDIMM flags - need to be filled.
>> +  0,   // Reserved.
>> +};
>> +
>> +EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE NFITTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_STRUCTURE_SIGNATURE,
>> +    0, /* need fill in */
>> +    EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE_REVISION
>> +    ),
>> +  0x00000000, // Reserved
>> +};
>> +
>> +NVDIMM_DATA NvdData[PLATFORM_CPU_MAX_SOCKET] = { 0 };
>> +
>> +EFI_STATUS
>> +AcpiNvdInfoInit (
>> +  IN OUT NVDIMM_INFO *NvdInfoPtr,
>> +  IN     UINTN       NvdId
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  VOID               *Hob;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL || NvdInfoPtr == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  NvdInfoPtr->Enabled = TRUE;
>> +  NvdInfoPtr->PhysId = NvdId;
>> +  NvdInfoPtr->NvdSize = PlatformHob->DimmList.Dimm[NvdId].Info.DimmSize * ONE_GB;
>> +  NvdInfoPtr->VendorId =
>> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[320]);
>> +  NvdInfoPtr->DeviceId =
>> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[192]);
>> +  NvdInfoPtr->RevisionId =
>> +    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[349];
>> +  NvdInfoPtr->SubVendorId =
>> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[194]);
>> +  NvdInfoPtr->SubDeviceId =
>> +    *((UINT16 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[196]);
>> +  NvdInfoPtr->SubRevisionId =
>> +    (UINT16)PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[198];
>> +  NvdInfoPtr->SerialNumber =
>> +    *((UINT32 *)&PlatformHob->DimmList.Dimm[NvdId].SpdData.Data[325]);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiNvdDataInit (
>> +  IN UINTN Socket
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  NVDIMM_INFO        *NvdInfo;
>> +  UINTN              Count;
>> +  VOID               *Hob;
>> +  UINTN              NvdRegionNum, RegionId;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  NvdRegionNum = 0;
>> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +    if (PlatformHob->DramInfo.NvdRegion[Count] != 0
>> +        && (PlatformHob->DramInfo.Socket[Count] == Socket))
>> +    {
>> +      NvdData[Socket].NvdRegionId[NvdRegionNum] = Count;
>> +      NvdRegionNum++;
>> +    }
>> +  }
>> +  if (NvdRegionNum == 0) {
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  NvdData[Socket].NvdRegionNum = NvdRegionNum;
>> +  NvdData[Socket].NvdMode = PlatformHob->DramInfo.NvdimmMode[Socket];
>> +  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
>> +    NvdInfo = &NvdData[Socket].NvdInfo[NVDIMM_SK0];
>> +    NvdInfo->DeviceHandle   =
>> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
>> +      PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
>> +    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
>> +    NvdInfo->RegionOffset   = 0;
>> +    AcpiNvdInfoInit (
>> +      NvdInfo,
>> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
>> +      PLATFORM_NVDIMM_NVD3_DIMM_ID
>> +      );
>> +
>> +    NvdInfo = &NvdData[Socket].NvdInfo[1];
>> +    NvdInfo->DeviceHandle   =
>> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
>> +      PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
>> +    NvdInfo->InterleaveWays = PLATFORM_NVDIMM_HASHED_INTERLEAVE_WAYS;
>> +    NvdInfo->RegionOffset   = PLATFORM_NVDIMM_HASHED_REGION_OFFSET;
>> +    AcpiNvdInfoInit (
>> +      NvdInfo,
>> +      (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
>> +      PLATFORM_NVDIMM_NVD4_DIMM_ID
>> +      );
>> +
>> +    /* Update NvdNum */
>> +    NvdData[Socket].NvdNum = 0;
>> +    for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
>> +      if (NvdData[Socket].NvdInfo[Count].Enabled) {
>> +        NvdData[Socket].NvdNum++;
>> +      }
>> +    }
>> +    return EFI_SUCCESS;
>> +  }
>> +  /* NVDIMM_NON_HASHED */
>> +  NvdData[Socket].NvdNum = 0;
>> +  for (Count = 0; Count < NvdData[Socket].NvdRegionNum; Count++) {
>> +    RegionId = NvdData[Socket].NvdRegionId[Count];
>> +    if (PlatformHob->DramInfo.Base[RegionId] ==
>> +        PLATFORM_NVDIMM_SK0_NHASHED_REGION0 ||
>> +        PlatformHob->DramInfo.Base[RegionId] ==
>> +        PLATFORM_NVDIMM_SK1_NHASHED_REGION0)
>> +    {
>> +      NvdInfo = &NvdData[Socket].NvdInfo[0];
>> +      NvdInfo->DeviceHandle   =
>> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DEVICE_HANDLE :
>> +        PLATFORM_NVDIMM_NVD3_DEVICE_HANDLE;
>> +      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
>> +      NvdInfo->RegionOffset   = 0;
>> +      AcpiNvdInfoInit (
>> +        NvdInfo,
>> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD1_DIMM_ID :
>> +        PLATFORM_NVDIMM_NVD3_DIMM_ID
>> +        );
>> +
>> +    } else if (PlatformHob->DramInfo.Base[RegionId] ==
>> +               PLATFORM_NVDIMM_SK0_NHASHED_REGION1 ||
>> +               PlatformHob->DramInfo.Base[RegionId] ==
>> +               PLATFORM_NVDIMM_SK1_NHASHED_REGION1)
>> +    {
>> +      NvdInfo = &NvdData[Socket].NvdInfo[1];
>> +      NvdInfo->DeviceHandle   =
>> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DEVICE_HANDLE :
>> +        PLATFORM_NVDIMM_NVD4_DEVICE_HANDLE;
>> +      NvdInfo->InterleaveWays = PLATFORM_NVDIMM_NHASHED_INTERLEAVE_WAYS;
>> +      NvdInfo->RegionOffset   = 0;
>> +      AcpiNvdInfoInit (
>> +        NvdInfo,
>> +        (Socket == 0) ? PLATFORM_NVDIMM_NVD2_DIMM_ID :
>> +        PLATFORM_NVDIMM_NVD4_DIMM_ID
>> +        );
>> +    }
>> +  }
>> +  /* Update NvdNum */
>> +  NvdData[Socket].NvdNum = 0;
>> +  for (Count = 0; Count < NVDIMM_NUM_PER_SK; Count++) {
>> +    if (NvdData[Socket].NvdInfo[Count].Enabled) {
>> +      NvdData[Socket].NvdNum++;
>> +    }
>> +  }
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/*
>> + * Fill in SPA structure
>> + */
>> +VOID
>> +AcpiNfitFillSPA (
>> +  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
>> +  IN     UINTN                                                     NvdRegionIndex,
>> +  IN     UINT64                                                    NvdRegionBase,
>> +  IN     UINT64                                                    NvdRegionSize
>> +  )
>> +{
>> +  ASSERT (NfitSpaPointer != NULL);
>> +
>> +  NfitSpaPointer->Flags                            = 0;
>> +  NfitSpaPointer->SPARangeStructureIndex           = NvdRegionIndex;
>> +  NfitSpaPointer->SystemPhysicalAddressRangeBase   = NvdRegionBase;
>> +  NfitSpaPointer->SystemPhysicalAddressRangeLength = NvdRegionSize;
>> +}
>> +
>> +VOID
>> +NfitFillControlRegion (
>> +  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *NfitControlRegionPointer,
>> +  IN     NVDIMM_INFO                                       *NvdInfo,
>> +  IN     UINTN                                             NvdControlRegionIndex
>> +  )
>> +{
>> +  ASSERT (
>> +    NfitControlRegionPointer != NULL
>> +    && NvdInfo != NULL
>> +    );
>> +
>> +  NfitControlRegionPointer->NVDIMMControlRegionStructureIndex =
>> +    NvdControlRegionIndex;
>> +  NfitControlRegionPointer->VendorID = NvdInfo->VendorId;
>> +  NfitControlRegionPointer->DeviceID = NvdInfo->DeviceId;
>> +  NfitControlRegionPointer->RevisionID = NvdInfo->RevisionId;
>> +  NfitControlRegionPointer->SubsystemVendorID = NvdInfo->SubVendorId;
>> +  NfitControlRegionPointer->SubsystemDeviceID = NvdInfo->SubDeviceId;
>> +  NfitControlRegionPointer->SubsystemRevisionID = NvdInfo->SubRevisionId;
>> +  NfitControlRegionPointer->SerialNumber = NvdInfo->SerialNumber;
>> +}
>> +
>> +VOID
>> +NfitFillRegionMapping (
>> +  IN OUT EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer,
>> +  IN     EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer,
>> +  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer,
>> +  IN     NVDIMM_INFO                                               *NvdInfo,
>> +  IN     UINTN                                                     NvdRegionID
>> +  )
>> +{
>> +  ASSERT (
>> +    NfitRegionMappingPointer != NULL
>> +    && NfitRegionMappingPointer != NULL
>> +    && NfitRegionMappingPointer != NULL
>> +    && NfitRegionMappingPointer != NULL
>> +    && NvdInfo != NULL
>> +    );
>> +
>> +  NfitRegionMappingPointer->NVDIMMRegionID = NvdRegionID;
>> +  NfitRegionMappingPointer->NVDIMMPhysicalID = NvdInfo->PhysId;
>> +  NfitRegionMappingPointer->InterleaveWays = NvdInfo->InterleaveWays;
>> +  NfitRegionMappingPointer->RegionOffset = NvdInfo->RegionOffset;
>> +  NfitRegionMappingPointer->NVDIMMRegionSize = NvdInfo->NvdSize;
>> +  NfitRegionMappingPointer->NFITDeviceHandle.DIMMNumber =
>> +    NvdInfo->DeviceHandle & 0x0F;
>> +  NfitRegionMappingPointer->NFITDeviceHandle.MemoryChannelNumber =
>> +    (NvdInfo->DeviceHandle >> 4) & 0x0F;
>> +  NfitRegionMappingPointer->NFITDeviceHandle.MemoryControllerID =
>> +    (NvdInfo->DeviceHandle >> 8) & 0x0F;
>> +  NfitRegionMappingPointer->NFITDeviceHandle.SocketID =
>> +    (NvdInfo->DeviceHandle >> 12) & 0x0F;
>> +  NfitRegionMappingPointer->SPARangeStructureIndex =
>> +    NfitSpaPointer->SPARangeStructureIndex;
>> +  NfitRegionMappingPointer->NVDIMMPhysicalAddressRegionBase =
>> +    NfitSpaPointer->SystemPhysicalAddressRangeBase;
>> +  NfitRegionMappingPointer->NVDIMMControlRegionStructureIndex =
>> +    NfitControlRegionPointer->NVDIMMControlRegionStructureIndex;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiNfitFillTableBySK (
>> +  IN     EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerStart,
>> +  IN OUT EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE **NfitSpaPointerNext,
>> +  IN     UINTN                                                     Socket
>> +  )
>> +{
>> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointer;
>> +  EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE         *NfitControlRegionPointer;
>> +  EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE         *NfitRegionMappingPointer;
>> +  PLATFORM_INFO_HOB                                         *PlatformHob;
>> +  VOID                                                      *Hob;
>> +  UINT64                                                    NvdRegionBase,
>> +                                                            NvdRegionSize;
>> +  UINTN NvdCount, MaxNvdCount, RegionCount;
>> +  UINTN RegionId, NvdRegionIndex, NvdIndex;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL
>> +      || NfitSpaPointerStart == NULL
>> +      || NfitSpaPointerNext == NULL)
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  PlatformHob    = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +  NvdRegionIndex = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdRegionNum;
>> +  NvdIndex       = (Socket == 0) ? 0 : NvdData[NVDIMM_SK0].NvdNum;
>> +  if (NvdData[Socket].NvdMode == NVDIMM_HASHED) {
>> +    /* Table Type 0: SPA Range Structure */
>> +    NfitSpaPointer = NfitSpaPointerStart;
>> +    CopyMem (
>> +      (VOID *)NfitSpaPointer,
>> +      (VOID *)&NfitSPATemplate,
>> +      sizeof (NfitSPATemplate)
>> +      );
>> +    RegionId      = NvdData[Socket].NvdRegionId[0];
>> +    NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
>> +    NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
>> +    NvdRegionIndex++;
>> +    AcpiNfitFillSPA (
>> +      NfitSpaPointer,
>> +      NvdRegionIndex,
>> +      NvdRegionBase,
>> +      NvdRegionSize
>> +      );
>> +
>> +    NfitControlRegionPointer =
>> +      (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
>> +      (NfitSpaPointer + 1);
>> +    for (NvdCount = 0; NvdCount < NVDIMM_NUM_PER_SK; NvdCount++) {
>> +      if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
>> +        continue;
>> +      }
>> +      NvdIndex++;
>> +      /* Table Type 4: NVDIMM Control Region Structure Mark */
>> +      CopyMem (
>> +        (VOID *)NfitControlRegionPointer,
>> +        (VOID *)&NvdimmControlRegionTemplate,
>> +        sizeof (NvdimmControlRegionTemplate)
>> +        );
>> +      NfitFillControlRegion (
>> +        NfitControlRegionPointer,
>> +        &NvdData[Socket].NvdInfo[NvdCount],
>> +        NvdIndex
>> +        );
>> +
>> +      NfitRegionMappingPointer =
>> +        (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
>> +        (NfitControlRegionPointer + 1);
>> +
>> +      /* Table Type 1: NVDIMM Region Mapping Structure */
>> +      CopyMem (
>> +        (VOID *)NfitRegionMappingPointer,
>> +        (VOID *)&NvdimmRegionMappingTemplate,
>> +        sizeof (NvdimmRegionMappingTemplate)
>> +        );
>> +      NfitFillRegionMapping (
>> +        NfitRegionMappingPointer,
>> +        NfitControlRegionPointer,
>> +        NfitSpaPointer,
>> +        &NvdData[Socket].NvdInfo[NvdCount],
>> +        NvdIndex - 1
>> +        );
>> +
>> +      NfitControlRegionPointer =
>> +        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
>> +        (NfitRegionMappingPointer + 1);
>> +    }
>> +    NfitSpaPointer =
>> +      (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
>> +      NfitControlRegionPointer;
>> +  } else { /* NVDIMM_NON_HASHED */
>> +    NfitSpaPointer = NfitSpaPointerStart;
>> +    for (RegionCount = 0; RegionCount < NvdData[Socket].NvdRegionNum;
>> +         RegionCount++)
>> +    {
>> +      /* Table Type 0: SPA Range Structure */
>> +      CopyMem (
>> +        (VOID *)NfitSpaPointer,
>> +        (VOID *)&NfitSPATemplate,
>> +        sizeof (NfitSPATemplate)
>> +        );
>> +      RegionId      = NvdData[Socket].NvdRegionId[RegionCount];
>> +      NvdRegionBase = PlatformHob->DramInfo.Base[RegionId];
>> +      NvdRegionSize = PlatformHob->DramInfo.Size[RegionId];
>> +      NvdRegionIndex++;
>> +      AcpiNfitFillSPA (
>> +        NfitSpaPointer,
>> +        NvdRegionIndex,
>> +        NvdRegionBase,
>> +        NvdRegionSize
>> +        );
>> +
>> +      NfitControlRegionPointer =
>> +        (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
>> +        (NfitSpaPointer + 1);
>> +      NvdCount = ((NvdRegionBase == PLATFORM_NVDIMM_SK0_NHASHED_REGION0) ||
>> +                  (NvdRegionBase == PLATFORM_NVDIMM_SK1_NHASHED_REGION0)) ?
>> +                 0 : PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
>> +      MaxNvdCount = NvdCount + PLATFORM_NVDIMM_NUM_MAX_PER_MCU;
>> +      for (; NvdCount < MaxNvdCount; NvdCount++) {
>> +        if (!NvdData[Socket].NvdInfo[NvdCount].Enabled) {
>> +          continue;
>> +        }
>> +        NvdIndex++;
>> +
>> +        /* Table Type 4: NVDIMM Control Region Structure Mark */
>> +        CopyMem (
>> +          (VOID *)NfitControlRegionPointer,
>> +          (VOID *)&NvdimmControlRegionTemplate,
>> +          sizeof (NvdimmControlRegionTemplate)
>> +          );
>> +        NfitFillControlRegion (
>> +          NfitControlRegionPointer,
>> +          &NvdData[Socket].NvdInfo[NvdCount],
>> +          NvdIndex
>> +          );
>> +
>> +        NfitRegionMappingPointer =
>> +          (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE *)
>> +          (NfitControlRegionPointer + 1);
>> +
>> +        /* Table Type 1: NVDIMM Region Mapping Structure */
>> +        CopyMem (
>> +          (VOID *)NfitRegionMappingPointer,
>> +          (VOID *)&NvdimmRegionMappingTemplate,
>> +          sizeof (NvdimmRegionMappingTemplate)
>> +          );
>> +        NfitFillRegionMapping (
>> +          NfitRegionMappingPointer,
>> +          NfitControlRegionPointer,
>> +          NfitSpaPointer,
>> +          &NvdData[Socket].NvdInfo[NvdCount],
>> +          NvdIndex - 1
>> +          );
>> +
>> +        NfitControlRegionPointer =
>> +          (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE *)
>> +          (NfitRegionMappingPointer + 1);
>> +      }
>> +      NfitSpaPointer =
>> +        (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
>> +        NfitControlRegionPointer;
>> +    }
>> +  }
>> +  /* Update NfitSpaPointerNext */
>> +  *NfitSpaPointerNext = NfitSpaPointer;
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiNfitFillTable (
>> +  IN EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer
>> +  )
>> +{
>> +  EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *NfitSpaPointerNext;
>> +
>> +  if (NfitTablePointer == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  NfitSpaPointerNext = (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE *)
>> +                       (NfitTablePointer + 1);
>> +
>> +  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
>> +    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK0);
>> +  }
>> +
>> +  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
>> +    AcpiNfitFillTableBySK (NfitSpaPointerNext, &NfitSpaPointerNext, NVDIMM_SK1);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/*
>> + * Install NFIT table.
>> + */
>> +EFI_STATUS
>> +AcpiInstallNfitTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *NfitTablePointer;
>> +  EFI_ACPI_TABLE_PROTOCOL                      *AcpiTableProtocol;
>> +  UINTN                                        NfitTableKey  = 0;
>> +  EFI_STATUS                                   Status;
>> +  UINTN                                        Size;
>> +  UINTN                                        NvdRegionNum;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  Status = AcpiNvdDataInit (NVDIMM_SK0);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  Status = AcpiNvdDataInit (NVDIMM_SK1);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  NvdRegionNum = NvdData[NVDIMM_SK0].NvdRegionNum +
>> +                 NvdData[NVDIMM_SK1].NvdRegionNum;
>> +  if (NvdRegionNum == 0) {
>> +    return EFI_INVALID_PARAMETER; /* No NVDIMM Region */
>> +  }
>> +  Size = sizeof (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE);
>> +  if (NvdData[NVDIMM_SK0].NvdRegionNum != 0) {
>> +    Size +=
>> +      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
>> +       NvdData[NVDIMM_SK0].NvdRegionNum) +
>> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
>> +       NvdData[NVDIMM_SK0].NvdNum) +
>> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
>> +       NvdData[NVDIMM_SK0].NvdNum);
>> +  }
>> +  if (NvdData[NVDIMM_SK1].NvdRegionNum != 0) {
>> +    Size +=
>> +      (sizeof (EFI_ACPI_6_3_NFIT_SYSTEM_PHYSICAL_ADDRESS_RANGE_STRUCTURE) *
>> +       NvdData[NVDIMM_SK1].NvdRegionNum) +
>> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_CONTROL_REGION_STRUCTURE) *
>> +       NvdData[NVDIMM_SK1].NvdNum) +
>> +      (sizeof (EFI_ACPI_6_3_NFIT_NVDIMM_REGION_MAPPING_STRUCTURE) *
>> +       NvdData[NVDIMM_SK1].NvdNum);
>> +  }
>> +  NfitTablePointer =
>> +    (EFI_ACPI_6_3_NVDIMM_FIRMWARE_INTERFACE_TABLE *)AllocateZeroPool (Size);
>> +  if (NfitTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +  CopyMem (
>> +    (VOID *)NfitTablePointer,
>> +    (VOID *)&NFITTableHeaderTemplate,
>> +    sizeof (NFITTableHeaderTemplate)
>> +    );
>> +
>> +  NfitTablePointer->Header.Length = Size;
>> +
>> +  Status = AcpiNfitFillTable (NfitTablePointer);
>> +  if (EFI_ERROR (Status)) {
>> +    FreePool ((VOID *)NfitTablePointer);
>> +    return Status;
>> +  }
>> +  AcpiTableChecksum (
>> +    (UINT8 *)NfitTablePointer,
>> +    NfitTablePointer->Header.Length
>> +    );
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)NfitTablePointer,
>> +                                NfitTablePointer->Header.Length,
>> +                                &NfitTableKey
>> +                                );
>> +  if (EFI_ERROR (Status)) {
>> +    FreePool ((VOID *)NfitTablePointer);
>> +  }
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
>> new file mode 100644
>> index 000000000000..296ae57aada0
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPcct.c
>> @@ -0,0 +1,196 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/AcpiPccLib.h>
>> +#include "AcpiPlatform.h"
>> +
>> +EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS PcctSubspaceTemplate = {
>> +  EFI_ACPI_6_3_PCCT_SUBSPACE_TYPE_2_HW_REDUCED_COMMUNICATIONS,
>> +  sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS),
>> +  0,                        // PlatformInterrupt
>> +  0,                        // PlatformInterruptFlags
>> +  0,                        // Reserved
>> +  0,                        // BaseAddress
>> +  0x100,                    // AddressLength
>> +  { 0, 0x20, 0, 0x3, 0x0 }, // DoorbellRegister
>> +  0,                        // DoorbellPreserve
>> +  0x53000040,               // DoorbellWrite
>> +  1,                        // NominalLatency
>> +  1,                        // MaximumPeriodicAccessRate
>> +  1,                        // MinimumRequestTurnaroundTime
>> +  { 0, 0x20, 0, 0x3, 0x0 }, // PlatformInterruptAckRegister
>> +  0,                        // PlatformInterruptAckPreserve
>> +  0x10001,                  // PlatformInterruptAckWrite
>> +};
>> +
>> +EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER PcctTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATIONS_CHANNEL_TABLE_SIGNATURE,
>> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER,
>> +    EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_REVISION
>> +    ),
>> +  EFI_ACPI_6_3_PCCT_FLAGS_PLATFORM_INTERRUPT,
>> +};
>> +
>> +EFI_STATUS
>> +AcpiPcctInit (
>> +  VOID
>> +  )
>> +{
>> +  UINT8  NumberOfSockets;
>> +  UINT8  Socket;
>> +  UINT16 Doorbell;
>> +  UINT16 Subspace;
>> +
>> +  NumberOfSockets = GetNumberOfActiveSockets ();
>> +  Subspace = 0;
>> +
>> +  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
>> +    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
>> +      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
>> +        continue;
>> +      }
>> +      AcpiPccInitSharedMemory (Socket, Doorbell, Subspace);
>> +      AcpiPccUnmaskDoorbellInterrupt (Socket, Doorbell);
>> +
>> +      Subspace++;
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Install PCCT table.
>> +
>> +  Each socket has 16 PCC subspaces corresponding to 16 Mailbox/Doorbell channels
>> +    0 - 7  : PMpro subspaces
>> +    8 - 15 : SMpro subspaces
>> +
>> +  Please note that some SMpro/PMpro Doorbell are reserved for private use.
>> +  The reserved Doorbells are filtered by using the ACPI_PCC_AVAILABLE_DOORBELL_MASK
>> +  and ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS macro.
>> +
>> +**/
>> +EFI_STATUS
>> +AcpiInstallPcctTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS                                               Status;
>> +  EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *PcctTablePointer;
>> +  EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS   *PcctEntryPointer;
>> +  EFI_PHYSICAL_ADDRESS                                     PccSharedMemPointer;
>> +  EFI_ACPI_TABLE_PROTOCOL                                  *AcpiTableProtocol;
>> +  UINTN                                                    PcctTableKey;
>> +  UINT8                                                    NumberOfSockets;
>> +  UINT8                                                    Socket;
>> +  UINT16                                                   Doorbell;
>> +  UINT16                                                   Subspace;
>> +  UINT16                                                   NumberOfSubspaces;
>> +  UINTN                                                    Size;
>> +  UINTN                                                    DoorbellAddress;
>> +
>> +  Subspace = 0;
>> +  NumberOfSockets = GetNumberOfActiveSockets ();
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  NumberOfSubspaces = ACPI_PCC_MAX_SUBPACE_PER_SOCKET * NumberOfSockets;
>> +
>> +  AcpiPccAllocateSharedMemory (&PccSharedMemPointer, NumberOfSubspaces);
>> +  if (PccSharedMemPointer == 0) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
>> +          NumberOfSubspaces * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
>> +
>> +  PcctTablePointer = (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER *)AllocateZeroPool (Size);
>> +  if (PcctTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  PcctEntryPointer = (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS *)
>> +                      ((UINT64)PcctTablePointer + sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER));
>> +
>> +  for (Socket = 0; Socket < NumberOfSockets; Socket++) {
>> +    for (Doorbell = 0; Doorbell < NUMBER_OF_DOORBELLS_PER_SOCKET; Doorbell++ ) {
>> +      if (AcpiPccIsDoorbellReserved (Doorbell + NUMBER_OF_DOORBELLS_PER_SOCKET * Socket)) {
>> +        continue;
>> +      }
>> +
>> +      CopyMem (
>> +        &PcctEntryPointer[Subspace],
>> +        &PcctSubspaceTemplate,
>> +        sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS)
>> +        );
>> +
>> +      PcctEntryPointer[Subspace].BaseAddress = (UINT64)PccSharedMemPointer + ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace;
>> +      PcctEntryPointer[Subspace].AddressLength = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE;
>> +
>> +      DoorbellAddress = MailboxGetDoorbellAddress (Socket, Doorbell);
>> +
>> +      PcctEntryPointer[Subspace].DoorbellRegister.Address = DoorbellAddress + DB_OUT_REG_OFST;
>> +      PcctEntryPointer[Subspace].PlatformInterrupt = MailboxGetDoorbellInterruptNumber (Socket, Doorbell);
>> +      PcctEntryPointer[Subspace].PlatformInterruptAckRegister.Address = DoorbellAddress + DB_STATUS_REG_OFST;
>> +
>> +      if (Doorbell == ACPI_PCC_CPPC_DOORBELL_ID) {
>> +        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_URGENT_CPPC_MESSAGE;
>> +        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_CPPC_NOMINAL_LATENCY_US;
>> +        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US;
>> +      } else {
>> +        PcctEntryPointer[Subspace].DoorbellWrite = MAILBOX_TYPICAL_PCC_MESSAGE;
>> +        PcctEntryPointer[Subspace].NominalLatency = ACPI_PCC_NOMINAL_LATENCY_US;
>> +        PcctEntryPointer[Subspace].MinimumRequestTurnaroundTime = ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US;
>> +      }
>> +      PcctEntryPointer[Subspace].MaximumPeriodicAccessRate = ACPI_PCC_MAX_PERIODIC_ACCESS_RATE;
>> +
>> +      Subspace++;
>> +    }
>> +  }
>> +
>> +  CopyMem (
>> +    PcctTablePointer,
>> +    &PcctTableHeaderTemplate,
>> +    sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER)
>> +    );
>> +
>> +  //
>> +  // Recalculate the size
>> +  //
>> +  Size = sizeof (EFI_ACPI_6_3_PLATFORM_COMMUNICATION_CHANNEL_TABLE_HEADER) +
>> +          Subspace * sizeof (EFI_ACPI_6_3_PCCT_SUBSPACE_2_HW_REDUCED_COMMUNICATIONS);
>> +
>> +  PcctTablePointer->Header.Length = Size;
>> +  AcpiTableChecksum (
>> +    (UINT8 *)PcctTablePointer,
>> +    PcctTablePointer->Header.Length
>> +    );
>> +
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)PcctTablePointer,
>> +                                PcctTablePointer->Header.Length,
>> +                                &PcctTableKey
>> +                                );
>> +  if (EFI_ERROR (Status)) {
>> +    AcpiPccFreeSharedMemory ();
>> +    FreePool ((VOID *)PcctTablePointer);
>> +    return Status;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
>> new file mode 100644
>> index 000000000000..3ed3e98d00d2
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPlatformDxe.c
>> @@ -0,0 +1,178 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "AcpiApei.h"
>> +#include "AcpiPlatform.h"
>> +
>> +STATIC EFI_EVENT mAcpiRegistration = NULL;
>> +
>> +/*
>> + * This GUID must match the FILE_GUID in AcpiTables.inf of each boards
>> + */
>> +STATIC CONST EFI_GUID mAcpiCommonTableFile = { 0xCEFA2AEB, 0x357E, 0x4F48, { 0x80, 0x66, 0xEA, 0x95, 0x08, 0x53, 0x05, 0x6E } } ;
>> +STATIC CONST EFI_GUID mJadeAcpiTableFile = { 0x5addbc13, 0x8634, 0x480c, { 0x9b, 0x94, 0x67, 0x1b, 0x78, 0x55, 0xcd, 0xb8 } };
>> +/**
>> + * Callback called when ACPI Protocol is installed
>> + */
>> +STATIC VOID
>> +AcpiNotificationEvent (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  EFI_STATUS                                   Status;
>> +  EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
>> +
>> +  Status = LocateAndInstallAcpiFromFv (&mAcpiCommonTableFile);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  Status = LocateAndInstallAcpiFromFv (&mJadeAcpiTableFile);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  //
>> +  // Find ACPI table RSD_PTR from the system table.
>> +  //
>> +  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, (VOID **)&Rsdp);
>> +  if (EFI_ERROR (Status)) {
>> +    Status = EfiGetSystemConfigurationTable (&gEfiAcpi10TableGuid, (VOID **)&Rsdp);
>> +  }
>> +
>> +  if (!EFI_ERROR (Status) &&
>> +      Rsdp != NULL &&
>> +      Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION &&
>> +      Rsdp->RsdtAddress != 0)
>> +  {
>> +    // ARM Platforms must set the RSDT address to NULL
>> +    Rsdp->RsdtAddress = 0;
>> +  }
>> +
>> +  DEBUG ((DEBUG_INFO, "[%a:%d]-\n", __FUNCTION__, __LINE__));
>> +}
>> +
>> +VOID
>> +EFIAPI
>> +InstallAcpiOnReadyToBoot (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  Status = AcpiInstallMadtTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Installed MADT table\n"));
>> +  }
>> +
>> +  Status = AcpiInstallPpttTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Installed PPTT table\n"));
>> +  }
>> +
>> +  Status = AcpiInstallSlitTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Installed SLIT table\n"));
>> +  }
>> +
>> +  Status = AcpiInstallSratTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Installed SRAT table\n"));
>> +  }
>> +
>> +  Status = AcpiInstallPcctTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Installed PCCT table\n"));
>> +  }
>> +
>> +  Status = AcpiInstallNfitTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Installed NFIT table\n"));
>> +  }
>> +
>> +  Status = AcpiPopulateBert ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "Populate BERT record\n"));
>> +  }
>> +
>> +  //
>> +  // Close the event, so it will not be signalled again.
>> +  //
>> +  gBS->CloseEvent (Event);
>> +}
>> +
>> +VOID
>> +EFIAPI
>> +UpdateAcpiOnExitBootServices (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +
>> +  Status = AcpiPatchDsdtTable ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "DSDT Table updated!\n"));
>> +  }
>> +
>> +  // Configure ACPI Platform Error Interfaces
>> +  Status = AcpiApeiUpdate ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "APEI Table updated!\n"));
>> +  }
>> +
>> +  // Configure PCC mailbox base address and unmask interrupt
>> +  Status = AcpiPcctInit ();
>> +  if (!EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_INFO, "PCCT Table updated!\n"));
>> +  }
>> +
>> +  //
>> +  // Close the event, so it will not be signalled again.
>> +  //
>> +  gBS->CloseEvent (Event);
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +AcpiPlatformDxeInitialize (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_EVENT  ReadyToBootEvent;
>> +  EFI_EVENT  ExitBootServicesEvent;
>> +  EFI_STATUS Status;
>> +
>> +  EfiCreateProtocolNotifyEvent (
>> +    &gEfiAcpiTableProtocolGuid,
>> +    TPL_CALLBACK,
>> +    AcpiNotificationEvent,
>> +    NULL,
>> +    &mAcpiRegistration
>> +    );
>> +
>> +  Status = gBS->CreateEvent (
>> +                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
>> +                  TPL_CALLBACK,
>> +                  UpdateAcpiOnExitBootServices,
>> +                  NULL,
>> +                  &ExitBootServicesEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  Status = gBS->CreateEventEx (
>> +                  EVT_NOTIFY_SIGNAL,
>> +                  TPL_CALLBACK,
>> +                  InstallAcpiOnReadyToBoot,
>> +                  NULL,
>> +                  &gEfiEventReadyToBootGuid,
>> +                  &ReadyToBootEvent
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
>> new file mode 100644
>> index 000000000000..97adb66beed3
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiPptt.c
>> @@ -0,0 +1,378 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "AcpiPlatform.h"
>> +
>> +EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR PPTTProcessorTemplate = {
>> +  EFI_ACPI_6_3_PPTT_TYPE_PROCESSOR,
>> +  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR),
>> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
>> +  {0}, /* Flags */
>> +  0,   /* Parent */
>> +  0,   /* AcpiProcessorId */
>> +  0    /* NumberOfPrivateResources */
>> +};
>> +
>> +EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE PPTTCacheTemplate = {
>> +  EFI_ACPI_6_3_PPTT_TYPE_CACHE,
>> +  sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE),
>> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
>> +  {0}, /* Flags */
>> +  0,   /* NextLevelOfCache */
>> +  0,   /* Size */
>> +  0,   /* NumberOfSets */
>> +  0,   /* Associativity */
>> +  {0}, /* Attributes */
>> +  0
>> +};
>> +
>> +EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER PPTTTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_STRUCTURE_SIGNATURE,
>> +    0, /* need fill in */
>> +    EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_REVISION
>> +    ),
>> +};
>> +
>> +STATIC EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *PpttTablePointer;
>> +STATIC UINT32                                                  PpttClusterOffset[PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET];
>> +STATIC UINT32                                                  PpttSocketOffset[PLATFORM_CPU_MAX_SOCKET];
>> +STATIC UINT32                                                  PpttRootOffset;
>> +STATIC UINT32                                                  PpttL1DataCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
>> +STATIC UINT32                                                  PpttL1InstructionCacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
>> +STATIC UINT32                                                  PpttL2CacheOffset[PLATFORM_CPU_MAX_NUM_CORES];
>> +STATIC UINT32                                                  PpttSLCCacheOffset[PLATFORM_CPU_MAX_SOCKET];
>> +
>> +UINT32
>> +AcpiPpttProcessorCoreNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 CpuId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
>> +  UINT32                                *ResPointer;
>> +  UINTN                                 ClusterIdPerSocket, CoreIdPerCpm, SocketId;
>> +
>> +  CopyMem (
>> +    PpttProcessorEntryPointer,
>> +    &PPTTProcessorTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
>> +    );
>> +
>> +  ClusterIdPerSocket = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) % PLATFORM_CPU_MAX_CPM;
>> +  SocketId = (CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM) / PLATFORM_CPU_MAX_CPM;
>> +  CoreIdPerCpm = CpuId  % PLATFORM_CPU_NUM_CORES_PER_CPM;
>> +  PpttProcessorEntryPointer->Flags.AcpiProcessorIdValid = 1;
>> +  PpttProcessorEntryPointer->Flags.NodeIsALeaf = 1;
>> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
>> +  PpttProcessorEntryPointer->AcpiProcessorId = (SocketId << PLATFORM_SOCKET_UID_BIT_OFFSET) | (ClusterIdPerSocket << 8) | CoreIdPerCpm;
>> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttClusterOffset[CpuId / PLATFORM_CPU_NUM_CORES_PER_CPM];
>> +  PpttProcessorEntryPointer->NumberOfPrivateResources = 2; /* L1I + L1D */
>> +
>> +  ResPointer = (UINT32 *)((UINT64)EntryPointer +
>> +                          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
>> +  ResPointer[0] = PpttL1InstructionCacheOffset[CpuId];
>> +  ResPointer[1] = PpttL1DataCacheOffset[CpuId];
>> +
>> +  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32);
>> +
>> +  return PpttProcessorEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttClusterNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 ClusterId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
>> +
>> +  PpttClusterOffset[ClusterId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +
>> +  CopyMem (
>> +    PpttProcessorEntryPointer,
>> +    &PPTTProcessorTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
>> +    );
>> +
>> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttSocketOffset[ClusterId / PLATFORM_CPU_MAX_CPM];
>> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
>> +
>> +  return PpttProcessorEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttSocketNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 SocketId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
>> +  UINT32                                *ResPointer;
>> +
>> +  PpttSocketOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +
>> +  CopyMem (
>> +    PpttProcessorEntryPointer,
>> +    &PPTTProcessorTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
>> +    );
>> +
>> +  PpttProcessorEntryPointer->Flags.PhysicalPackage = 1;
>> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
>> +  PpttProcessorEntryPointer->Parent = (UINT32)PpttRootOffset;
>> +
>> +  PpttProcessorEntryPointer->NumberOfPrivateResources = 1;
>> +  ResPointer = (UINT32 *)((UINT64)EntryPointer + sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR));
>> +  ResPointer[0] = PpttSLCCacheOffset[SocketId];
>> +
>> +  PpttProcessorEntryPointer->Length = sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32);
>> +
>> +  return PpttProcessorEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttRootNode (
>> +  VOID *EntryPointer
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = EntryPointer;
>> +
>> +  PpttRootOffset = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +
>> +  CopyMem (
>> +    PpttProcessorEntryPointer,
>> +    &PPTTProcessorTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)
>> +    );
>> +
>> +  PpttProcessorEntryPointer->Flags.IdenticalImplementation = 1;
>> +
>> +  return PpttProcessorEntryPointer->Length;
>> +}
>> +
>> +STATIC VOID
>> +AcpiPpttFillCacheSizeInfo (
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *Node,
>> +  UINT32                            Level
>> +  )
>> +{
>> +  UINT64 CacheCCSIDR;
>> +  UINT32 CacheLineSize;
>> +  UINT32 Count;
>> +
>> +  CacheCCSIDR = ReadCCSIDR (Level);
>> +
>> +  CacheLineSize = 1;
>> +  Count = CCSIDR_LINE_SIZE (CacheCCSIDR) + 4;
>> +  while (Count-- > 0) {
>> +    CacheLineSize *= 2;
>> +  }
>> +
>> +  Node->Flags.LineSizeValid = 1;
>> +  Node->Flags.NumberOfSetsValid = 1;
>> +  Node->Flags.AssociativityValid = 1;
>> +  Node->Flags.SizePropertyValid = 1;
>> +  Node->Flags.CacheTypeValid = 1;
>> +  Node->NumberOfSets = CCSIDR_NUMSETS (CacheCCSIDR) + 1;
>> +  Node->Associativity = CCSIDR_ASSOCIATIVITY (CacheCCSIDR) + 1;
>> +  Node->LineSize = CacheLineSize;
>> +  Node->Size = Node->NumberOfSets *
>> +               Node->Associativity *
>> +               Node->LineSize;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttL1DataCacheNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 CpuId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
>> +
>> +  PpttL1DataCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +  CopyMem (
>> +    PpttCacheEntryPointer,
>> +    &PPTTCacheTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
>> +    );
>> +
>> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
>> +  PpttCacheEntryPointer->Attributes.CacheType = 0x0; /* Data Cache */
>> +  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
>> +
>> +  return PpttCacheEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttL1InstructionCacheNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 CpuId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
>> +
>> +  PpttL1InstructionCacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +  CopyMem (
>> +    PpttCacheEntryPointer,
>> +    &PPTTCacheTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
>> +    );
>> +
>> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 1);
>> +  PpttCacheEntryPointer->Attributes.CacheType = 0x1; /* Instruction Cache */
>> +  PpttCacheEntryPointer->NextLevelOfCache = PpttL2CacheOffset[CpuId];
>> +
>> +  return PpttCacheEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttL2CacheNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 CpuId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
>> +
>> +  PpttL2CacheOffset[CpuId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +  CopyMem (
>> +    PpttCacheEntryPointer,
>> +    &PPTTCacheTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
>> +    );
>> +
>> +  AcpiPpttFillCacheSizeInfo (PpttCacheEntryPointer, 2);
>> +  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
>> +  PpttCacheEntryPointer->NextLevelOfCache = 0;
>> +
>> +  return PpttCacheEntryPointer->Length;
>> +}
>> +
>> +STATIC UINT32
>> +AcpiPpttSLCCacheNode (
>> +  VOID   *EntryPointer,
>> +  UINT32 SocketId
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE *PpttCacheEntryPointer = EntryPointer;
>> +
>> +  PpttSLCCacheOffset[SocketId] = (UINT64)EntryPointer - (UINT64)PpttTablePointer;
>> +  CopyMem (
>> +    PpttCacheEntryPointer,
>> +    &PPTTCacheTemplate,
>> +    sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)
>> +    );
>> +
>> +  PpttCacheEntryPointer->Flags.LineSizeValid = 1;
>> +  PpttCacheEntryPointer->Flags.NumberOfSetsValid = 1;
>> +  PpttCacheEntryPointer->Flags.AssociativityValid = 1;
>> +  PpttCacheEntryPointer->Flags.SizePropertyValid = 1;
>> +  PpttCacheEntryPointer->Flags.CacheTypeValid = 1;
>> +
>> +  PpttCacheEntryPointer->Size = 0x2000000; /* 32 MB */
>> +  PpttCacheEntryPointer->NumberOfSets = 0x400; /* 1024 sets per 1MB HN-F */
>> +
>> +  PpttCacheEntryPointer->Associativity = 0x10; /* 16-way set-associative */
>> +  PpttCacheEntryPointer->LineSize = 0x40; /* 64 bytes */
>> +  PpttCacheEntryPointer->NextLevelOfCache = 0;
>> +
>> +  PpttCacheEntryPointer->Attributes.CacheType = 0x3; /* Unified Cache */
>> +
>> +  return PpttCacheEntryPointer->Length;
>> +}
>> +
>> +/*
>> + *  Install PPTT table.
>> + */
>> +EFI_STATUS
>> +AcpiInstallPpttTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *PpttProcessorEntryPointer = NULL;
>> +  EFI_ACPI_TABLE_PROTOCOL               *AcpiTableProtocol;
>> +  UINTN                                 PpttTableKey  = 0;
>> +  UINTN                                 Count;
>> +  EFI_STATUS                            Status;
>> +  UINTN                                 Size;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Size = sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER) +
>> +          sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) +                                                        /* Root node */
>> +          (PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                                /* SLC node */
>> +          (PLATFORM_CPU_MAX_SOCKET * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + sizeof (UINT32))) +        /* Socket node */
>> +          (PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR)) +     /* Cluster node */
>> +          (PLATFORM_CPU_MAX_NUM_CORES * (sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR) + 2 * sizeof (UINT32))) + /* Core node */
>> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1I node */
>> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE)) +                             /* L1D node */
>> +          (PLATFORM_CPU_MAX_NUM_CORES * sizeof (EFI_ACPI_6_3_PPTT_STRUCTURE_CACHE));                              /* L2 node */
>> +
>> +  PpttTablePointer =
>> +    (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER *)AllocateZeroPool (Size);
>> +  if (PpttTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  PpttProcessorEntryPointer =
>> +    (EFI_ACPI_6_3_PPTT_STRUCTURE_PROCESSOR *)((UINT64)PpttTablePointer +
>> +                                              sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER));
>> +
>> +  Size = 0;
>> +  Size += AcpiPpttRootNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size));
>> +
>> +  for (Count = 0; Count < PLATFORM_CPU_MAX_SOCKET; Count++) {
>> +    Size += AcpiPpttSLCCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +    Size += AcpiPpttSocketNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +  }
>> +
>> +  for (Count = 0; Count < PLATFORM_CPU_MAX_CPM * PLATFORM_CPU_MAX_SOCKET; Count++) {
>> +    Size += AcpiPpttClusterNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +  }
>> +
>> +  for (Count = 0; Count < PLATFORM_CPU_MAX_NUM_CORES; Count++) {
>> +    Size += AcpiPpttL2CacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +    Size += AcpiPpttL1InstructionCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +    Size += AcpiPpttL1DataCacheNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +    Size += AcpiPpttProcessorCoreNode ((VOID *)((UINT64)PpttProcessorEntryPointer + Size), Count);
>> +  }
>> +
>> +  CopyMem (
>> +    PpttTablePointer,
>> +    &PPTTTableHeaderTemplate,
>> +    sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER)
>> +    );
>> +
>> +  Size += sizeof (EFI_ACPI_6_3_PROCESSOR_PROPERTIES_TOPOLOGY_TABLE_HEADER);
>> +  PpttTablePointer->Header.Length = Size;
>> +
>> +  AcpiTableChecksum (
>> +    (UINT8 *)PpttTablePointer,
>> +    PpttTablePointer->Header.Length
>> +    );
>> +
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)PpttTablePointer,
>> +                                PpttTablePointer->Header.Length,
>> +                                &PpttTableKey
>> +                                );
>> +  FreePool ((VOID *)PpttTablePointer);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
>> new file mode 100644
>> index 000000000000..60acdb9dd5db
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSlit.c
>> @@ -0,0 +1,190 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "AcpiPlatform.h"
>> +
>> +#define MAX_NODES_PER_SOCKET          4
>> +#define SELF_DISTANCE                 10
>> +#define REMOTE_DISTANCE               20
>> +
>> +EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER SLITTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE,
>> +    0, /* need fill in */
>> +    EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION
>> +    ),
>> +  0,
>> +};
>> +
>> +VOID
>> +ComputeCoordinatesForNode (
>> +  UINTN Node,
>> +  UINTN *X,
>> +  UINTN *Y
>> +  )
>> +{
>> +  switch (Node) {
>> +  case 0:
>> +    *X = 0;
>> +    *Y = 0;
>> +    break;
>> +  case 1:
>> +    *X = 1;
>> +    *Y = 0;
>> +    break;
>> +  case 2:
>> +    *X = 0;
>> +    *Y = 1;
>> +    break;
>> +  case 3:
>> +    *X = 1;
>> +    *Y = 1;
>> +    break;
>> +  default:
>> +    *X = 0;
>> +    *Y = 0;
>> +    break;
>> +  }
>> +}
>> +
>> +/**
>> +  Compute the distance between between two nodes on socket.
>> +**/
>> +UINT8
>> +ComputeSlitDistanceOnSocket (
>> +  UINTN Node1,
>> +  UINTN Node2
>> +  )
>> +{
>> +  UINTN X1, Y1, X2, Y2;
>> +  UINTN XDistance, YDistance;
>> +
>> +  ComputeCoordinatesForNode (Node1, &X1, &Y1);
>> +  ComputeCoordinatesForNode (Node2, &X2, &Y2);
>> +
>> +  XDistance = ABS ((INTN)(X1 - X2));
>> +  YDistance = ABS ((INTN)(Y1 - Y2));
>> +
>> +  return (UINT8)(XDistance + YDistance + SELF_DISTANCE);
>> +}
>> +
>> +/**
>> +  Compute the distance between between two nodes on
>> +  different sockets.
>> +  Node1 - local socket node number
>> +  Node2 - remote socket node number
>> +**/
>> +UINT8
>> +ComputeSlitDistanceOnRemoteSocket (
>> +  UINTN LocalNode,
>> +  UINTN RemoteNode
>> +  )
>> +{
>> +  UINTN LocalDistance, RemoteDistance;
>> +
>> +  //
>> +  // Mesh forwards traffic between sockets over both CCIX links when going from
>> +  // one quadrant to another. For example, memory access from Node 0 to Node 4
>> +  // results in traffic being split between RCA0 and 1. Hence distance is
>> +  // different only between upper half and lower half of sockets and not
>> +  // between quadrants. Hemisphere configuration is not impacted as there
>> +  // is no upper-half.
>> +  //
>> +  LocalDistance = 0;
>> +  RemoteDistance = 0;
>> +  if (LocalNode >= (MAX_NODES_PER_SOCKET / 2)) {
>> +    LocalDistance = 1;
>> +  }
>> +  if (RemoteNode >= (MAX_NODES_PER_SOCKET / 2)) {
>> +    RemoteDistance = 1;
>> +  }
>> +
>> +  return (UINT8)(LocalDistance + RemoteDistance + REMOTE_DISTANCE);
>> +}
>> +
>> +UINT8
>> +ComputeSlitDistance (
>> +  UINTN Node1,
>> +  UINTN Node2,
>> +  UINTN DomainsPerSocket
>> +  )
>> +{
>> +  UINT8 Distance;
>> +
>> +  Distance = 0;
>> +  if ((Node1 / DomainsPerSocket) == (Node2 / DomainsPerSocket)) {
>> +    Distance = ComputeSlitDistanceOnSocket (
>> +                 Node1 % DomainsPerSocket,
>> +                 Node2 % DomainsPerSocket
>> +                 );
>> +  } else {
>> +    Distance = ComputeSlitDistanceOnRemoteSocket (
>> +                 Node1 % DomainsPerSocket,
>> +                 Node2 % DomainsPerSocket
>> +                 );
>> +  }
>> +
>> +  return Distance;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiInstallSlitTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_ACPI_TABLE_PROTOCOL                                        *AcpiTableProtocol;
>> +  EFI_STATUS                                                     Status;
>> +  UINTN                                                          NumDomain, Count, Count1;
>> +  EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *SlitTablePointer;
>> +  UINT8                                                          *TmpPtr;
>> +  UINTN                                                          SlitTableKey;
>> +  UINTN                                                          NumDomainPerSocket;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  NumDomainPerSocket = CpuGetNumberOfSubNumaRegion ();
>> +  NumDomain = NumDomainPerSocket * GetNumberOfActiveSockets ();
>> +
>> +  SlitTablePointer = (EFI_ACPI_6_3_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER *)
>> +                     AllocateZeroPool (sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain);
>> +  if (SlitTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +  CopyMem ((VOID *)SlitTablePointer, (VOID *)&SLITTableHeaderTemplate, sizeof (SLITTableHeaderTemplate));
>> +  SlitTablePointer->NumberOfSystemLocalities = NumDomain;
>> +  TmpPtr = (UINT8 *)SlitTablePointer + sizeof (SLITTableHeaderTemplate);
>> +  for (Count = 0; Count < NumDomain; Count++) {
>> +    for (Count1 = 0; Count1 < NumDomain; Count1++, TmpPtr++) {
>> +      *TmpPtr = ComputeSlitDistance (Count, Count1, NumDomainPerSocket);
>> +    }
>> +  }
>> +
>> +  SlitTablePointer->Header.Length = sizeof (SLITTableHeaderTemplate) + NumDomain * NumDomain;
>> +
>> +  AcpiTableChecksum (
>> +    (UINT8 *)SlitTablePointer,
>> +    SlitTablePointer->Header.Length
>> +    );
>> +
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)SlitTablePointer,
>> +                                SlitTablePointer->Header.Length,
>> +                                &SlitTableKey
>> +                                );
>> +  FreePool ((VOID *)SlitTablePointer);
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
>> new file mode 100644
>> index 000000000000..5f3b7007623a
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/AcpiPlatformDxe/AcpiSrat.c
>> @@ -0,0 +1,274 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Guid/ArmMpCoreInfo.h>
>> +#include "AcpiPlatform.h"
>> +
>> +EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER SRATTableHeaderTemplate = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE,
>> +    0, /* need fill in */
>> +    EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION
>> +    ),
>> +  0x00000001,
>> +  0x0000000000000000,
>> +};
>> +
>> +EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE GicItsAffinityTemplate = {
>> +  .Type = EFI_ACPI_6_3_GIC_ITS_AFFINITY,
>> +  sizeof (EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE),
>> +  .ProximityDomain = 0, /* ProximityDomain */
>> +  { EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE },
>> +  .ItsId = 0,
>> +};
>> +
>> +STATIC
>> +UINTN
>> +SratCalculateNumMemoryRegion (
>> +  VOID
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  UINTN              Count;
>> +  UINT64             TmpVal;
>> +  VOID               *Hob;
>> +  UINTN              Result;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return 0;
>> +  }
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  Result = 0;
>> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +    TmpVal = PlatformHob->DramInfo.Size[Count];
>> +    if (TmpVal > 0) {
>> +      Result++;
>> +    }
>> +  }
>> +
>> +  return Result;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +SratAddMemAffinity (
>> +  EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *SratMemAffinity
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  UINTN              Count, NumRegion;
>> +  UINT64             RegionSize, RegionBase;
>> +  VOID               *Hob;
>> +  UINTN              ProximityDomain;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  NumRegion = 0;
>> +
>> +  for (Count = 0; Count < PlatformHob->DramInfo.NumRegion; Count++) {
>> +    RegionSize = PlatformHob->DramInfo.Size[Count];
>> +    RegionBase = PlatformHob->DramInfo.Base[Count];
>> +    ProximityDomain = PlatformHob->DramInfo.Node[Count];
>> +    if (RegionSize > 0) {
>> +      ZeroMem ((VOID *)&SratMemAffinity[NumRegion], sizeof (SratMemAffinity[NumRegion]));
>> +      SratMemAffinity[NumRegion].Flags = EFI_ACPI_6_3_MEMORY_ENABLED;
>> +      if (PlatformHob->DramInfo.NvdRegion[Count] != 0) {
>> +        /* Mark NVDIMM-N region as HOT_PLUGGABLE and NON-VOLATILE */
>> +        SratMemAffinity[NumRegion].Flags |= EFI_ACPI_6_3_MEMORY_HOT_PLUGGABLE |
>> +                                            EFI_ACPI_6_3_MEMORY_NONVOLATILE;
>> +      }
>> +      SratMemAffinity[NumRegion].LengthLow =
>> +        (UINT32)(RegionSize & 0xFFFFFFFF);
>> +      SratMemAffinity[NumRegion].LengthHigh =
>> +        (UINT32)((RegionSize & 0xFFFFFFFF00000000ULL) >> 32);
>> +      SratMemAffinity[NumRegion].AddressBaseLow =
>> +        (UINT32)(RegionBase & 0xFFFFFFFF);
>> +      SratMemAffinity[NumRegion].AddressBaseHigh =
>> +        (UINT32)((RegionBase & 0xFFFFFFFF00000000ULL) >> 32);
>> +      SratMemAffinity[NumRegion].ProximityDomain = (UINT32)(ProximityDomain);
>> +      SratMemAffinity[NumRegion].Type = EFI_ACPI_6_3_MEMORY_AFFINITY;
>> +      SratMemAffinity[NumRegion].Length = sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
>> +      NumRegion++;
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +SratAddGiccAffinity (
>> +  EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *SratGiccAffinity
>> +  )
>> +{
>> +  ARM_PROCESSOR_TABLE *ArmProcessorTable;
>> +  ARM_CORE_INFO       *ArmCoreInfoTable;
>> +  UINTN               Count, NumNode, Idx;
>> +  UINT32              AcpiProcessorUid;
>> +  UINT8               Socket;
>> +  UINT8               Cpm;
>> +
>> +  for (Idx = 0; Idx < gST->NumberOfTableEntries; Idx++) {
>> +    if (CompareGuid (&gArmMpCoreInfoGuid, &(gST->ConfigurationTable[Idx].VendorGuid))) {
>> +      ArmProcessorTable = (ARM_PROCESSOR_TABLE *)gST->ConfigurationTable[Idx].VendorTable;
>> +      ArmCoreInfoTable = ArmProcessorTable->ArmCpus;
>> +      break;
>> +    }
>> +  }
>> +
>> +  if (Idx == gST->NumberOfTableEntries) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  Count = 0;
>> +  NumNode = 0;
>> +  while (Count != ArmProcessorTable->NumberOfEntries) {
>> +    for (Idx = 0; Idx < ArmProcessorTable->NumberOfEntries; Idx++ ) {
>> +      Socket = ArmCoreInfoTable[Idx].ClusterId;
>> +      Cpm = (ArmCoreInfoTable[Idx].CoreId >> PLATFORM_CPM_UID_BIT_OFFSET);
>> +      if (CpuGetSubNumNode (Socket, Cpm) != NumNode) {
>> +        /* We add nodes based on ProximityDomain order */
>> +        continue;
>> +      }
>> +      AcpiProcessorUid = (ArmCoreInfoTable[Idx].ClusterId << PLATFORM_SOCKET_UID_BIT_OFFSET) +
>> +                         ArmCoreInfoTable[Idx].CoreId;
>> +      ZeroMem ((VOID *)&SratGiccAffinity[Count], sizeof (SratGiccAffinity[Count]));
>> +      SratGiccAffinity[Count].AcpiProcessorUid = AcpiProcessorUid;
>> +      SratGiccAffinity[Count].Flags = 1;
>> +      SratGiccAffinity[Count].Length = sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
>> +      SratGiccAffinity[Count].Type = EFI_ACPI_6_3_GICC_AFFINITY;
>> +      SratGiccAffinity[Count].ProximityDomain = CpuGetSubNumNode (Socket, Cpm);
>> +      Count++;
>> +    }
>> +    NumNode++;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC UINT32
>> +InstallGicItsAffinity (
>> +  VOID   *EntryPointer,
>> +  UINT32 Index
>> +  )
>> +{
>> +  EFI_ACPI_6_3_GIC_ITS_AFFINITY_STRUCTURE *ItsAffinityEntryPointer = EntryPointer;
>> +  UINTN                                   Size;
>> +
>> +  Size = sizeof (GicItsAffinityTemplate);
>> +  CopyMem (ItsAffinityEntryPointer, &GicItsAffinityTemplate, Size);
>> +  return Size;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +SratAddGicItsAffinity (
>> +  VOID *TmpPtr
>> +  )
>> +{
>> +  UINTN Size = 0;
>> +  UINTN Index;
>> +
>> +  /* Install Gic ITSAffinity */
>> +  if (!IsSlaveSocketPresent ()) {
>> +    for (Index = 0; Index <= 1; Index++) { /* RCA0/1 */
>> +      GicItsAffinityTemplate.ItsId = Index;
>> +      GicItsAffinityTemplate.ProximityDomain = 0;
>> +      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
>> +    }
>> +  }
>> +
>> +  for (Index = SOCKET0_FIRST_RC; Index <= SOCKET0_LAST_RC; Index++) {
>> +    GicItsAffinityTemplate.ItsId = Index;
>> +    GicItsAffinityTemplate.ProximityDomain = 0;
>> +    Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
>> +  }
>> +
>> +  if (IsSlaveSocketActive ()) {
>> +    for (Index = SOCKET1_FIRST_RC; Index <= SOCKET1_LAST_RC; Index++) {
>> +      GicItsAffinityTemplate.ItsId = Index;
>> +      GicItsAffinityTemplate.ProximityDomain = 1;
>> +      Size += InstallGicItsAffinity ((VOID *)((UINT64)TmpPtr + Size), Index);
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +AcpiInstallSratTable (
>> +  VOID
>> +  )
>> +{
>> +  EFI_ACPI_TABLE_PROTOCOL                            *AcpiTableProtocol;
>> +  EFI_STATUS                                         Status;
>> +  EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *SratTablePointer;
>> +  UINT8                                              *TmpPtr;
>> +  UINTN                                              SratTableKey;
>> +  UINTN                                              Size;
>> +
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiAcpiTableProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&AcpiTableProtocol
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Size = sizeof (SRATTableHeaderTemplate) +
>> +         SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE) +
>> +         GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE) +
>> +         ((SOCKET0_LAST_RC - SOCKET0_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate));
>> +  if (IsSlaveSocketActive ()) {
>> +    Size += (SOCKET1_LAST_RC - SOCKET1_FIRST_RC +  1) * sizeof (GicItsAffinityTemplate);
>> +  } else if (!IsSlaveSocketPresent ()) {
>> +    Size += 2 * sizeof (GicItsAffinityTemplate); /* RCA0/1 */
>> +  }
>> +
>> +  SratTablePointer = (EFI_ACPI_6_3_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER *)AllocateZeroPool (Size);
>> +  if (SratTablePointer == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +  CopyMem ((VOID *)SratTablePointer, (VOID *)&SRATTableHeaderTemplate, sizeof (SRATTableHeaderTemplate));
>> +
>> +  TmpPtr = (UINT8 *)SratTablePointer + sizeof (SRATTableHeaderTemplate);
>> +  Status = SratAddMemAffinity ((EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE *)TmpPtr);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  TmpPtr += SratCalculateNumMemoryRegion () * sizeof (EFI_ACPI_6_3_MEMORY_AFFINITY_STRUCTURE);
>> +  Status = SratAddGiccAffinity ((EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE *)TmpPtr);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  TmpPtr += GetNumberOfActiveCores () * sizeof (EFI_ACPI_6_3_GICC_AFFINITY_STRUCTURE);
>> +  SratAddGicItsAffinity ((VOID *)(UINT64)TmpPtr);
>> +  SratTablePointer->Header.Length = Size;
>> +
>> +  AcpiTableChecksum (
>> +    (UINT8 *)SratTablePointer,
>> +    SratTablePointer->Header.Length
>> +    );
>> +
>> +  Status = AcpiTableProtocol->InstallAcpiTable (
>> +                                AcpiTableProtocol,
>> +                                (VOID *)SratTablePointer,
>> +                                SratTablePointer->Header.Length,
>> +                                &SratTableKey
>> +                                );
>> +  FreePool ((VOID *)SratTablePointer);
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
>> new file mode 100755
>> index 000000000000..023509412f04
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S0.asi
>> @@ -0,0 +1,5639 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Device(C000) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x0)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 0, 0xFD, 2}
>> +  }) // Domain 0
>> +}
>> +
>> +Device(C001) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 1, 0xFD, 2}
>> +  }) // Domain 1
>> +}
>> +
>> +Device(C002) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 2, 0xFD, 2}
>> +  }) // Domain 2
>> +}
>> +
>> +Device(C003) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 3, 0xFD, 2}
>> +  }) // Domain 3
>> +}
>> +
>> +Device(C004) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 4, 0xFD, 2}
>> +  }) // Domain 4
>> +}
>> +
>> +Device(C005) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 5, 0xFD, 2}
>> +  }) // Domain 5
>> +}
>> +
>> +Device(C006) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 6, 0xFD, 2}
>> +  }) // Domain 6
>> +}
>> +
>> +Device(C007) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 7, 0xFD, 2}
>> +  }) // Domain 7
>> +}
>> +
>> +Device(C008) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 8, 0xFD, 2}
>> +  }) // Domain 8
>> +}
>> +
>> +Device(C009) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 9, 0xFD, 2}
>> +  }) // Domain 9
>> +}
>> +
>> +Device(C010) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 10, 0xFD, 2}
>> +  }) // Domain 10
>> +}
>> +
>> +Device(C011) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 11, 0xFD, 2}
>> +  }) // Domain 11
>> +}
>> +
>> +Device(C012) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 12, 0xFD, 2}
>> +  }) // Domain 12
>> +}
>> +
>> +Device(C013) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 13, 0xFD, 2}
>> +  }) // Domain 13
>> +}
>> +
>> +Device(C014) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 14, 0xFD, 2}
>> +  }) // Domain 14
>> +}
>> +
>> +Device(C015) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 15, 0xFD, 2}
>> +  }) // Domain 15
>> +}
>> +
>> +Device(C016) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 16, 0xFD, 2}
>> +  }) // Domain 16
>> +}
>> +
>> +Device(C017) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 17, 0xFD, 2}
>> +  }) // Domain 17
>> +}
>> +
>> +Device(C018) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 18, 0xFD, 2}
>> +  }) // Domain 18
>> +}
>> +
>> +Device(C019) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 19, 0xFD, 2}
>> +  }) // Domain 19
>> +}
>> +
>> +Device(C020) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xa00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 20, 0xFD, 2}
>> +  }) // Domain 20
>> +}
>> +
>> +Device(C021) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xa01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 21, 0xFD, 2}
>> +  }) // Domain 21
>> +}
>> +
>> +Device(C022) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xb00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 22, 0xFD, 2}
>> +  }) // Domain 22
>> +}
>> +
>> +Device(C023) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xb01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 23, 0xFD, 2}
>> +  }) // Domain 23
>> +}
>> +
>> +Device(C024) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xc00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 24, 0xFD, 2}
>> +  }) // Domain 24
>> +}
>> +
>> +Device(C025) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xc01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 25, 0xFD, 2}
>> +  }) // Domain 25
>> +}
>> +
>> +Device(C026) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xd00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 26, 0xFD, 2}
>> +  }) // Domain 26
>> +}
>> +
>> +Device(C027) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xd01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 27, 0xFD, 2}
>> +  }) // Domain 27
>> +}
>> +
>> +Device(C028) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xe00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 28, 0xFD, 2}
>> +  }) // Domain 28
>> +}
>> +
>> +Device(C029) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xe01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 29, 0xFD, 2}
>> +  }) // Domain 29
>> +}
>> +
>> +Device(C030) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xf00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 30, 0xFD, 2}
>> +  }) // Domain 30
>> +}
>> +
>> +Device(C031) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0xf01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 31, 0xFD, 2}
>> +  }) // Domain 31
>> +}
>> +
>> +Device(C032) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 32, 0xFD, 2}
>> +  }) // Domain 32
>> +}
>> +
>> +Device(C033) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 33, 0xFD, 2}
>> +  }) // Domain 33
>> +}
>> +
>> +Device(C034) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 34, 0xFD, 2}
>> +  }) // Domain 34
>> +}
>> +
>> +Device(C035) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 35, 0xFD, 2}
>> +  }) // Domain 35
>> +}
>> +
>> +Device(C036) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 36, 0xFD, 2}
>> +  }) // Domain 36
>> +}
>> +
>> +Device(C037) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 37, 0xFD, 2}
>> +  }) // Domain 37
>> +}
>> +
>> +Device(C038) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 38, 0xFD, 2}
>> +  }) // Domain 38
>> +}
>> +
>> +Device(C039) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 39, 0xFD, 2}
>> +  }) // Domain 39
>> +}
>> +
>> +Device(C040) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 40, 0xFD, 2}
>> +  }) // Domain 40
>> +}
>> +
>> +Device(C041) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 41, 0xFD, 2}
>> +  }) // Domain 41
>> +}
>> +
>> +Device(C042) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 42, 0xFD, 2}
>> +  }) // Domain 42
>> +}
>> +
>> +Device(C043) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 2)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 2)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 2)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 2)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 2)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 2)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 43, 0xFD, 2}
>> +  }) // Domain 43
>> +}
>> +
>> +Device(C044) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 44, 0xFD, 2}
>> +  }) // Domain 44
>> +}
>> +
>> +Device(C045) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 45, 0xFD, 2}
>> +  }) // Domain 45
>> +}
>> +
>> +Device(C046) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 46, 0xFD, 2}
>> +  }) // Domain 46
>> +}
>> +
>> +Device(C047) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 47, 0xFD, 2}
>> +  }) // Domain 47
>> +}
>> +
>> +Device(C048) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 48, 0xFD, 2}
>> +  }) // Domain 48
>> +}
>> +
>> +Device(C049) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 49, 0xFD, 2}
>> +  }) // Domain 49
>> +}
>> +
>> +Device(C050) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 50, 0xFD, 2}
>> +  }) // Domain 50
>> +}
>> +
>> +Device(C051) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 2)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 51, 0xFD, 2}
>> +  }) // Domain 51
>> +}
>> +
>> +Device(C052) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 52, 0xFD, 2}
>> +  }) // Domain 52
>> +}
>> +
>> +Device(C053) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 53, 0xFD, 2}
>> +  }) // Domain 53
>> +}
>> +
>> +Device(C054) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 54, 0xFD, 2}
>> +  }) // Domain 54
>> +}
>> +
>> +Device(C055) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 55, 0xFD, 2}
>> +  }) // Domain 5
>> +}
>> +
>> +Device(C056) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 56, 0xFD, 2}
>> +  }) // Domain 56
>> +}
>> +
>> +Device(C057) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 57, 0xFD, 2}
>> +  }) // Domain 57
>> +}
>> +
>> +Device(C058) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 58, 0xFD, 2}
>> +  }) // Domain 58
>> +}
>> +
>> +Device(C059) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 59, 0xFD, 2}
>> +  }) // Domain 59
>> +}
>> +
>> +Device(C060) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 60, 0xFD, 2}
>> +  }) // Domain 60
>> +}
>> +
>> +Device(C061) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 61, 0xFD, 2}
>> +  }) // Domain 61
>> +}
>> +
>> +Device(C062) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 62, 0xFD, 2}
>> +  }) // Domain 62
>> +}
>> +
>> +Device(C063) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x1f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 63, 0xFD, 2}
>> +  }) // Domain 63
>> +}
>> +
>> +Device(C064) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 64, 0xFD, 2}
>> +  }) // Domain 64
>> +}
>> +
>> +Device(C065) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 65, 0xFD, 2}
>> +  }) // Domain 65
>> +}
>> +
>> +Device(C066) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 66, 0xFD, 2}
>> +  }) // Domain 66
>> +}
>> +
>> +Device(C067) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 67, 0xFD, 2}
>> +  }) // Domain 67
>> +}
>> +
>> +Device(C068) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 68, 0xFD, 2}
>> +  }) // Domain 68
>> +}
>> +
>> +Device(C069) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 69, 0xFD, 2}
>> +  }) // Domain 69
>> +}
>> +
>> +Device(C070) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 70, 0xFD, 2}
>> +  }) // Domain 70
>> +}
>> +
>> +Device(C071) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 71, 0xFD, 2}
>> +  }) // Domain 71
>> +}
>> +
>> +Device(C072) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 72, 0xFD, 2}
>> +  }) // Domain 72
>> +}
>> +
>> +Device(C073) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 73, 0xFD, 2}
>> +  }) // Domain 73
>> +}
>> +
>> +Device(C074) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 74, 0xFD, 2}
>> +  }) // Domain 74
>> +}
>> +
>> +Device(C075) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 75, 0xFD, 2}
>> +  }) // Domain 75
>> +}
>> +
>> +Device(C076) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 76, 0xFD, 2}
>> +  }) // Domain 76
>> +}
>> +
>> +Device(C077) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 77, 0xFD, 2}
>> +  }) // Domain 77
>> +}
>> +
>> +Device(C078) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 78, 0xFD, 2}
>> +  }) // Domain 78
>> +}
>> +
>> +Device(C079) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 79, 0xFD, 2}
>> +  }) // Domain 79
>> +}
>> +
>> +Device(C080) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 80, 0xFD, 2}
>> +  }) // Domain 80
>> +}
>> +
>> +Device(C081) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 81, 0xFD, 2}
>> +  }) // Domain 81
>> +}
>> +
>> +Device(C082) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 82, 0xFD, 2}
>> +  }) // Domain 82
>> +}
>> +
>> +Device(C083) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 83, 0xFD, 2}
>> +  }) // Domain 83
>> +}
>> +
>> +Device(C084) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 84, 0xFD, 2}
>> +  }) // Domain 84
>> +}
>> +
>> +Device(C085) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 85, 0xFD, 2}
>> +  }) // Domain 85
>> +}
>> +
>> +Device(C086) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 86, 0xFD, 2}
>> +  }) // Domain 86
>> +}
>> +
>> +Device(C087) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 87, 0xFD, 2}
>> +  }) // Domain 87
>> +}
>> +
>> +Device(C088) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 88, 0xFD, 2}
>> +  }) // Domain 88
>> +}
>> +
>> +Device(C089) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 89, 0xFD, 2}
>> +  }) // Domain 89
>> +}
>> +
>> +Device(C090) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 90, 0xFD, 2}
>> +  }) // Domain 90
>> +}
>> +
>> +Device(C091) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 91, 0xFD, 2}
>> +  }) // Domain 91
>> +}
>> +
>> +Device(C092) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 92, 0xFD, 2}
>> +  }) // Domain 92
>> +}
>> +
>> +Device(C093) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 93, 0xFD, 2}
>> +  }) // Domain 93
>> +}
>> +
>> +Device(C094) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 94, 0xFD, 2}
>> +  }) // Domain 94
>> +}
>> +
>> +Device(C095) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x2f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 95, 0xFD, 2}
>> +  }) // Domain 95
>> +}
>> +
>> +Device(C096) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 96, 0xFD, 2}
>> +  }) // Domain 96
>> +}
>> +
>> +Device(C097) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 97, 0xFD, 2}
>> +  }) // Domain 97
>> +}
>> +
>> +Device(C098) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 98, 0xFD, 2}
>> +  }) // Domain 98
>> +}
>> +
>> +Device(C099) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 99, 0xFD, 2}
>> +  }) // Domain 99
>> +}
>> +
>> +Device(C100) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 100, 0xFD, 2}
>> +  }) // Domain 100
>> +}
>> +
>> +Device(C101) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 101, 0xFD, 2}
>> +  }) // Domain 101
>> +}
>> +
>> +Device(C102) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 102, 0xFD, 2}
>> +  }) // Domain 102
>> +}
>> +
>> +Device(C103) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 103, 0xFD, 2}
>> +  }) // Domain 103
>> +}
>> +
>> +Device(C104) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 104, 0xFD, 2}
>> +  }) // Domain 104
>> +}
>> +
>> +Device(C105) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 105, 0xFD, 2}
>> +  }) // Domain 105
>> +}
>> +
>> +Device(C106) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 106, 0xFD, 2}
>> +  }) // Domain 106
>> +}
>> +
>> +Device(C107) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 107, 0xFD, 2}
>> +  }) // Domain 107
>> +}
>> +
>> +Device(C108) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 108, 0xFD, 2}
>> +  }) // Domain 108
>> +}
>> +
>> +Device(C109) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 109, 0xFD, 2}
>> +  }) // Domain 109
>> +}
>> +
>> +Device(C110) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 110, 0xFD, 2}
>> +  }) // Domain 110
>> +}
>> +
>> +Device(C111) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 111, 0xFD, 2}
>> +  }) // Domain 111
>> +}
>> +
>> +Device(C112) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 112, 0xFD, 2}
>> +  }) // Domain 112
>> +}
>> +
>> +Device(C113) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 113, 0xFD, 2}
>> +  }) // Domain 113
>> +}
>> +
>> +Device(C114) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 114, 0xFD, 2}
>> +  }) // Domain 114
>> +}
>> +
>> +Device(C115) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 115, 0xFD, 2}
>> +  }) // Domain 115
>> +}
>> +
>> +Device(C116) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 116, 0xFD, 2}
>> +  }) // Domain 116
>> +}
>> +
>> +Device(C117) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 117, 0xFD, 2}
>> +  }) // Domain 117
>> +}
>> +
>> +Device(C118) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 118, 0xFD, 2}
>> +  }) // Domain 118
>> +}
>> +
>> +Device(C119) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 119, 0xFD, 2}
>> +  }) // Domain 119
>> +}
>> +
>> +Device(C120) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 120, 0xFD, 2}
>> +  }) // Domain 120
>> +}
>> +
>> +Device(C121) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 121, 0xFD, 2}
>> +  }) // Domain 121
>> +}
>> +
>> +Device(C122) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 122, 0xFD, 2}
>> +  }) // Domain 122
>> +}
>> +
>> +Device(C123) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 123, 0xFD, 2}
>> +  }) // Domain 123
>> +}
>> +
>> +Device(C124) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 124, 0xFD, 2}
>> +  }) // Domain 124
>> +}
>> +
>> +Device(C125) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 125, 0xFD, 2}
>> +  }) // Domain 125
>> +}
>> +
>> +Device(C126) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 126, 0xFD, 2}
>> +  }) // Domain 126
>> +}
>> +
>> +Device(C127) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x3f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 127, 0xFD, 2}
>> +  }) // Domain 127
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
>> new file mode 100755
>> index 000000000000..b3cc7a1b00e4
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU-S1.asi
>> @@ -0,0 +1,5639 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Device(C128) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x000, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x004, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x008, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x00c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x010, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x014, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x050, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x054, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x058, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 128, 0xFD, 2}
>> +  }) // Domain 128
>> +}
>> +
>> +Device(C129) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x080, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x084, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x088, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x08c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x090, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x094, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x0d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 1219, 0xFD, 2}
>> +  }) // Domain 129
>> +}
>> +
>> +Device(C130) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x104, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x114, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x134, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x154, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 130, 0xFD, 2}
>> +  }) // Domain 130
>> +}
>> +
>> +Device(C131) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x184, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x194, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 131, 0xFD, 2}
>> +  }) // Domain 131
>> +}
>> +
>> +Device(C132) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x204, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x214, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x234, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x254, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 132, 0xFD, 2}
>> +  }) // Domain 132
>> +}
>> +
>> +Device(C133) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x284, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x294, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 133, 0xFD, 2}
>> +  }) // Domain 133
>> +}
>> +
>> +Device(C134) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x304, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x314, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x334, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x354, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 134, 0xFD, 2}
>> +  }) // Domain 134
>> +}
>> +
>> +Device(C135) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x384, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x394, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 135, 0xFD, 2}
>> +  }) // Domain 135
>> +}
>> +
>> +Device(C136) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x400, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x404, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x408, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x40c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x410, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x414, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x42c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x434, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x450, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x454, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x458, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 136, 0xFD, 2}
>> +  }) // Domain 136
>> +}
>> +
>> +Device(C137) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x480, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x484, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x488, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x48c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x490, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x494, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x4b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x4d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 137, 0xFD, 2}
>> +  }) // Domain 137
>> +}
>> +
>> +Device(C138) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x500, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x504, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x508, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x50c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x510, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x514, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x52c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x534, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x550, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x554, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x558, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 138, 0xFD, 2}
>> +  }) // Domain 138
>> +}
>> +
>> +Device(C139) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x580, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x584, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x588, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x58c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x590, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x594, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x5b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x5d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 139, 0xFD, 2}
>> +  }) // Domain 139
>> +}
>> +
>> +Device(C140) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x600, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x604, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x608, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x60c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x610, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x614, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x62c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x634, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x650, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x654, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x658, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 140, 0xFD, 2}
>> +  }) // Domain 140
>> +}
>> +
>> +Device(C141) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x680, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x684, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x688, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x68c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x690, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x694, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x6b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x6d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 141, 0xFD, 2}
>> +  }) // Domain 141
>> +}
>> +
>> +Device(C142) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x700, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x704, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x708, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x70c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x710, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x714, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x72c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x734, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x750, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x754, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x758, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 142, 0xFD, 2}
>> +  }) // Domain 142
>> +}
>> +
>> +Device(C143) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x780, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x784, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x788, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x78c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x790, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x794, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x7b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x7d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 143, 0xFD, 2}
>> +  }) // Domain 143
>> +}
>> +
>> +Device(C144) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x800, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x804, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x808, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x80c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x810, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x814, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x82c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x834, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x850, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x854, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x858, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 144, 0xFD, 2}
>> +  }) // Domain 144
>> +}
>> +
>> +Device(C145) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x880, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x884, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x888, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x88c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x890, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x894, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x8b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x8d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 145, 0xFD, 2}
>> +  }) // Domain 145
>> +}
>> +
>> +Device(C146) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x900, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x904, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x908, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x90c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x910, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x914, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x92c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x934, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x950, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x954, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x958, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 146, 0xFD, 2}
>> +  }) // Domain 146
>> +}
>> +
>> +Device(C147) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x980, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x984, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x988, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x98c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x990, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x994, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x9b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x9d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 147, 0xFD, 2}
>> +  }) // Domain 147
>> +}
>> +
>> +Device(C148) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xa34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 148, 0xFD, 2}
>> +  }) // Domain 148
>> +}
>> +
>> +Device(C149) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xa94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xaac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xab4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xad8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 149, 0xFD, 2}
>> +  }) // Domain 149
>> +}
>> +
>> +Device(C150) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xb34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 150, 0xFD, 2}
>> +  }) // Domain 150
>> +}
>> +
>> +Device(C151) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xb94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xbb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xbd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 151, 0xFD, 2}
>> +  }) // Domain 151
>> +}
>> +
>> +Device(C152) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xc34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 152, 0xFD, 2}
>> +  }) // Domain 152
>> +}
>> +
>> +Device(C153) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xc94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xcb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xcd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 153, 0xFD, 2}
>> +  }) // Domain 153
>> +}
>> +
>> +Device(C154) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xd34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 154, 0xFD, 2}
>> +  }) // Domain 154
>> +}
>> +
>> +Device(C155) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xd94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xdb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xdd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 155, 0xFD, 2}
>> +  }) // Domain 155
>> +}
>> +
>> +Device(C156) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xe34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 156, 0xFD, 2}
>> +  }) // Domain 156
>> +}
>> +
>> +Device(C157) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xe94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xeb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xed8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 157, 0xFD, 2}
>> +  }) // Domain 157
>> +}
>> +
>> +Device(C158) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xf34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 158, 0xFD, 2}
>> +  }) // Domain 158
>> +}
>> +
>> +Device(C159) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x10f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xf94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0xfb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0xfd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 159, 0xFD, 2}
>> +  }) // Domain 159
>> +}
>> +
>> +Device(C160) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1000, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1004, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1008, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x100c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1010, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1014, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x102c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1034, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1050, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1054, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1058, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 160, 0xFD, 2}
>> +  }) // Domain 160
>> +}
>> +
>> +Device(C161) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1080, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1084, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1088, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x108c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1090, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1094, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x10b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x10d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 161, 0xFD, 2}
>> +  }) // Domain 161
>> +}
>> +
>> +Device(C162) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1100, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1104, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1108, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x110c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1110, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1114, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x112c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1134, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1150, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1154, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1158, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 162, 0xFD, 2}
>> +  }) // Domain 162
>> +}
>> +
>> +Device(C163) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1180, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1184, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1188, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x118c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1190, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1194, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x11b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x11d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 163, 0xFD, 2}
>> +  }) // Domain 163
>> +}
>> +
>> +Device(C164) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1200, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1204, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1208, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x120c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1210, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1214, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x122c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1234, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1250, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1254, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1258, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 164, 0xFD, 2}
>> +  }) // Domain 164
>> +}
>> +
>> +Device(C165) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1280, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1284, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1288, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x128c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1290, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1294, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x12b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x12d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 165, 0xFD, 2}
>> +  }) // Domain 165
>> +}
>> +
>> +Device(C166) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1300, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1304, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1308, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x130c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1310, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1314, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x132c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1334, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1350, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1354, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1358, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 166, 0xFD, 2}
>> +  }) // Domain 166
>> +}
>> +
>> +Device(C167) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1380, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1384, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1388, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x138c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1390, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1394, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x13b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x13d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 167, 0xFD, 2}
>> +  }) // Domain 167
>> +}
>> +
>> +Device(C168) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1400, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1404, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1408, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x140c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1410, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1414, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x142c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1434, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1450, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1454, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1458, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 168, 0xFD, 2}
>> +  }) // Domain 168
>> +}
>> +
>> +Device(C169) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1480, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1484, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1488, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x148c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1490, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1494, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x14b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x14d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 169, 0xFD, 2}
>> +  }) // Domain 169
>> +}
>> +
>> +Device(C170) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1500, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1504, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1508, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x150c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1510, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1514, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x152c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1534, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1550, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1554, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1558, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 170, 0xFD, 2}
>> +  }) // Domain 170
>> +}
>> +
>> +Device(C171) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1580, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1584, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1588, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x158c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1590, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1594, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x15b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x15d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 171, 0xFD, 2}
>> +  }) // Domain 171
>> +}
>> +
>> +Device(C172) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1600, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1604, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1608, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x160c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1610, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1614, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x162c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1634, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1650, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1654, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1658, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 172, 0xFD, 2}
>> +  }) // Domain 172
>> +}
>> +
>> +Device(C173) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1680, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1684, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1688, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x168c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1690, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1694, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x16b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x16d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 173, 0xFD, 2}
>> +  }) // Domain 173
>> +}
>> +
>> +Device(C174) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1700, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1704, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1708, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x170c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1710, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1714, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x172c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1734, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1750, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1754, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1758, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 174, 0xFD, 2}
>> +  }) // Domain 174
>> +}
>> +
>> +Device(C175) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1780, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1784, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1788, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x178c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1790, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1794, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x17b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x17d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 175, 0xFD, 2}
>> +  }) // Domain 175
>> +}
>> +
>> +Device(C176) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1800, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1804, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1808, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x180c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1810, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1814, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x182c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1834, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1850, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1854, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1858, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 176, 0xFD, 2}
>> +  }) // Domain 176
>> +}
>> +
>> +Device(C177) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1880, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1884, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1888, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x188c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1890, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1894, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x18b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x18d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 177, 0xFD, 2}
>> +  }) // Domain 177
>> +}
>> +
>> +Device(C178) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1900, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1904, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1908, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x190c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1910, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1914, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x192c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1934, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1950, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1954, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1958, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 178, 0xFD, 2}
>> +  }) // Domain 178
>> +}
>> +
>> +Device(C179) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1980, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1984, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1988, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x198c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1990, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1994, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x19b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x19d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 179, 0xFD, 2}
>> +  }) // Domain 179
>> +}
>> +
>> +Device(C180) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1a34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 180, 0xFD, 2}
>> +  }) // Domain 180
>> +}
>> +
>> +Device(C181) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1a94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1aac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1ab4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ad8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 181, 0xFD, 2}
>> +  }) // Domain 181
>> +}
>> +
>> +Device(C182) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1b34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 182, 0xFD, 2}
>> +  }) // Domain 182
>> +}
>> +
>> +Device(C183) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1b94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1bb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1bd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 183, 0xFD, 2}
>> +  }) // Domain 183
>> +}
>> +
>> +Device(C184) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1c34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 184, 0xFD, 2}
>> +  }) // Domain 184
>> +}
>> +
>> +Device(C185) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1c94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1cb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1cd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 185, 0xFD, 2}
>> +  }) // Domain 185
>> +}
>> +
>> +Device(C186) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1d34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 186, 0xFD, 2}
>> +  }) // Domain 186
>> +}
>> +
>> +Device(C187) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1d94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1dac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1db4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1dd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 187, 0xFD, 2}
>> +  }) // Domain 187
>> +}
>> +
>> +Device(C188) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1e34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 188, 0xFD, 2}
>> +  }) // Domain 188
>> +}
>> +
>> +Device(C189) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1e94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1eb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1ed8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 189, 0xFD, 2}
>> +  }) // Domain 189
>> +}
>> +
>> +Device(C190) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1f34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 190, 0xFD, 2}
>> +  }) // Domain 190
>> +}
>> +
>> +Device(C191) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x11f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1f94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x1fb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x1fd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 191, 0xFD, 2}
>> +  }) // Domain 191
>> +}
>> +
>> +Device(C192) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2000, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2004, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2008, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x200c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2010, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2014, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x202c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2034, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2050, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2054, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2058, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 192, 0xFD, 2}
>> +  }) // Domain 192
>> +}
>> +
>> +Device(C193) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2080, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2084, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2088, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x208c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2090, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2094, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x20b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x20d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 193, 0xFD, 2}
>> +  }) // Domain 193
>> +}
>> +
>> +Device(C194) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2100, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2104, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2108, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x210c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2110, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2114, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x212c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2134, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2150, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2154, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2158, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 194, 0xFD, 2}
>> +  }) // Domain 194
>> +}
>> +
>> +Device(C195) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2180, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2184, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2188, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x218c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2190, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2194, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x21b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x21d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 195, 0xFD, 2}
>> +  }) // Domain 195
>> +}
>> +
>> +Device(C196) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2200, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2204, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2208, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x220c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2210, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2214, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x222c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2234, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2250, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2254, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2258, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 196, 0xFD, 2}
>> +  }) // Domain 196
>> +}
>> +
>> +Device(C197) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2280, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2284, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2288, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x228c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2290, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2294, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x22b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x22d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 197, 0xFD, 2}
>> +  }) // Domain 197
>> +}
>> +
>> +Device(C198) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2300, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2304, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2308, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x230c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2310, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2314, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x232c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2334, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2350, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2354, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2358, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 198, 0xFD, 2}
>> +  }) // Domain 198
>> +}
>> +
>> +Device(C199) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2380, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2384, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2388, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x238c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2390, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2394, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x23b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x23d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 199, 0xFD, 2}
>> +  }) // Domain 199
>> +}
>> +
>> +Device(C200) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2400, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2404, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2408, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x240c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2410, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2414, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x242c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2434, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2450, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2454, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2458, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 200, 0xFD, 2}
>> +  }) // Domain 200
>> +}
>> +
>> +Device(C201) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2480, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2484, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2488, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x248c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2490, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2494, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x24b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x24d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 201, 0xFD, 2}
>> +  }) // Domain 201
>> +}
>> +
>> +Device(C202) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2500, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2504, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2508, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x250c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2510, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2514, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x252c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2534, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2550, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2554, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2558, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 202, 0xFD, 2}
>> +  }) // Domain 202
>> +}
>> +
>> +Device(C203) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2580, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2584, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2588, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x258c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2590, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2594, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x25b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x25d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 203, 0xFD, 2}
>> +  }) // Domain 203
>> +}
>> +
>> +Device(C204) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2600, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2604, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2608, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x260c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2610, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2614, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x262c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2634, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2650, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2654, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2658, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 204, 0xFD, 2}
>> +  }) // Domain 204
>> +}
>> +
>> +Device(C205) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2680, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2684, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2688, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x268c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2690, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2694, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x26b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x26d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 205, 0xFD, 2}
>> +  }) // Domain 205
>> +}
>> +
>> +Device(C206) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2700, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2704, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2708, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x270c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2710, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2714, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x272c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2734, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2750, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2754, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2758, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 206, 0xFD, 2}
>> +  }) // Domain 206
>> +}
>> +
>> +Device(C207) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2780, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2784, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2788, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x278c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2790, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2794, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x27b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x27d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 207, 0xFD, 2}
>> +  }) // Domain 207
>> +}
>> +
>> +Device(C208) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2800, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2804, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2808, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x280c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2810, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2814, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x282c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2834, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2850, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2854, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2858, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 208, 0xFD, 2}
>> +  }) // Domain 208
>> +}
>> +
>> +Device(C209) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2880, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2884, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2888, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x288c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2890, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2894, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x28b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x28d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 209, 0xFD, 2}
>> +  }) // Domain 209
>> +}
>> +
>> +Device(C210) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2900, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2904, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2908, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x290c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2910, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2914, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x292c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2934, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2950, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2954, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2958, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 210, 0xFD, 2}
>> +  }) // Domain 210
>> +}
>> +
>> +Device(C211) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2980, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2984, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2988, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x298c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2990, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2994, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29ac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x29b4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x29d8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 211, 0xFD, 2}
>> +  }) // Domain 211
>> +}
>> +
>> +Device(C212) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2a34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 212, 0xFD, 2}
>> +  }) // Domain 212
>> +}
>> +
>> +Device(C213) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2a94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2aac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2ab4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ad8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 213, 0xFD, 2}
>> +  }) // Domain 213
>> +}
>> +
>> +Device(C214) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2b34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 214, 0xFD, 2}
>> +  }) // Domain 214
>> +}
>> +
>> +Device(C215) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2b94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2bb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2bd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 215, 0xFD, 2}
>> +  }) // Domain 215
>> +}
>> +
>> +Device(C216) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2c34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 216, 0xFD, 2}
>> +  }) // Domain 216
>> +}
>> +
>> +Device(C217) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2c94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2cb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2cd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 217, 0xFD, 2}
>> +  }) // Domain 217
>> +}
>> +
>> +Device(C218) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2d34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 218, 0xFD, 2}
>> +  }) // Domain 218
>> +}
>> +
>> +Device(C219) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2d94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2dac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2db4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2dd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 219, 0xFD, 2}
>> +  }) // Domain 219
>> +}
>> +
>> +Device(C220) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2e34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 220, 0xFD, 2}
>> +  }) // Domain 220
>> +}
>> +
>> +Device(C221) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2e94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2eb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2ed8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 221, 0xFD, 2}
>> +  }) // Domain 221
>> +}
>> +
>> +Device(C222) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f00, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f04, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f08, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f0c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f10, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f14, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f2c, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2f34, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f50, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f54, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f58, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 222, 0xFD, 2}
>> +  }) // Domain 222
>> +}
>> +
>> +Device(C223) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x12f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f80, 17)},         // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f84, 17)},         // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f88, 17)},         // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f8c, 17)},         // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f90, 17)},         // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2f94, 17)},         // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fac, 17)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x2fb4, 17)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd0, 17)},         // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd4, 17)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x2fd8, 17)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 223, 0xFD, 2}
>> +  }) // Domain 223
>> +}
>> +
>> +Device(C224) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13000)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3000, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3004, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3008, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x300c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3010, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3014, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x302c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3034, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3050, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3054, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3058, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 224, 0xFD, 2}
>> +  }) // Domain 224
>> +}
>> +
>> +Device(C225) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13001)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3080, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3084, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3088, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x308c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3090, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3094, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x30b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x30d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 225, 0xFD, 2}
>> +  }) // Domain 225
>> +}
>> +
>> +Device(C226) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13100)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3100, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3104, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3108, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x310c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3110, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3114, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x312c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3134, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3150, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3154, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3158, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 226, 0xFD, 2}
>> +  }) // Domain 226
>> +}
>> +
>> +Device(C227) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13101)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3180, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3184, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3188, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x318c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3190, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3194, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x31b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x31d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 227, 0xFD, 2}
>> +  }) // Domain 227
>> +}
>> +
>> +Device(C228) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13200)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3200, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3204, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3208, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x320c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3210, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3214, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x322c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3234, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3250, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3254, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3258, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 228, 0xFD, 2}
>> +  }) // Domain 228
>> +}
>> +
>> +Device(C229) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13201)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3280, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3284, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3288, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x328c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3290, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3294, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x32b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x32d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 229, 0xFD, 2}
>> +  }) // Domain 229
>> +}
>> +
>> +Device(C230) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13300)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3300, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3304, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3308, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x330c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3310, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3314, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x332c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3334, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3350, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3354, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3358, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 230, 0xFD, 2}
>> +  }) // Domain 230
>> +}
>> +
>> +Device(C231) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13301)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3380, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3384, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3388, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x338c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3390, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3394, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x33b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x33d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 231, 0xFD, 2}
>> +  }) // Domain 231
>> +}
>> +
>> +Device(C232) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13400)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3400, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3404, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3408, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x340c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3410, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3414, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x342c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3434, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3450, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3454, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3458, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 232, 0xFD, 2}
>> +  }) // Domain 232
>> +}
>> +
>> +Device(C233) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13401)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3480, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3484, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3488, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x348c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3490, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3494, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x34b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x34d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 233, 0xFD, 2}
>> +  }) // Domain 233
>> +}
>> +
>> +Device(C234) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13500)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3500, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3504, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3508, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x350c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3510, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3514, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x352c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3534, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3550, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3554, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3558, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 234, 0xFD, 2}
>> +  }) // Domain 234
>> +}
>> +
>> +Device(C235) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13501)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3580, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3584, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3588, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x358c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3590, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3594, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x35b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x35d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 235, 0xFD, 2}
>> +  }) // Domain 235
>> +}
>> +
>> +Device(C236) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13600)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3600, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3604, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3608, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x360c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3610, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3614, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x362c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3634, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3650, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3654, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3658, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 236, 0xFD, 2}
>> +  }) // Domain 236
>> +}
>> +
>> +Device(C237) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13601)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3680, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3684, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3688, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x368c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3690, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3694, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x36b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x36d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 237, 0xFD, 2}
>> +  }) // Domain 237
>> +}
>> +
>> +Device(C238) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13700)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3700, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3704, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3708, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x370c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3710, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3714, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x372c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3734, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3750, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3754, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3758, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 238, 0xFD, 2}
>> +  }) // Domain 238
>> +}
>> +
>> +Device(C239) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13701)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3780, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3784, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3788, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x378c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3790, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3794, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x37b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x37d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 239, 0xFD, 2}
>> +  }) // Domain 239
>> +}
>> +
>> +Device(C240) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13800)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3800, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3804, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3808, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x380c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3810, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3814, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x382c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3834, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3850, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3854, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3858, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 240, 0xFD, 2}
>> +  }) // Domain 240
>> +}
>> +
>> +Device(C241) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13801)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3880, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3884, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3888, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x388c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3890, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3894, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x38b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x38d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 241, 0xFD, 2}
>> +  }) // Domain 241
>> +}
>> +
>> +Device(C242) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13900)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3900, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3904, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3908, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x390c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3910, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3914, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x392c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3934, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3950, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3954, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3958, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 242, 0xFD, 2}
>> +  }) // Domain 242
>> +}
>> +
>> +Device(C243) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13901)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3980, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3984, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3988, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x398c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3990, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3994, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39ac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x39b4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x39d8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 243, 0xFD, 2}
>> +  }) // Domain 243
>> +}
>> +
>> +Device(C244) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13a00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3a34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 244, 0xFD, 2}
>> +  }) // Domain 244
>> +}
>> +
>> +Device(C245) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13a01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3a94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3aac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3ab4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ad8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 245, 0xFD, 2}
>> +  }) // Domain 245
>> +}
>> +
>> +Device(C246) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13b00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3b34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 246, 0xFD, 2}
>> +  }) // Domain 246
>> +}
>> +
>> +Device(C247) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13b01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3b94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3bb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3bd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 247, 0xFD, 2}
>> +  }) // Domain 247
>> +}
>> +
>> +Device(C248) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13c00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3c34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 248, 0xFD, 2}
>> +  }) // Domain 248
>> +}
>> +
>> +Device(C249) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13c01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3c94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3cb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3cd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 249, 0xFD, 2}
>> +  }) // Domain 249
>> +}
>> +
>> +Device(C250) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13d00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3d34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 250, 0xFD, 2}
>> +  }) // Domain 250
>> +}
>> +
>> +Device(C251) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13d01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3d94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3dac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3db4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3dd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 251, 0xFD, 2}
>> +  }) // Domain 251
>> +}
>> +
>> +Device(C252) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13e00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3e34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 252, 0xFD, 2}
>> +  }) // Domain 252
>> +}
>> +
>> +Device(C253) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13e01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3e94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3eb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3ed8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 253, 0xFD, 2}
>> +  }) // Domain 253
>> +}
>> +
>> +Device(C254) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13f00)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f00, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f04, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f08, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f0c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f10, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f14, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f2c, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3f34, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f50, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f54, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f58, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package() {
>> +    Package() {5, 0, 254, 0xFD, 2}
>> +  }) // Domain 254
>> +}
>> +
>> +Device(C255) {
>> +  Name(_HID, "ACPI0007")
>> +  Name(_UID, 0x13f01)
>> +
>> +  Method (_LPI, 0, NotSerialized) {
>> +    return(PLPI)
>> +  }
>> +
>> +  Name(PCPC, Package() {
>> +    23,                                                         // NumEntries
>> +    3,                                                          // Revision
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f80, 2)},        // Highest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f84, 2)},        // Nominal Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f88, 2)},        // Lowest Nonlinear Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f8c, 2)},        // Lowest Performance
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f90, 2)},        // Guaranteed Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3f94, 2)},        // Desired Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Minimum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Maximum Performance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Reduction Tolerance Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Time Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Counter Wraparound Time
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fac, 2)},         // Reference Counter Register
>> +    ResourceTemplate(){Register(PCC, 64, 0, 0x3fb4, 2)},         // Delivered Counter Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Performance Limited Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Enable Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Selection Enable
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Autonomous Activity Window Register
>> +    ResourceTemplate(){Register(SystemMemory, 0, 0, 0, 0)},     // Energy Performance Preference Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd0, 2)},        // Reference Performance Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd4, 2)},         // Lowest Frequency Register
>> +    ResourceTemplate(){Register(PCC, 32, 0, 0x3fd8, 2)},         // Nominal Frequency Register
>> +  })
>> +  If (LEqual(CPCE, 0x1)) {
>> +    Method (_CPC, 0, NotSerialized) {
>> +      return(PCPC)
>> +    }
>> +  }
>> +  //Performance State dependency
>> +  Name(_PSD, Package(){
>> +    Package() {5, 0, 255, 0xFD, 2}
>> +  }) // Domain 255
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/CPU.asi b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
>> new file mode 100755
>> index 000000000000..00c09340b957
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/CPU.asi
>> @@ -0,0 +1,127 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Name (CPCE, 1)                       // CPPC Enable
>> +Name (LPIE, 0)                       // LPI Enable
>> +
>> +Method (_OSC, 4, Serialized) {         // _OSC: Operating System Capabilities
>> +  CreateDWordField (Arg3, 0x00, STS0)
>> +  CreateDWordField (Arg3, 0x04, CAP0)
>> +  If (LEqual(Arg0, ToUUID ("0811b06e-4a27-44f9-8d60-3cbbc22e7b48")) /* Platform-wide Capabilities */) {
>> +    If (LNotEqual(Arg1, One)) {
>> +      And(STS0, 0xFFFFFFE0, STS0)
>> +      Or(STS0, 0x0A, STS0)          // Unrecognized Revision, OSC failure
>> +    } Else {
>> +      If (LEqual(And(CAP0, 0x100), 0x100)) {
>> +        And(CAP0, 0xFFFFFEFF, CAP0) // No support for OS Initiated LPI
>> +        And(STS0, 0xFFFFFFE0, STS0)
>> +        Or(STS0, 0x12, STS0)
>> +      }
>> +      If (LEqual(LPIE, 0x1)) {
>> +        Or(CAP0, 0x80, CAP0)        // Support for LPI
>> +      } Else {
>> +        And(CAP0, 0xFFFFFF7F, CAP0) // No support for LPI
>> +      }
>> +      If (LEqual(CPCE, 0x1)) {
>> +        Or(CAP0, 0x40, CAP0)        // Support for CPPCv2
>> +      } Else {
>> +        And(CAP0, 0xFFFFFFBF, CAP0) // No support for CPPCv2
>> +      }
>> +    }
>> +  } Else {
>> +    And(STS0, 0xFFFFFFE0, STS0)
>> +    Or(STS0, 0x06, STS0)            // Unrecognized Revision, Unrecognized UUID
>> +  }
>> +  Return (Arg3)
>> +}
>> +
>> +Name(PLPI, Package() {
>> +  0,                     // Version
>> +  1,                     // Level Index
>> +  2,                     // Count
>> +  // WFI for CPU (NS-WFI)
>> +  Package() {
>> +    1,                   // Min residency (uS)
>> +    1,                   // Wake latency (uS)
>> +    1,                   // Flags
>> +    0,                   // Arch Context Flags
>> +    100,                 // Residency Counter Frequency
>> +    0,                   // No parent state
>> +    ResourceTemplate () {
>> +      // Register Entry method
>> +      Register (FFixedHW,
>> +        0x20,            // Bit Width
>> +        0x00,            // Bit Offset
>> +        0xFFFFFFFF,      // Address
>> +        0x03,            // Access Size
>> +      )
>> +    },
>> +    ResourceTemplate() { // Null Residency Counter
>> +      Register (SystemMemory, 0, 0, 0, 0)
>> +    },
>> +    ResourceTemplate() { // Null Usage Counter
>> +      Register (SystemMemory, 0, 0, 0, 0)
>> +    },
>> +    "Standby",
>> +  },
>> +  // Retention state for CPU (S-WFI)
>> +  Package() {
>> +    2,                   // Min residency (uS)
>> +    2,                   // Wake latency (uS)
>> +    1,                   // Flags
>> +    0,                   // Arch Context Flags
>> +    100,                 // Residency Counter Frequency
>> +    1,                   // Parent node can be in Standby states
>> +    ResourceTemplate () {
>> +      // Register Entry method
>> +      Register (FFixedHW,
>> +        0x20,            // Bit Width
>> +        0x00,            // Bit Offset
>> +        0x00000001,      // Address
>> +        0x03,            // Access Size
>> +      )
>> +    },
>> +    ResourceTemplate() { // Null Residency Counter
>> +      Register (SystemMemory, 0, 0, 0, 0)
>> +    },
>> +    ResourceTemplate() { // Null Usage Counter
>> +      Register (SystemMemory, 0, 0, 0, 0)
>> +    },
>> +    "Standby_ATF"
>> +  },
>> +})
>> +
>> +Device (SYST) {            // System state
>> +  Name(_HID, "ACPI0010")
>> +  Name(_UID, 1)
>> +  Name (_LPI, Package() {
>> +    0,                     // Version
>> +    0,                     // Level Index
>> +    1,                     // Count
>> +    // Retention state for Cluster
>> +    Package() {
>> +      100,               // Min residency (uS)
>> +      100,               // Wake latency (uS)
>> +      1,                   // Flags
>> +      0,                   // Arch Context Flags
>> +      100,                 // Residency Counter Frequency
>> +      0,                   // No Parent State
>> +      0x02000100,          // Integer Entry method
>> +      ResourceTemplate() { // Null Residency Counter
>> +        Register (SystemMemory, 0, 0, 0, 0)
>> +      },
>> +      ResourceTemplate() { // Null Usage Counter
>> +        Register (SystemMemory, 0, 0, 0, 0)
>> +      },
>> +      "Standby"
>> +    },
>> +  })
>> +
>> +  Include ("CPU-S0.asi")
>> +  Include ("CPU-S1.asi")
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
>> new file mode 100755
>> index 000000000000..b9e2da79b5ef
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/Dsdt.asl
>> @@ -0,0 +1,575 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +DefinitionBlock("Dsdt.aml", "DSDT", 0x02, "Ampere", "Jade", 1) {
>> +  //
>> +  // Board Model
>> +  Name(\BDMD, "Jade Board")
>> +  Name(TPMF, 0)  // TPM presence
>> +  Name(AERF, 0)  // PCIe AER Firmware-First
>> +  Scope(\_SB) {
>> +
>> +    Include ("CPU.asi")
>> +    Include ("PMU.asi")
>> +
>> +    //
>> +    // Hardware Monitor
>> +    Device(HM00) {
>> +      Name(_HID, "APMC0D29")
>> +      Name(_UID, "HWM0")
>> +      Name(_DDN, "HWM0")
>> +      Name(_CCA, ONE)
>> +      Name(_STR, Unicode("Hardware Monitor Device"))
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0xF)
>> +      }
>> +      Name (_DSD, Package () {
>> +        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +        Package() {
>> +          Package() {"pcc-channel", 14}
>> +        }
>> +      })
>> +    }
>> +
>> +    //
>> +    // Hardware Monitor
>> +    Device(HM01) {
>> +      Name(_HID, "APMC0D29")
>> +      Name(_UID, "HWM1")
>> +      Name(_DDN, "HWM1")
>> +      Name(_CCA, ONE)
>> +      Name(_STR, Unicode("Hardware Monitor Device"))
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0xF)
>> +      }
>> +      Name (_DSD, Package () {
>> +        ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +        Package() {
>> +          Package() {"pcc-channel", 29}
>> +        }
>> +      })
>> +    }
>> +
>> +    //
>> +    // Hardware Monitor
>> +    Device(HM02) {
>> +      Name(_HID, "AMPC0005")
>> +      Name(_UID, "HWM2")
>> +      Name(_DDN, "HWM2")
>> +      Name(_CCA, ONE)
>> +      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0xF)
>> +      }
>> +      Name(_CRS, ResourceTemplate() {
>> +        QWordMemory (
>> +          ResourceProducer,     // ResourceUsage
>> +          PosDecode,            // Decode
>> +          MinFixed,             // IsMinFixed
>> +          MaxFixed,             // IsMaxFixed
>> +          Cacheable,            // Cacheable
>> +          ReadWrite,            // ReadAndWrite
>> +          0x0000000000000000,   // AddressGranularity - GRA
>> +          0x0000000088900000,   // AddressMinimum - MIN
>> +          0x000000008891FFFF,   // AddressMaximum - MAX
>> +          0x0000000000000000,   // AddressTranslation - TRA
>> +          0x0000000000020000    // RangeLength - LEN
>> +        )
>> +      })
>> +    }
>> +
>> +    //
>> +    // Hardware Monitor
>> +    Device(HM03) {
>> +      Name(_HID, "AMPC0005")
>> +      Name(_UID, "HWM3")
>> +      Name(_DDN, "HWM3")
>> +      Name(_CCA, ONE)
>> +      Name(_STR, Unicode("AC01 SoC Hardware Monitor Device"))
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0xF)
>> +      }
>> +      Name(_CRS, ResourceTemplate() {
>> +        QWordMemory (
>> +          ResourceProducer,     // ResourceUsage
>> +          PosDecode,            // Decode
>> +          MinFixed,             // IsMinFixed
>> +          MaxFixed,             // IsMaxFixed
>> +          Cacheable,            // Cacheable
>> +          ReadWrite,            // ReadAndWrite
>> +          0x0000000000000000,   // AddressGranularity - GRA
>> +          0x0000000088920000,   // AddressMinimum - MIN
>> +          0x000000008893FFFF,   // AddressMaximum - MAX
>> +          0x0000000000000000,   // AddressTranslation - TRA
>> +          0x0000000000020000    // RangeLength - LEN
>> +        )
>> +      })
>> +    }
>> +
>> +    //
>> +    // DesignWare I2C on AHBC bus
>> +    Device(I2C4) {
>> +      Name(_HID, "APMC0D0F")
>> +      Name(_UID, 4)
>> +      Name(_STR, Unicode("Altra I2C Device"))
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0x0f)
>> +      }
>> +      Name(_CCA, ONE)
>> +      Name(_CRS, ResourceTemplate() {
>> +        QWordMemory (
>> +          ResourceProducer,     // ResourceUsage
>> +          PosDecode,            // Decode
>> +          MinFixed,             // IsMinFixed
>> +          MaxFixed,             // IsMaxFixed
>> +          NonCacheable,         // Cacheable
>> +          ReadWrite,            // ReadAndWrite
>> +          0x0000000000000000,   // AddressGranularity - GRA
>> +          0x00001000026B0000,   // AddressMinimum - MIN
>> +          0x00001000026BFFFF,   // AddressMaximum - MAX
>> +          0x0000000000000000,   // AddressTranslation - TRA
>> +          0x0000000000010000    // RangeLength - LEN
>> +        )
>> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 105 }
>> +      })
>> +      Device (IPI) {
>> +        Name(_HID, "AMPC0004")
>> +        Name(_CID, "IPI0001")
>> +        Name(_STR, Unicode("IPMI_SSIF"))
>> +        Name(_UID, 0)
>> +        Name(_CCA, ONE)
>> +        Method(_STA, 0, NotSerialized) {
>> +          Return (0x0f)
>> +        }
>> +        Method(_IFT) {
>> +          Return(0x04) // IPMI SSIF
>> +        }
>> +        Method(_ADR) {
>> +          Return(0x10) // SSIF slave address
>> +        }
>> +        Method(_SRV) {
>> +          Return(0x0200) // IPMI Specification Revision
>> +        }
>> +        Name(_CRS, ResourceTemplate ()
>> +        {
>> +          I2cSerialBus (0x0010, ControllerInitiated, 0x00061A80,
>> +          AddressingMode7Bit, "\\_SB.I2C4",
>> +          0x00, ResourceConsumer,,
>> +          )
>> +        })
>> +      }
>> +      Name(SSCN, Package() { 0x3E2, 0x47D, 0 })
>> +      Name(FMCN, Package() { 0xA4, 0x13F, 0 })
>> +    }
>> +
>> +    //
>> +    // Report APEI Errors to GHES via SCI notification.
>> +    // SCI notification requires one GED and one HED Device
>> +    //     GED = Generic Event Device (ACPI0013)
>> +    //     HED = Hardware Error Device (PNP0C33)
>> +    //
>> +    Device(GED0) {
>> +        Name(_HID, "ACPI0013")
>> +        Name(_UID, Zero)
>> +        Method(_STA) {
>> +          Return (0xF)
>> +        }
>> +        Name(_CRS, ResourceTemplate () {
>> +          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 84 } // GHES
>> +        })
>> +        Method(_EVT, 1, Serialized) {
>> +          Switch (ToInteger(Arg0)) {
>> +            Case (84) { // GHES interrupt
>> +              Notify (HED0, 0x80)
>> +            }
>> +          }
>> +        }
>> +    }
>> +
>> +    // Shutdown button using GED.
>> +    Device(GED1) {
>> +        Name(_HID, "ACPI0013")
>> +        Name(_CID, "ACPI0013")
>> +        Name(_UID, One)
>> +        Method(_STA) {
>> +          Return (0xF)
>> +        }
>> +        Name(_CRS, ResourceTemplate () {
>> +          Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 327 }
>> +        })
>> +        OperationRegion(PDDR, SystemMemory, 0x1000027B0004, 4)
>> +        Field(PDDR, DWordAcc, NoLock, Preserve) {
>> +          STDI, 8
>> +        }
>> +
>> +        OperationRegion(INTE, SystemMemory, 0x1000027B0030, 4)
>> +        Field(INTE, DWordAcc, NoLock, Preserve) {
>> +          STDE, 8
>> +        }
>> +
>> +        OperationRegion(INTT, SystemMemory, 0x1000027B0034, 4)
>> +        Field(INTT, DWordAcc, NoLock, Preserve) {
>> +          TYPE, 8
>> +        }
>> +
>> +        OperationRegion(INTP, SystemMemory, 0x1000027B0038, 4)
>> +        Field(INTP, DWordAcc, NoLock, Preserve) {
>> +          POLA, 8
>> +        }
>> +
>> +        OperationRegion(INTS, SystemMemory, 0x1000027B003c, 4)
>> +        Field(INTS, DWordAcc, NoLock, Preserve) {
>> +          STDS, 8
>> +        }
>> +
>> +        OperationRegion(INTC, SystemMemory, 0x1000027B0040, 4)
>> +        Field(INTC, DWordAcc, NoLock, Preserve) {
>> +          SINT, 8
>> +        }
>> +
>> +        OperationRegion(INTM, SystemMemory, 0x1000027B0044, 4)
>> +        Field(INTM, DWordAcc, NoLock, Preserve) {
>> +          MASK, 8
>> +        }
>> +
>> +        Method(_INI, 0, NotSerialized) {
>> +          // Set level type, low active (shutdown)
>> +          Store (0x00, TYPE)
>> +          Store (0x00, POLA)
>> +          // Set Input type (shutdown)
>> +          Store (0x00, STDI)
>> +          // Enable interrupt (shutdown)
>> +          Store (0x80, STDE)
>> +          // Unmask the interrupt.
>> +          Store (0x00, MASK)
>> +        }
>> +        Method(_EVT, 1, Serialized) {
>> +          Switch (ToInteger(Arg0)) {
>> +            Case (327) {
>> +              if (And (STDS, 0x80)) {
>> +                //Clear the interrupt.
>> +                Store (0x80, SINT)
>> +                // Notify OSPM the power button is pressed
>> +                Notify (\_SB.PWRB, 0x80)
>> +              }
>> +            }
>> +          }
>> +        }
>> +    }
>> +
>> +    // Power button device description
>> +    Device(PWRB) {
>> +        Name(_HID, EISAID("PNP0C0C"))
>> +        Name(_ADR, 0)
>> +        Name(_UID, 0)
>> +        Name(_CCA, ONE)
>> +        Method(_STA, 0, Notserialized) {
>> +            Return (0x0b)
>> +        }
>> +    }
>> +
>> +    //
>> +    // UART0 PL011
>> +    Device(URT0) {
>> +      Name(_HID, "ARMH0011")
>> +      Name(_UID, 0)
>> +      Name(_CCA, ONE)
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0x0f)
>> +      }
>> +      Name(_CRS, ResourceTemplate() {
>> +        QWordMemory (
>> +          ResourceProducer,     // ResourceUsage
>> +          PosDecode,            // Decode
>> +          MinFixed,             // IsMinFixed
>> +          MaxFixed,             // IsMaxFixed
>> +          NonCacheable,         // Cacheable
>> +          ReadWrite,            // ReadAndWrite
>> +          0x0000000000000000,   // AddressGranularity - GRA
>> +          0x0000100002600000,   // AddressMinimum - MIN
>> +          0x0000100002600FFF,   // AddressMaximum - MAX
>> +          0x0000000000000000,   // AddressTranslation - TRA
>> +          0x0000000000001000    // RangeLength - LEN
>> +        )
>> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 98 }
>> +      })
>> +    } // UART0
>> +
>> +    //
>> +    // UART2 PL011
>> +    Device(URT2) {
>> +      Name(_HID, "ARMH0011")
>> +      Name(_UID, 1)
>> +      Name(_CCA, ONE)
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0x0f)
>> +      }
>> +      Name(_CRS, ResourceTemplate() {
>> +        QWordMemory (
>> +          ResourceProducer,     // ResourceUsage
>> +          PosDecode,            // Decode
>> +          MinFixed,             // IsMinFixed
>> +          MaxFixed,             // IsMaxFixed
>> +          NonCacheable,         // Cacheable
>> +          ReadWrite,            // ReadAndWrite
>> +          0x0000000000000000,   // AddressGranularity - GRA
>> +          0x0000100002620000,   // AddressMinimum - MIN
>> +          0x0000100002620FFF,   // AddressMaximum - MAX
>> +          0x0000000000000000,   // AddressTranslation - TRA
>> +          0x0000000000001000    // RangeLength - LEN
>> +        )
>> +        Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 100 }
>> +      })
>> +    } // UART1
>> +
>> +    Device(HED0)
>> +    {
>> +        Name(_HID, EISAID("PNP0C33"))
>> +        Name(_UID, Zero)
>> +    }
>> +
>> +    Device(NVDR) {
>> +      Name(_HID, "ACPI0012")
>> +      Method(_STA, 0, NotSerialized) {
>> +        return (0xf)
>> +      }
>> +      Method (_DSM, 0x4, Serialized) {
>> +        // Not support any functions for now
>> +        Return (Buffer() {0})
>> +      }
>> +      Device (NVD1) {
>> +        Name(_ADR, 0x0330)
>> +        Name(SMRT, Buffer(13) {0})
>> +        CreateDWordField(SMRT, 0, BSTA)
>> +        CreateWordField(SMRT, 4, BHTH)
>> +        CreateWordField(SMRT, 6, BTMP)
>> +        CreateByteField(SMRT, 8, BETH)
>> +        CreateByteField(SMRT, 9, BWTH)
>> +        CreateByteField(SMRT, 10, BNLF)
>> +        OperationRegion(BUF1, SystemMemory, 0x88980000, 16)
>> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
>> +          STAT, 32, //Status
>> +          HLTH, 16, //Module Health
>> +          CTMP, 16, //Module Current Status
>> +          ETHS, 8, //Error Threshold Status
>> +          WTHS, 8, //Warning Threshold Status
>> +          NVLF, 8, //NVM Lifetime
>> +          ,     40 //Reserve
>> +        }
>> +        Method (_DSM, 0x4, Serialized) {
>> +          //Accept only MSF Family type NVDIMM DSM functions
>> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
>> +            //Handle Func 0 query implemented commands
>> +            If(LEqual(Arg2, 0)) {
>> +              //Check revision and returned proper implemented commands
>> +              //Support only health check for now
>> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
>> +            }
>> +            //Handle MSF DSM Func 11 Get Smart and Health Info
>> +            If(LEqual(Arg2, 11)) {
>> +              Store(\_SB.NVDR.NVD1.STAT, BSTA)
>> +              Store(\_SB.NVDR.NVD1.HLTH, BHTH)
>> +              Store(\_SB.NVDR.NVD1.CTMP, BTMP)
>> +              Store(\_SB.NVDR.NVD1.ETHS, BETH)
>> +              Store(\_SB.NVDR.NVD1.WTHS, BWTH)
>> +              Store(\_SB.NVDR.NVD1.NVLF, BNLF)
>> +              Return (SMRT)
>> +            }
>> +          }
>> +          Return (Buffer() {0})
>> +        }
>> +        Method(_STA, 0, NotSerialized) {
>> +          return (0xf)
>> +        }
>> +      }
>> +      Device (NVD2) {
>> +        Name(_ADR, 0x0770)
>> +        Name(SMRT, Buffer(13) {0})
>> +        CreateDWordField(SMRT, 0, BSTA)
>> +        CreateWordField(SMRT, 4, BHTH)
>> +        CreateWordField(SMRT, 6, BTMP)
>> +        CreateByteField(SMRT, 8, BETH)
>> +        CreateByteField(SMRT, 9, BWTH)
>> +        CreateByteField(SMRT, 10, BNLF)
>> +        OperationRegion(BUF1, SystemMemory, 0x88988000, 16)
>> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
>> +          STAT, 32, //Status
>> +          HLTH, 16, //Module Health
>> +          CTMP, 16, //Module Current Status
>> +          ETHS, 8, //Error Threshold Status
>> +          WTHS, 8, //Warning Threshold Status
>> +          NVLF, 8, //NVM Lifetime
>> +          ,     40 //Reserve
>> +        }
>> +        Method (_DSM, 0x4, Serialized) {
>> +          //Accept only MSF Family type NVDIMM DSM functions
>> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
>> +            //Handle Func 0 query implemented commands
>> +            If(LEqual(Arg2, 0)) {
>> +              //Check revision and returned proper implemented commands
>> +              //Support only health check for now
>> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
>> +            }
>> +            //Handle MSF DSM Func 11 Get Smart and Health Info
>> +            If(LEqual(Arg2, 11)) {
>> +              Store(\_SB.NVDR.NVD2.STAT, BSTA)
>> +              Store(\_SB.NVDR.NVD2.HLTH, BHTH)
>> +              Store(\_SB.NVDR.NVD2.CTMP, BTMP)
>> +              Store(\_SB.NVDR.NVD2.ETHS, BETH)
>> +              Store(\_SB.NVDR.NVD2.WTHS, BWTH)
>> +              Store(\_SB.NVDR.NVD2.NVLF, BNLF)
>> +              Return (SMRT)
>> +            }
>> +          }
>> +          Return (Buffer() {0})
>> +        }
>> +        Method(_STA, 0, NotSerialized) {
>> +          return (0xf)
>> +        }
>> +      }
>> +      Device (NVD3) {
>> +        Name(_ADR, 0x1330)
>> +        Name(SMRT, Buffer(13) {0})
>> +        CreateDWordField(SMRT, 0, BSTA)
>> +        CreateWordField(SMRT, 4, BHTH)
>> +        CreateWordField(SMRT, 6, BTMP)
>> +        CreateByteField(SMRT, 8, BETH)
>> +        CreateByteField(SMRT, 9, BWTH)
>> +        CreateByteField(SMRT, 10, BNLF)
>> +        OperationRegion(BUF1, SystemMemory, 0xC0080000, 16)
>> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
>> +          STAT, 32, //Status
>> +          HLTH, 16, //Module Health
>> +          CTMP, 16, //Module Current Status
>> +          ETHS, 8, //Error Threshold Status
>> +          WTHS, 8, //Warning Threshold Status
>> +          NVLF, 8, //NVM Lifetime
>> +          ,     40 //Reserve
>> +        }
>> +        Method (_DSM, 0x4, Serialized) {
>> +          //Accept only MSF Family type NVDIMM DSM functions
>> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
>> +            //Handle Func 0 query implemented commands
>> +            If(LEqual(Arg2, 0)) {
>> +              //Check revision and returned proper implemented commands
>> +              //Support only health check for now
>> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
>> +            }
>> +            //Handle MSF DSM Func 11 Get Smart and Health Info
>> +            If(LEqual(Arg2, 11)) {
>> +              Store(\_SB.NVDR.NVD3.STAT, BSTA)
>> +              Store(\_SB.NVDR.NVD3.HLTH, BHTH)
>> +              Store(\_SB.NVDR.NVD3.CTMP, BTMP)
>> +              Store(\_SB.NVDR.NVD3.ETHS, BETH)
>> +              Store(\_SB.NVDR.NVD3.WTHS, BWTH)
>> +              Store(\_SB.NVDR.NVD3.NVLF, BNLF)
>> +              Return (SMRT)
>> +            }
>> +          }
>> +          Return (Buffer() {0})
>> +        }
>> +        Method(_STA, 0, NotSerialized) {
>> +          return (0xf)
>> +        }
>> +      }
>> +      Device (NVD4) {
>> +        Name(_ADR, 0x1770)
>> +        Name(SMRT, Buffer(13) {0})
>> +        CreateDWordField(SMRT, 0, BSTA)
>> +        CreateWordField(SMRT, 4, BHTH)
>> +        CreateWordField(SMRT, 6, BTMP)
>> +        CreateByteField(SMRT, 8, BETH)
>> +        CreateByteField(SMRT, 9, BWTH)
>> +        CreateByteField(SMRT, 10, BNLF)
>> +        OperationRegion(BUF1, SystemMemory, 0xC0088000, 16)
>> +        Field (BUF1, DWordAcc, NoLock, Preserve) {
>> +          STAT, 32, //Status
>> +          HLTH, 16, //Module Health
>> +          CTMP, 16, //Module Current Status
>> +          ETHS, 8, //Error Threshold Status
>> +          WTHS, 8, //Warning Threshold Status
>> +          NVLF, 8, //NVM Lifetime
>> +          ,     40 //Reserve
>> +        }
>> +        Method (_DSM, 0x4, Serialized) {
>> +          //Accept only MSF Family type NVDIMM DSM functions
>> +          If(LEqual(Arg0, ToUUID ("1ee68b36-d4bd-4a1a-9a16-4f8e53d46e05"))) {
>> +            //Handle Func 0 query implemented commands
>> +            If(LEqual(Arg2, 0)) {
>> +              //Check revision and returned proper implemented commands
>> +              //Support only health check for now
>> +              Return (Buffer() {0x01, 0x08}) //Byte 0: 0x1
>> +            }
>> +            //Handle MSF DSM Func 11 Get Smart and Health Info
>> +            If(LEqual(Arg2, 11)) {
>> +              Store(\_SB.NVDR.NVD4.STAT, BSTA)
>> +              Store(\_SB.NVDR.NVD4.HLTH, BHTH)
>> +              Store(\_SB.NVDR.NVD4.CTMP, BTMP)
>> +              Store(\_SB.NVDR.NVD4.ETHS, BETH)
>> +              Store(\_SB.NVDR.NVD4.WTHS, BWTH)
>> +              Store(\_SB.NVDR.NVD4.NVLF, BNLF)
>> +              Return (SMRT)
>> +            }
>> +          }
>> +          Return (Buffer() {0})
>> +        }
>> +        Method(_STA, 0, NotSerialized) {
>> +          return (0xf)
>> +        }
>> +      }
>> +    }
>> +
>> +    Device (TPM0) {
>> +      //
>> +      // TPM 2.0
>> +      //
>> +
>> +      //
>> +      // TAG for patching TPM2.0 _HID
>> +      //
>> +      Name (_HID, "NNNN0000")
>> +      Name (_CID, "MSFT0101")
>> +      Name (_UID, 0)
>> +
>> +      Name (CRBB, 0x10000000)
>> +      Name (CRBL, 0x10000000)
>> +
>> +      Name (RBUF, ResourceTemplate () {
>> +        Memory32Fixed (ReadWrite, 0x88500000, 0x1000, PCRE)
>> +      })
>> +
>> +      Method (_CRS, 0x0, Serialized) {
>> +        // Declare fields in PCRE
>> +        CreateDWordField(RBUF, ^PCRE._BAS, BASE)
>> +        CreateDWordField(RBUF, ^PCRE._LEN, LENG)
>> +
>> +        // Store updatable values into them
>> +        Store(CRBB, BASE)
>> +        Store(CRBL, LENG)
>> +
>> +        Return (RBUF)
>> +      }
>> +
>> +      Method (_STR,0) {
>> +        Return (Unicode ("TPM 2.0 Device"))
>> +      }
>> +
>> +      Method (_STA, 0) {
>> +        if (TPMF) {
>> +          Return (0x0f)  //Enable resources
>> +        }
>> +        Return (0x0)
>> +      }
>> +    }
>> +
>> +    Include ("PCI-S0.Rca01.asi")
>> +    Include ("PCI-S0.asi")
>> +    Include ("PCI-S1.asi")
>> +    Include ("PCI-PDRC.asi")
>> +  }
>> +} // DSDT
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
>> new file mode 100644
>> index 000000000000..16c00c35e3fe
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-PDRC.asi
>> @@ -0,0 +1,217 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +  // Motherboard resource consumption for PCIE resource reservation
>> +  // as upstream discussion "ACPI namespace details for ARM64"
>> +  Device (PDRC) {
>> +    Name (_HID, EISAID("PNP0C02"))
>> +    Name (_UID, 1)
>> +    // S0 Start here
>> +    Name (PDRS, ResourceTemplate() {
>> +      QWordMemory (              // PCIE0 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00003BFFF0000000,   // AddressMinimum - MIN
>> +        0x00003BFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE1 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00003FFFF0000000,   // AddressMinimum - MIN
>> +        0x00003FFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE2 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000023FFF0000000,   // AddressMinimum - MIN
>> +        0x000023FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE3 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000027FFF0000000,   // AddressMinimum - MIN
>> +        0x000027FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE4 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00002BFFF0000000,   // AddressMinimum - MIN
>> +        0x00002BFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE5 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00002FFFF0000000,   // AddressMinimum - MIN
>> +        0x00002FFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      // S1 Start here
>> +      QWordMemory (              // PCIE6 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00007BFFF0000000,   // AddressMinimum - MIN
>> +        0x00007BFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE7 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00007FFFF0000000,   // AddressMinimum - MIN
>> +        0x00007FFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE8 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000063FFF0000000,   // AddressMinimum - MIN
>> +        0x000063FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIE9 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000067FFF0000000,   // AddressMinimum - MIN
>> +        0x000067FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +      QWordMemory (              // PCIEA 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00006BFFF0000000,   // AddressMinimum - MIN
>> +        0x00006BFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIEB 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00006FFFF0000000,   // AddressMinimum - MIN
>> +        0x00006FFFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIEC 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000033FFF0000000,   // AddressMinimum - MIN
>> +        0x000033FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (              // PCIED 256M CFG region for ECAM
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x000037FFF0000000,   // AddressMinimum - MIN
>> +        0x000037FFFFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    // Current Resource Settings
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (PDRS)
>> +    }
>> +  }
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
>> new file mode 100755
>> index 000000000000..67e1518ebf88
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.Rca01.asi
>> @@ -0,0 +1,681 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +  // PCI0 RCA0
>> +  Device (PCI0) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 12)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI0")
>> +    Name (_STR, Unicode("PCIe 0 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 128/129/130/131 respectively. PCI0 RCA0
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 128},
>> +      Package() {0x0001FFFF, 1, 0, 129},
>> +      Package() {0x0001FFFF, 2, 0, 130},
>> +      Package() {0x0001FFFF, 3, 0, 131},
>> +      Package() {0x0002FFFF, 0, 0, 128},
>> +      Package() {0x0002FFFF, 1, 0, 129},
>> +      Package() {0x0002FFFF, 2, 0, 130},
>> +      Package() {0x0002FFFF, 3, 0, 131},
>> +      Package() {0x0003FFFF, 0, 0, 128},
>> +      Package() {0x0003FFFF, 1, 0, 129},
>> +      Package() {0x0003FFFF, 2, 0, 130},
>> +      Package() {0x0003FFFF, 3, 0, 131},
>> +      Package() {0x0004FFFF, 0, 0, 128},
>> +      Package() {0x0004FFFF, 1, 0, 129},
>> +      Package() {0x0004FFFF, 2, 0, 130},
>> +      Package() {0x0004FFFF, 3, 0, 131},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x33FFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000040000000,   // AddressMinimum - MIN
>> +        0x000000004FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000300000000000,   // AddressMinimum - MIN
>> +        0x000033FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI0 RCA0
>> +
>> +  // PCI1 RCA1
>> +  Device (PCI1) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 13)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI1")
>> +    Name (_STR, Unicode("PCIe 1 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 132/133/134/135 respectively. PCI1 RCA1
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 132},
>> +      Package() {0x0001FFFF, 1, 0, 133},
>> +      Package() {0x0001FFFF, 2, 0, 134},
>> +      Package() {0x0001FFFF, 3, 0, 135},
>> +      Package() {0x0002FFFF, 0, 0, 132},
>> +      Package() {0x0002FFFF, 1, 0, 133},
>> +      Package() {0x0002FFFF, 2, 0, 134},
>> +      Package() {0x0002FFFF, 3, 0, 135},
>> +      Package() {0x0003FFFF, 0, 0, 132},
>> +      Package() {0x0003FFFF, 1, 0, 133},
>> +      Package() {0x0003FFFF, 2, 0, 134},
>> +      Package() {0x0003FFFF, 3, 0, 135},
>> +      Package() {0x0004FFFF, 0, 0, 132},
>> +      Package() {0x0004FFFF, 1, 0, 133},
>> +      Package() {0x0004FFFF, 2, 0, 134},
>> +      Package() {0x0004FFFF, 3, 0, 135},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x37FFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000050000000,   // AddressMinimum - MIN
>> +        0x000000005FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000010000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        Cacheable,            // Cacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000340000000000,   // AddressMinimum - MIN
>> +        0x000037FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI1 RCA1
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
>> new file mode 100755
>> index 000000000000..7c05c6768a0e
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S0.asi
>> @@ -0,0 +1,2078 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +  // PCI2 RCA2
>> +  Device (PCI2) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 1)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI2")
>> +    Name (_STR, Unicode("PCIe 2 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 136/137/138/139 respectively. PCI2 RCA2
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 136},
>> +      Package() {0x0001FFFF, 1, 0, 137},
>> +      Package() {0x0001FFFF, 2, 0, 138},
>> +      Package() {0x0001FFFF, 3, 0, 139},
>> +      Package() {0x0002FFFF, 0, 0, 136},
>> +      Package() {0x0002FFFF, 1, 0, 137},
>> +      Package() {0x0002FFFF, 2, 0, 138},
>> +      Package() {0x0002FFFF, 3, 0, 139},
>> +      Package() {0x0003FFFF, 0, 0, 136},
>> +      Package() {0x0003FFFF, 1, 0, 137},
>> +      Package() {0x0003FFFF, 2, 0, 138},
>> +      Package() {0x0003FFFF, 3, 0, 139},
>> +      Package() {0x0004FFFF, 0, 0, 136},
>> +      Package() {0x0004FFFF, 1, 0, 137},
>> +      Package() {0x0004FFFF, 2, 0, 138},
>> +      Package() {0x0004FFFF, 3, 0, 139},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x3BFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE80000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000030000000,   // AddressMinimum - MIN
>> +        0x0000000037FFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000380000000000,   // AddressMinimum - MIN
>> +        0x00003BFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP, 0) // PCI _OSC Support Field value
>> +    Name (CTRL, 0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3,0,CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI2 RCA2
>> +
>> +  // PCI3 RCA3
>> +  Device (PCI3) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 0)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI3")
>> +    Name (_STR, Unicode("PCIe 3 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 140/141/142/143 respectively. PCI3 RCA3
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 140},
>> +      Package() {0x0001FFFF, 1, 0, 141},
>> +      Package() {0x0001FFFF, 2, 0, 142},
>> +      Package() {0x0001FFFF, 3, 0, 143},
>> +      Package() {0x0002FFFF, 0, 0, 140},
>> +      Package() {0x0002FFFF, 1, 0, 141},
>> +      Package() {0x0002FFFF, 2, 0, 142},
>> +      Package() {0x0002FFFF, 3, 0, 143},
>> +      Package() {0x0003FFFF, 0, 0, 140},
>> +      Package() {0x0003FFFF, 1, 0, 141},
>> +      Package() {0x0003FFFF, 2, 0, 142},
>> +      Package() {0x0003FFFF, 3, 0, 143},
>> +      Package() {0x0004FFFF, 0, 0, 140},
>> +      Package() {0x0004FFFF, 1, 0, 141},
>> +      Package() {0x0004FFFF, 2, 0, 142},
>> +      Package() {0x0004FFFF, 3, 0, 143},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x3FFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to Return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE00000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000038000000,   // AddressMinimum - MIN
>> +        0x000000003FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00003C0000000000,   // AddressMinimum - MIN
>> +        0x00003FFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP, 0) // PCI _OSC Support Field value
>> +    Name (CTRL, 0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI3 RCA3
>> +
>> +  // PCI4 RCB0
>> +  Device (PCI4) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 2)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI4")
>> +    Name (_STR, Unicode("PCIe 4 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 144/145/146/147 respectively. PCI4 RCB0
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 144},
>> +      Package() {0x0001FFFF, 1, 0, 145},
>> +      Package() {0x0001FFFF, 2, 0, 146},
>> +      Package() {0x0001FFFF, 3, 0, 147},
>> +      Package() {0x0002FFFF, 0, 0, 144},
>> +      Package() {0x0002FFFF, 1, 0, 145},
>> +      Package() {0x0002FFFF, 2, 0, 146},
>> +      Package() {0x0002FFFF, 3, 0, 147},
>> +      Package() {0x0003FFFF, 0, 0, 144},
>> +      Package() {0x0003FFFF, 1, 0, 145},
>> +      Package() {0x0003FFFF, 2, 0, 146},
>> +      Package() {0x0003FFFF, 3, 0, 147},
>> +      Package() {0x0004FFFF, 0, 0, 144},
>> +      Package() {0x0004FFFF, 1, 0, 145},
>> +      Package() {0x0004FFFF, 2, 0, 146},
>> +      Package() {0x0004FFFF, 3, 0, 147},
>> +      Package() {0x0005FFFF, 0, 0, 144},
>> +      Package() {0x0005FFFF, 1, 0, 145},
>> +      Package() {0x0005FFFF, 2, 0, 146},
>> +      Package() {0x0005FFFF, 3, 0, 147},
>> +      Package() {0x0006FFFF, 0, 0, 144},
>> +      Package() {0x0006FFFF, 1, 0, 145},
>> +      Package() {0x0006FFFF, 2, 0, 146},
>> +      Package() {0x0006FFFF, 3, 0, 147},
>> +      Package() {0x0007FFFF, 0, 0, 144},
>> +      Package() {0x0007FFFF, 1, 0, 145},
>> +      Package() {0x0007FFFF, 2, 0, 146},
>> +      Package() {0x0007FFFF, 3, 0, 147},
>> +      Package() {0x0008FFFF, 0, 0, 144},
>> +      Package() {0x0008FFFF, 1, 0, 145},
>> +      Package() {0x0008FFFF, 2, 0, 146},
>> +      Package() {0x0008FFFF, 3, 0, 147},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x23FFF0000000)
>> +    }
>> +
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FEC0000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000001000000,   // AddressMinimum - MIN
>> +        0x0000000007FFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000007000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000200000000000,   // AddressMinimum - MIN
>> +        0x000023FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2))
>> +        {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI4 RCB0
>> +
>> +  // PCI5 RCB1
>> +  Device (PCI5) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID,"PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 3)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI5")
>> +    Name (_STR, Unicode("PCIe 5 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 148/149/150/151 respectively. PCI5 RCB1
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 148},
>> +      Package() {0x0001FFFF, 1, 0, 149},
>> +      Package() {0x0001FFFF, 2, 0, 150},
>> +      Package() {0x0001FFFF, 3, 0, 151},
>> +      Package() {0x0002FFFF, 0, 0, 148},
>> +      Package() {0x0002FFFF, 1, 0, 149},
>> +      Package() {0x0002FFFF, 2, 0, 150},
>> +      Package() {0x0002FFFF, 3, 0, 151},
>> +      Package() {0x0003FFFF, 0, 0, 148},
>> +      Package() {0x0003FFFF, 1, 0, 149},
>> +      Package() {0x0003FFFF, 2, 0, 150},
>> +      Package() {0x0003FFFF, 3, 0, 151},
>> +      Package() {0x0004FFFF, 0, 0, 148},
>> +      Package() {0x0004FFFF, 1, 0, 149},
>> +      Package() {0x0004FFFF, 2, 0, 150},
>> +      Package() {0x0004FFFF, 3, 0, 151},
>> +      Package() {0x0005FFFF, 0, 0, 148},
>> +      Package() {0x0005FFFF, 1, 0, 149},
>> +      Package() {0x0005FFFF, 2, 0, 150},
>> +      Package() {0x0005FFFF, 3, 0, 151},
>> +      Package() {0x0006FFFF, 0, 0, 148},
>> +      Package() {0x0006FFFF, 1, 0, 149},
>> +      Package() {0x0006FFFF, 2, 0, 150},
>> +      Package() {0x0006FFFF, 3, 0, 151},
>> +      Package() {0x0007FFFF, 0, 0, 148},
>> +      Package() {0x0007FFFF, 1, 0, 149},
>> +      Package() {0x0007FFFF, 2, 0, 150},
>> +      Package() {0x0007FFFF, 3, 0, 151},
>> +      Package() {0x0008FFFF, 0, 0, 148},
>> +      Package() {0x0008FFFF, 1, 0, 149},
>> +      Package() {0x0008FFFF, 2, 0, 150},
>> +      Package() {0x0008FFFF, 3, 0, 151},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x27FFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FF00000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000008000000,   // AddressMinimum - MIN
>> +        0x000000000FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000240000000000,   // AddressMinimum - MIN
>> +        0x000027FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP, 0) // PCI _OSC Support Field value
>> +    Name (CTRL, 0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +            Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +            Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2))
>> +        {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI5 RCB1
>> +
>> +
>> +  // PCI6 RCB2
>> +  Device (PCI6) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID,"PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID,"PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 4)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI6")
>> +    Name (_STR, Unicode("PCIe 6 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 152/153/154/155 respectively. PCI6 RCB2
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 152},
>> +      Package() {0x0001FFFF, 1, 0, 153},
>> +      Package() {0x0001FFFF, 2, 0, 154},
>> +      Package() {0x0001FFFF, 3, 0, 155},
>> +      Package() {0x0002FFFF, 0, 0, 152},
>> +      Package() {0x0002FFFF, 1, 0, 153},
>> +      Package() {0x0002FFFF, 2, 0, 154},
>> +      Package() {0x0002FFFF, 3, 0, 155},
>> +      Package() {0x0003FFFF, 0, 0, 152},
>> +      Package() {0x0003FFFF, 1, 0, 153},
>> +      Package() {0x0003FFFF, 2, 0, 154},
>> +      Package() {0x0003FFFF, 3, 0, 155},
>> +      Package() {0x0004FFFF, 0, 0, 152},
>> +      Package() {0x0004FFFF, 1, 0, 153},
>> +      Package() {0x0004FFFF, 2, 0, 154},
>> +      Package() {0x0004FFFF, 3, 0, 155},
>> +      Package() {0x0005FFFF, 0, 0, 152},
>> +      Package() {0x0005FFFF, 1, 0, 153},
>> +      Package() {0x0005FFFF, 2, 0, 154},
>> +      Package() {0x0005FFFF, 3, 0, 155},
>> +      Package() {0x0006FFFF, 0, 0, 152},
>> +      Package() {0x0006FFFF, 1, 0, 153},
>> +      Package() {0x0006FFFF, 2, 0, 154},
>> +      Package() {0x0006FFFF, 3, 0, 155},
>> +      Package() {0x0007FFFF, 0, 0, 152},
>> +      Package() {0x0007FFFF, 1, 0, 153},
>> +      Package() {0x0007FFFF, 2, 0, 154},
>> +      Package() {0x0007FFFF, 3, 0, 155},
>> +      Package() {0x0008FFFF, 0, 0, 152},
>> +      Package() {0x0008FFFF, 1, 0, 153},
>> +      Package() {0x0008FFFF, 2, 0, 154},
>> +      Package() {0x0008FFFF, 3, 0, 155},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x2BFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000010000000,   // AddressMinimum - MIN
>> +        0x0000000017FFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000280000000000,   // AddressMinimum - MIN
>> +        0x00002BFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3,0,CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3,4,CDW2)
>> +        CreateDWordField (Arg3,8,CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2,SUPP)
>> +        Store (CDW3,CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL,0x1E,CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1,One)) {
>> +          Or (CDW1,0x08,CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3,CTRL)) {
>> +          Or (CDW1,0x10,CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL,CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1,4,CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI6 RCB2
>> +
>> +  // PCI7 RCB3
>> +  Device (PCI7) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID,"PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID,"PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 5)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCI7")
>> +    Name (_STR, Unicode("PCIe 7 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 156/157/158/159 respectively. PCI7 RCB3
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 156},
>> +      Package() {0x0001FFFF, 1, 0, 157},
>> +      Package() {0x0001FFFF, 2, 0, 158},
>> +      Package() {0x0001FFFF, 3, 0, 159},
>> +      Package() {0x0002FFFF, 0, 0, 156},
>> +      Package() {0x0002FFFF, 1, 0, 157},
>> +      Package() {0x0002FFFF, 2, 0, 158},
>> +      Package() {0x0002FFFF, 3, 0, 159},
>> +      Package() {0x0003FFFF, 0, 0, 156},
>> +      Package() {0x0003FFFF, 1, 0, 157},
>> +      Package() {0x0003FFFF, 2, 0, 158},
>> +      Package() {0x0003FFFF, 3, 0, 159},
>> +      Package() {0x0004FFFF, 0, 0, 156},
>> +      Package() {0x0004FFFF, 1, 0, 157},
>> +      Package() {0x0004FFFF, 2, 0, 158},
>> +      Package() {0x0004FFFF, 3, 0, 159},
>> +      Package() {0x0005FFFF, 0, 0, 156},
>> +      Package() {0x0005FFFF, 1, 0, 157},
>> +      Package() {0x0005FFFF, 2, 0, 158},
>> +      Package() {0x0005FFFF, 3, 0, 159},
>> +      Package() {0x0006FFFF, 0, 0, 156},
>> +      Package() {0x0006FFFF, 1, 0, 157},
>> +      Package() {0x0006FFFF, 2, 0, 158},
>> +      Package() {0x0006FFFF, 3, 0, 159},
>> +      Package() {0x0007FFFF, 0, 0, 156},
>> +      Package() {0x0007FFFF, 1, 0, 157},
>> +      Package() {0x0007FFFF, 2, 0, 158},
>> +      Package() {0x0007FFFF, 3, 0, 159},
>> +      Package() {0x0008FFFF, 0, 0, 156},
>> +      Package() {0x0008FFFF, 1, 0, 157},
>> +      Package() {0x0008FFFF, 2, 0, 158},
>> +      Package() {0x0008FFFF, 3, 0, 159},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x2FFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FF40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000018000000,   // AddressMinimum - MIN
>> +        0x000000001FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00002C0000000000,   // AddressMinimum - MIN
>> +        0x00002FFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3,0,CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3,4,CDW2)
>> +        CreateDWordField (Arg3,8,CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2,SUPP)
>> +        Store (CDW3,CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL,0x1E,CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1,One)) {
>> +          Or (CDW1,0x08,CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3,CTRL)) {
>> +          Or (CDW1,0x10,CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL,CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1,4,CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCI7 RCB3
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
>> new file mode 100755
>> index 000000000000..2757f3124b83
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PCI-S1.asi
>> @@ -0,0 +1,2087 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +  //
>> +  // S1 Start here
>> +  //
>> +
>> +  // PCIE6 S1 RCA2
>> +  Device (PCIA) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID,"PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID,"PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 6)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCIA")
>> +    Name (_STR, Unicode("PCIe 10 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 136/137/138/139 + 320 respectively. PCIA RCA2
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 456},
>> +      Package() {0x0001FFFF, 1, 0, 457},
>> +      Package() {0x0001FFFF, 2, 0, 458},
>> +      Package() {0x0001FFFF, 3, 0, 459},
>> +      Package() {0x0002FFFF, 0, 0, 456},
>> +      Package() {0x0002FFFF, 1, 0, 457},
>> +      Package() {0x0002FFFF, 2, 0, 458},
>> +      Package() {0x0002FFFF, 3, 0, 459},
>> +      Package() {0x0003FFFF, 0, 0, 456},
>> +      Package() {0x0003FFFF, 1, 0, 457},
>> +      Package() {0x0003FFFF, 2, 0, 458},
>> +      Package() {0x0003FFFF, 3, 0, 459},
>> +      Package() {0x0004FFFF, 0, 0, 456},
>> +      Package() {0x0004FFFF, 1, 0, 457},
>> +      Package() {0x0004FFFF, 2, 0, 458},
>> +      Package() {0x0004FFFF, 3, 0, 459},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x7BFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FF80000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000070000000,   // AddressMinimum - MIN
>> +        0x0000000077FFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000780000000000,   // AddressMinimum - MIN
>> +        0x00007BFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3,0,CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3,4,CDW2)
>> +        CreateDWordField (Arg3,8,CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2,SUPP)
>> +        Store (CDW3,CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL,0x1E,CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1,One)) {
>> +          Or (CDW1,0x08,CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3,CTRL)) {
>> +          Or (CDW1,0x10,CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL,CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1,4,CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCIA RCA2
>> +
>> +  // PCIEB RCA3
>> +  Device (PCIB) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID,"PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID,"PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 7)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCIB")
>> +    Name (_STR, Unicode("PCIe 11 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 140/141/142/143 + 320 respectively. PCIB RCA3
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 460},
>> +      Package() {0x0001FFFF, 1, 0, 461},
>> +      Package() {0x0001FFFF, 2, 0, 462},
>> +      Package() {0x0001FFFF, 3, 0, 463},
>> +      Package() {0x0002FFFF, 0, 0, 460},
>> +      Package() {0x0002FFFF, 1, 0, 461},
>> +      Package() {0x0002FFFF, 2, 0, 462},
>> +      Package() {0x0002FFFF, 3, 0, 463},
>> +      Package() {0x0003FFFF, 0, 0, 460},
>> +      Package() {0x0003FFFF, 1, 0, 461},
>> +      Package() {0x0003FFFF, 2, 0, 462},
>> +      Package() {0x0003FFFF, 3, 0, 463},
>> +      Package() {0x0004FFFF, 0, 0, 460},
>> +      Package() {0x0004FFFF, 1, 0, 461},
>> +      Package() {0x0004FFFF, 2, 0, 462},
>> +      Package() {0x0004FFFF, 3, 0, 463},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x7FFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FFC0000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000078000000,   // AddressMinimum - MIN
>> +        0x000000007FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00007C0000000000,   // AddressMinimum - MIN
>> +        0x00007FFFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3,0,CDW1)
>> +      If (LEqual (Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3,4,CDW2)
>> +        CreateDWordField (Arg3,8,CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2,SUPP)
>> +        Store (CDW3,CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL,0x1E,CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1,One)) {
>> +            Or (CDW1,0x08,CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3,CTRL)) {
>> +            Or (CDW1,0x10,CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL,CDW3)
>> +        Return (Arg3)
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1,4,CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCIB RCA3
>> +
>> +  // PCIC RCB0
>> +  Device (PCIC) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 8)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCIC")
>> +    Name (_STR, Unicode("PCIe 12 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 144/145/146/147 + 320 respectively. PCIC RCB0
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 464},
>> +      Package() {0x0001FFFF, 1, 0, 465},
>> +      Package() {0x0001FFFF, 2, 0, 466},
>> +      Package() {0x0001FFFF, 3, 0, 467},
>> +      Package() {0x0002FFFF, 0, 0, 464},
>> +      Package() {0x0002FFFF, 1, 0, 465},
>> +      Package() {0x0002FFFF, 2, 0, 466},
>> +      Package() {0x0002FFFF, 3, 0, 467},
>> +      Package() {0x0003FFFF, 0, 0, 464},
>> +      Package() {0x0003FFFF, 1, 0, 465},
>> +      Package() {0x0003FFFF, 2, 0, 466},
>> +      Package() {0x0003FFFF, 3, 0, 467},
>> +      Package() {0x0004FFFF, 0, 0, 464},
>> +      Package() {0x0004FFFF, 1, 0, 465},
>> +      Package() {0x0004FFFF, 2, 0, 466},
>> +      Package() {0x0004FFFF, 3, 0, 467},
>> +      Package() {0x0005FFFF, 0, 0, 464},
>> +      Package() {0x0005FFFF, 1, 0, 465},
>> +      Package() {0x0005FFFF, 2, 0, 466},
>> +      Package() {0x0005FFFF, 3, 0, 467},
>> +      Package() {0x0006FFFF, 0, 0, 464},
>> +      Package() {0x0006FFFF, 1, 0, 465},
>> +      Package() {0x0006FFFF, 2, 0, 466},
>> +      Package() {0x0006FFFF, 3, 0, 467},
>> +      Package() {0x0007FFFF, 0, 0, 464},
>> +      Package() {0x0007FFFF, 1, 0, 465},
>> +      Package() {0x0007FFFF, 2, 0, 466},
>> +      Package() {0x0007FFFF, 3, 0, 467},
>> +      Package() {0x0008FFFF, 0, 0, 464},
>> +      Package() {0x0008FFFF, 1, 0, 465},
>> +      Package() {0x0008FFFF, 2, 0, 466},
>> +      Package() {0x0008FFFF, 3, 0, 467},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x63FFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000040000000,   // AddressMinimum - MIN
>> +        0x0000000047FFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000600000000000,   // AddressMinimum - MIN
>> +        0x000063FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCIC RCB0
>> +
>> +  // PCID RCB1
>> +  Device (PCID) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 9)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCID")
>> +    Name (_STR, Unicode("PCIe 13 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 148/149/150/151 + 320 respectively. PCID RCB1
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 468},
>> +      Package() {0x0001FFFF, 1, 0, 469},
>> +      Package() {0x0001FFFF, 2, 0, 470},
>> +      Package() {0x0001FFFF, 3, 0, 471},
>> +      Package() {0x0002FFFF, 0, 0, 468},
>> +      Package() {0x0002FFFF, 1, 0, 469},
>> +      Package() {0x0002FFFF, 2, 0, 470},
>> +      Package() {0x0002FFFF, 3, 0, 471},
>> +      Package() {0x0003FFFF, 0, 0, 468},
>> +      Package() {0x0003FFFF, 1, 0, 469},
>> +      Package() {0x0003FFFF, 2, 0, 470},
>> +      Package() {0x0003FFFF, 3, 0, 471},
>> +      Package() {0x0004FFFF, 0, 0, 468},
>> +      Package() {0x0004FFFF, 1, 0, 469},
>> +      Package() {0x0004FFFF, 2, 0, 470},
>> +      Package() {0x0004FFFF, 3, 0, 471},
>> +      Package() {0x0005FFFF, 0, 0, 468},
>> +      Package() {0x0005FFFF, 1, 0, 469},
>> +      Package() {0x0005FFFF, 2, 0, 470},
>> +      Package() {0x0005FFFF, 3, 0, 471},
>> +      Package() {0x0006FFFF, 0, 0, 468},
>> +      Package() {0x0006FFFF, 1, 0, 469},
>> +      Package() {0x0006FFFF, 2, 0, 470},
>> +      Package() {0x0006FFFF, 3, 0, 471},
>> +      Package() {0x0007FFFF, 0, 0, 468},
>> +      Package() {0x0007FFFF, 1, 0, 469},
>> +      Package() {0x0007FFFF, 2, 0, 470},
>> +      Package() {0x0007FFFF, 3, 0, 471},
>> +      Package() {0x0008FFFF, 0, 0, 468},
>> +      Package() {0x0008FFFF, 1, 0, 469},
>> +      Package() {0x0008FFFF, 2, 0, 470},
>> +      Package() {0x0008FFFF, 3, 0, 471},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x67FFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000048000000,   // AddressMinimum - MIN
>> +        0x000000004FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000640000000000,   // AddressMinimum - MIN
>> +        0x000067FFDFFFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCID RCB1
>> +
>> +  // PCIE RCB2
>> +  Device (PCIE) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 10)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCIE")
>> +    Name (_STR, Unicode("PCIe 14 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 152/153/154/155 + 320 respectively. PCIE RCB2
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 472},
>> +      Package() {0x0001FFFF, 1, 0, 473},
>> +      Package() {0x0001FFFF, 2, 0, 474},
>> +      Package() {0x0001FFFF, 3, 0, 475},
>> +      Package() {0x0002FFFF, 0, 0, 472},
>> +      Package() {0x0002FFFF, 1, 0, 473},
>> +      Package() {0x0002FFFF, 2, 0, 474},
>> +      Package() {0x0002FFFF, 3, 0, 475},
>> +      Package() {0x0003FFFF, 0, 0, 472},
>> +      Package() {0x0003FFFF, 1, 0, 473},
>> +      Package() {0x0003FFFF, 2, 0, 474},
>> +      Package() {0x0003FFFF, 3, 0, 475},
>> +      Package() {0x0004FFFF, 0, 0, 472},
>> +      Package() {0x0004FFFF, 1, 0, 473},
>> +      Package() {0x0004FFFF, 2, 0, 474},
>> +      Package() {0x0004FFFF, 3, 0, 475},
>> +      Package() {0x0005FFFF, 0, 0, 472},
>> +      Package() {0x0005FFFF, 1, 0, 473},
>> +      Package() {0x0005FFFF, 2, 0, 474},
>> +      Package() {0x0005FFFF, 3, 0, 475},
>> +      Package() {0x0006FFFF, 0, 0, 472},
>> +      Package() {0x0006FFFF, 1, 0, 473},
>> +      Package() {0x0006FFFF, 2, 0, 474},
>> +      Package() {0x0006FFFF, 3, 0, 475},
>> +      Package() {0x0007FFFF, 0, 0, 472},
>> +      Package() {0x0007FFFF, 1, 0, 473},
>> +      Package() {0x0007FFFF, 2, 0, 474},
>> +      Package() {0x0007FFFF, 3, 0, 475},
>> +      Package() {0x0008FFFF, 0, 0, 472},
>> +      Package() {0x0008FFFF, 1, 0, 473},
>> +      Package() {0x0008FFFF, 2, 0, 474},
>> +      Package() {0x0008FFFF, 3, 0, 475},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x6BFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000050000000,   // AddressMinimum - MIN
>> +        0x0000000057FFFFFF,   // AddressMaximum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000680000000000,   // AddressMinimum - MIN
>> +        0x00006BFFDFFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCIE RCB2
>> +
>> +  // PCIF RCB3
>> +  Device (PCIF) {
>> +    //
>> +    // Hardware ID must be PNP0A08, which maps to a PCIe root complex.
>> +    // Section 6.1.5
>> +    //
>> +
>> +    Name (_HID, "PNP0A08")
>> +    Name (_CCA, ONE)
>> +
>> +    Method (_STA, 0, NotSerialized) {
>> +      Return (0xF)                      // The default value is 0x0. Unfortunately, it breaks
>> +                                        // run-time patching as the representation of 0 is special
>> +                                        // encoding and cannot be patched to expand with extra bytes
>> +                                        // easily. As such, we default to 0xF and patch this based
>> +                                        // on whether the port was enabled or not by the BIOS.
>> +    }
>> +
>> +    //
>> +    // Optionally, include a compatible ID of PNP0A03, which maps to a PCI
>> +    // root complex for use with pre-PCIe operating systems.
>> +    // Section 6.1.2
>> +    //
>> +
>> +    Name (_CID, "PNP0A03")
>> +
>> +    //
>> +    // Declare the segment number of this root complex. Most systems only
>> +    // have one segment, which is numbered 0.
>> +    // Section 6.5.6
>> +    //
>> +
>> +    Name (_SEG, 11)
>> +
>> +    //
>> +    // Declare the base bus number, which is the bus number of the root
>> +    // bus in this root complex. This is usually 0, but need not be.
>> +    // For root complexes supporting multiple root busses, this should
>> +    // be the lowest numbered root bus.
>> +    // Section 6.5.5
>> +    //
>> +
>> +    Name (_BBN, 0)
>> +
>> +    //
>> +    // The _UID value provides a way of uniquely identifying a device
>> +    // in the case where more than one instance of a specific device
>> +    // is implemented with the same _HID/_CID. For systems with a
>> +    // single root complex, this is usually just 0. For systems with
>> +    // multiple root complexes, this should be different for each
>> +    // root complex.
>> +    // Section 6.1.12
>> +    //
>> +
>> +    Name (_UID, "PCIF")
>> +    Name (_STR, Unicode("PCIe 15 Device"))
>> +
>> +    //
>> +    // Declare the PCI Routing Table.
>> +    // This defines SPI mappings of the four line-based interrupts
>> +    // associated with the root complex and hierarchy below it.
>> +    // Section 6.2.12
>> +    //
>> +
>> +    Name (_PRT, Package() {
>> +
>> +      //
>> +      // Routing for device 0, all functions.
>> +      // Note: ARM doesn't support LNK nodes, so the third param
>> +      // is 0 and the fourth param is the SPI number of the interrupt
>> +      // line. In this example, the A/B/C/D interrupts are wired to
>> +      // SPI lines 156/157/158/159 + 320 respectively. PCIF RCB3
>> +      //
>> +      Package() {0x0001FFFF, 0, 0, 476},
>> +      Package() {0x0001FFFF, 1, 0, 477},
>> +      Package() {0x0001FFFF, 2, 0, 478},
>> +      Package() {0x0001FFFF, 3, 0, 479},
>> +      Package() {0x0002FFFF, 0, 0, 476},
>> +      Package() {0x0002FFFF, 1, 0, 477},
>> +      Package() {0x0002FFFF, 2, 0, 478},
>> +      Package() {0x0002FFFF, 3, 0, 479},
>> +      Package() {0x0003FFFF, 0, 0, 476},
>> +      Package() {0x0003FFFF, 1, 0, 477},
>> +      Package() {0x0003FFFF, 2, 0, 478},
>> +      Package() {0x0003FFFF, 3, 0, 479},
>> +      Package() {0x0004FFFF, 0, 0, 476},
>> +      Package() {0x0004FFFF, 1, 0, 477},
>> +      Package() {0x0004FFFF, 2, 0, 478},
>> +      Package() {0x0004FFFF, 3, 0, 479},
>> +      Package() {0x0005FFFF, 0, 0, 476},
>> +      Package() {0x0005FFFF, 1, 0, 477},
>> +      Package() {0x0005FFFF, 2, 0, 478},
>> +      Package() {0x0005FFFF, 3, 0, 479},
>> +      Package() {0x0006FFFF, 0, 0, 476},
>> +      Package() {0x0006FFFF, 1, 0, 477},
>> +      Package() {0x0006FFFF, 2, 0, 478},
>> +      Package() {0x0006FFFF, 3, 0, 479},
>> +      Package() {0x0007FFFF, 0, 0, 476},
>> +      Package() {0x0007FFFF, 1, 0, 477},
>> +      Package() {0x0007FFFF, 2, 0, 478},
>> +      Package() {0x0007FFFF, 3, 0, 479},
>> +      Package() {0x0008FFFF, 0, 0, 476},
>> +      Package() {0x0008FFFF, 1, 0, 477},
>> +      Package() {0x0008FFFF, 2, 0, 478},
>> +      Package() {0x0008FFFF, 3, 0, 479},
>> +    })
>> +
>> +    //
>> +    // Declare the resources assigned to this root complex.
>> +    // Section 6.2.2
>> +    //
>> +    Method (_CBA, 0, Serialized) {
>> +      Return (0x6FFFF0000000)
>> +    }
>> +
>> +    //
>> +    // Declare a ResourceTemplate buffer to return the resource
>> +    // requirements from _CRS.
>> +    // Section 19.5.109
>> +    //
>> +
>> +    Name (RBUF, ResourceTemplate () {
>> +
>> +      //
>> +      // Declare the range of bus numbers assigned to this root
>> +      // complex. In this example, the minimum bus number will be
>> +      // 0, the maximum bus number will be 0xFF, supporting
>> +      // 256 busses total.
>> +      // Section 19.5.141
>> +      //
>> +
>> +      WordBusNumber (
>> +        ResourceProducer,
>> +        MinFixed,   // IsMinFixed
>> +        MaxFixed,   // IsMaxFixed
>> +        PosDecode,  // Decode
>> +        0,          // AddressGranularity
>> +        0,          // AddressMinimum - Minimum Bus Number
>> +        255,        // AddressMaximum - Maximum Bus Number
>> +        0,          // AddressTranslation - Set to 0
>> +        256)        // RangeLength - Number of Busses
>> +
>> +      //
>> +      // Declare the memory range to be used for BAR memory
>> +      // windows. This declares a 4GB region starting at
>> +      // 0x4000000000.
>> +      // Section 19.5.80
>> +      //
>> +      // Memory32Fixed (ReadWrite, 0x1FE40000, 0x10000, )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x0000000058000000,   // AddressMinimum - MIN
>> +        0x000000005FFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x0000000008000000    // RangeLength - LEN
>> +      )
>> +
>> +      QWordMemory (
>> +        ResourceProducer,     // ResourceUsage
>> +        PosDecode,            // Decode
>> +        MinFixed,             // IsMinFixed
>> +        MaxFixed,             // IsMaxFixed
>> +        NonCacheable,         // NonCacheable
>> +        ReadWrite,            // ReadAndWrite
>> +        0x0000000000000000,   // AddressGranularity - GRA
>> +        0x00006C0000000000,   // AddressMinimum - MIN
>> +        0x00006FFFDFFFFFFF,   // AddressMinimum - MAX
>> +        0x0000000000000000,   // AddressTranslation - TRA
>> +        0x000003FFE0000000    // RangeLength - LEN
>> +      )
>> +    })
>> +
>> +    Method (_CRS, 0, Serialized) {
>> +      Return (RBUF)
>> +    }
>> +
>> +    //
>> +    // Declare an _OSC (OS Control Handoff) method which takes 4 arguments.
>> +    //
>> +    // Argments:
>> +    //   Arg0  A Buffer containing a UUID
>> +    //   Arg1  An Integer containing a Revision ID of the buffer format
>> +    //   Arg2  An Integer containing a count of entries in Arg3
>> +    //   Arg3  A Buffer containing a list of DWORD capabilities
>> +    // Return Value:
>> +    //   A Buffer containing a list of capabilities
>> +    // See the APCI spec, Section 6.2.10,
>> +    // and the PCI FW spec, Section 4.5.
>> +    //
>> +    // The following is an example, and may need modification for
>> +    // specific implementations.
>> +    //
>> +
>> +    Name (SUPP,0) // PCI _OSC Support Field value
>> +    Name (CTRL,0) // PCI _OSC Control Field value
>> +
>> +    Method (_OSC, 4) {
>> +
>> +      //
>> +      // Look for the PCI Host Bridge Interface UUID.
>> +      // Section 6.2.10.3
>> +      //
>> +
>> +      //
>> +      // Create DWord-adressable fields from the Capabilities Buffer
>> +      // Create CDW1 outside the test as it's used in the else clause.
>> +      //
>> +
>> +      CreateDWordField (Arg3, 0, CDW1)
>> +      If (LEqual (Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
>> +
>> +        CreateDWordField (Arg3, 4, CDW2)
>> +        CreateDWordField (Arg3, 8, CDW3)
>> +
>> +        //
>> +        // Save Capabilities DWord 2 & 3
>> +        //
>> +
>> +        Store (CDW2, SUPP)
>> +        Store (CDW3, CTRL)
>> +
>> +        //
>> +        // Only allow native hot plug control if OS supports:
>> +        //  ASPM
>> +        //  Clock PM
>> +        //  MSI/MSI-X
>> +        //
>> +
>> +        If (LNotEqual (And (SUPP, 0x16), 0x16)) {
>> +
>> +          //
>> +          // Mask bit 0 (and undefined bits)
>> +          //
>> +
>> +          And (CTRL, 0x1E, CTRL)
>> +        }
>> +
>> +        //
>> +        // Never allow native Hot plug, PME.
>> +        // Never allow SHPC (no SHPC controller in this system).
>> +        // Only allow PCIe AER control if PCIe AER Firmware-First is disabled
>> +        // Allows PCI Express Capability Structure control
>> +        //
>> +
>> +        If (AERF) {
>> +          And (CTRL, 0x10, CTRL)
>> +        } Else {
>> +          And (CTRL, 0x18, CTRL)
>> +        }
>> +
>> +        //
>> +        // Check for unknown revision.
>> +        //
>> +
>> +        If (LNotEqual (Arg1, One)) {
>> +          Or (CDW1, 0x08, CDW1)
>> +        }
>> +
>> +        //
>> +        // Check if capabilities bits were masked.
>> +        //
>> +
>> +        If (LNotEqual (CDW3, CTRL)) {
>> +          Or (CDW1, 0x10, CDW1)
>> +        }
>> +
>> +        //
>> +        // Update DWORD3 in the buffer.
>> +        //
>> +
>> +        Store (CTRL, CDW3)
>> +        Return (Arg3)
>> +
>> +      } Else {
>> +
>> +        //
>> +        // Unrecognized UUID
>> +        //
>> +
>> +        Or (CDW1, 4, CDW1)
>> +        Return (Arg3)
>> +      }
>> +    } // End _OSC
>> +
>> +    //
>> +    // Declare a _DSM method for various functions called by the OS.
>> +    // See the APCI spec, Section 9.14.1,
>> +    // and the PCI FW spec, Section 4.6.
>> +    // See also:
>> +    // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
>> +    //
>> +
>> +    Method (_DSM, 0x4, Serialized) {
>> +
>> +      //
>> +      // Match against the _DSM PCI GUID.
>> +      //
>> +
>> +      If (LEqual (Arg0, ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))) {
>> +
>> +        Switch (ToInteger(Arg2)) {
>> +          //
>> +          // Function 0: Return supported functions as a bitfield
>> +          // with one bit for each supported function.
>> +          // Bit 0 must always be set, as that represents
>> +          // function 0 (which is what is being called here).
>> +          // Support for different functions may depend on
>> +          // the revision ID of the interface, passed as Arg1.
>> +          //
>> +
>> +          Case (0) {
>> +
>> +              //
>> +              // Functions 0-7 are supported.
>> +              //
>> +
>> +              Return (Buffer() {0x01})
>> +          }
>> +        }
>> +      }
>> +
>> +      //
>> +      // If not one of the function identifiers we recognize, then return a buffer
>> +      // with bit 0 set to 0 indicating no functions supported.
>> +      //
>> +
>> +      Return (Buffer() {0})
>> +    }
>> +
>> +    //
>> +    // Root Port 0 Device within the Root Complex.
>> +    //
>> +    Device (RP0) {
>> +      //
>> +      // Device 0, Function 0.
>> +      //
>> +
>> +      Name (_ADR, 0x00000000)
>> +    }
>> +
>> +    Method (_PXM, 0, NotSerialized) {
>> +      // Patch by code
>> +      Return(0xFF)
>> +    }
>> +  } // PCIF RCB3
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
>> new file mode 100755
>> index 000000000000..0e9db557d925
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S0.asi
>> @@ -0,0 +1,1303 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Device(CMN0) {
>> +  Name(_HID, "ARMHC600") // Device Identification Objects
>> +  Name(_CID, "ARMHC600")
>> +  Name(_UID, 0)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("CMN0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +  QWordMemory (
>> +    ResourceConsumer,     // ResourceUsage
>> +    PosDecode,            // Decode
>> +    MinFixed,             // IsMinFixed
>> +    MaxFixed,             // IsMaxFixed
>> +    NonCacheable,         // Cacheable
>> +    ReadWrite,            // ReadAndWrite
>> +    0x0000000000000000,   // AddressGranularity - GRA
>> +    0x0000100010000000,   // AddressMinimum - MIN
>> +    0x000010001fffffff,   // AddressMaximum - MAX
>> +    0x0000000000000000,   // AddressTranslation - TRA
>> +    0x0000000010000000    // RangeLength - LEN
>> +  )
>> +  QWordMemory (
>> +    ResourceConsumer,     // ResourceUsage
>> +    PosDecode,            // Decode
>> +    MinFixed,             // IsMinFixed
>> +    MaxFixed,             // IsMaxFixed
>> +    NonCacheable,         // Cacheable
>> +    ReadWrite,            // ReadAndWrite
>> +    0x0000000000000000,   // AddressGranularity - GRA
>> +    0x0000100012500000,   // AddressMinimum - MIN
>> +    0x00001000164fffff,   // AddressMaximum - MAX
>> +    0x0000000000000000,   // AddressTranslation - TRA
>> +    0x0000000004000000    // RangeLength - LEN
>> +  )
>> +  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 314 }
>> +  })
>> +}
>> +
>> +Device(MC00) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008C000A00,   // AddressMinimum - MIN
>> +      0x000010008C000BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC01) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 1)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008C400A00,   // AddressMinimum - MIN
>> +      0x000010008C400BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC02) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 2)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU2"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008C800A00,   // AddressMinimum - MIN
>> +      0x000010008C800BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC03) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 3)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU3"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008CC00A00,   // AddressMinimum - MIN
>> +      0x000010008CC00BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC04) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 4)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU4"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008D000A00,   // AddressMinimum - MIN
>> +      0x000010008D000BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC05) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 5)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU5"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008D400A00,   // AddressMinimum - MIN
>> +      0x000010008D400BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC06) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 6)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU6"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008D800A00,   // AddressMinimum - MIN
>> +      0x000010008D800BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(MC07) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 7)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 0: MCU7"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000010008DC00A00,   // AddressMinimum - MIN
>> +      0x000010008DC00BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 312 }
>> +  })
>> +}
>> +
>> +Device(DU00) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 64 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x000000,
>> +          0x000100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU01) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 65 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x010000,
>> +          0x010100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU02) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x2)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x2 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 66 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x020000,
>> +          0x020100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU03) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x3)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x3 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 67 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x030000,
>> +          0x030100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU04) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 68 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x040000,
>> +          0x040100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU05) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 69 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x050000,
>> +          0x050100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU06) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x6)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x6 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 71 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x060000,
>> +          0x060100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU07) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x7)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x7 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 80 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x070000,
>> +          0x070100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU08) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x8)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x8 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 81 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x080000,
>> +          0x080100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU09) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x9)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x9 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 82 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x090000,
>> +          0x090100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0A) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xA)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xA Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 83 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0A0000,
>> +          0x0A0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0B) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xB)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xB Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 115 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0B0000,
>> +          0x0B0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0C) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xC)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xC Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 116 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0C0000,
>> +          0x0C0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0D) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xD)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xD Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 221 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0D0000,
>> +          0x0D0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0E) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xE)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xE Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 222 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0E0000,
>> +          0x0E0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU0F) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0xF)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0xF Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 223 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x0F0000,
>> +          0x0F0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU10) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x10)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x10 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 248 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100000,
>> +          0x100100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU11) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x11)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x11 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 249 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x110000,
>> +          0x110100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU12) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x12)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x12 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 250 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x120000,
>> +          0x120100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU13) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x13)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x13 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 251 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x130000,
>> +          0x130100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU14) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x14)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x14 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 252 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x140000,
>> +          0x140100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU15) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x15)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x15 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 253 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x150000,
>> +          0x150100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU16) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x16)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x16 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 254 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x160000,
>> +          0x160100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU17) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x17)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x17 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 255 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x170000,
>> +          0x170100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU18) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x18)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x18 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 297 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x180000,
>> +          0x180100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU19) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x19)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x19 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 298 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x190000,
>> +          0x190100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1A) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1A)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1A Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 299 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1A0000,
>> +          0x1A0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1B) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1B)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1B Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 300 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1B0000,
>> +          0x1B0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1C) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1C)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1C Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 301 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1C0000,
>> +          0x1C0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1D) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1D)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1D Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 313 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1D0000,
>> +          0x1D0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1E) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1E)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1E Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 316 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1E0000,
>> +          0x1E0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU1F) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x1F)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x1F Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 317 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1F0000,
>> +          0x1F0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU20) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x20)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x20 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 318 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x200000,
>> +          0x200100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU21) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x21)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x21 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 319 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x210000,
>> +          0x210100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU22) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x22)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x22 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 344 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x220000,
>> +          0x220100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU23) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x23)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x23 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 345 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x230000,
>> +          0x230100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU24) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x24)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x24 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 346 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x240000,
>> +          0x240100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU25) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x25)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x25 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 347 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x250000,
>> +          0x250100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU26) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x26)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x26 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 348 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x260000,
>> +          0x260100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU27) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x27)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x27 Socket 0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 349 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x270000,
>> +          0x270100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
>> new file mode 100755
>> index 000000000000..1ae1bac8098b
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU-S1.asi
>> @@ -0,0 +1,1303 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Device(CMN1) {
>> +  Name(_HID, "ARMHC600") // Device Identification Objects
>> +  Name(_CID, "ARMHC600")
>> +  Name(_UID, 1)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("CMN1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +  QWordMemory (
>> +    ResourceConsumer,     // ResourceUsage
>> +    PosDecode,            // Decode
>> +    MinFixed,             // IsMinFixed
>> +    MaxFixed,             // IsMaxFixed
>> +    NonCacheable,         // Cacheable
>> +    ReadWrite,            // ReadAndWrite
>> +    0x0000000000000000,   // AddressGranularity - GRA
>> +    0x0000500010000000,   // AddressMinimum - MIN
>> +    0x000050001fffffff,   // AddressMaximum - MAX
>> +    0x0000000000000000,   // AddressTranslation - TRA
>> +    0x0000000010000000    // RangeLength - LEN
>> +  )
>> +  QWordMemory (
>> +    ResourceConsumer,     // ResourceUsage
>> +    PosDecode,            // Decode
>> +    MinFixed,             // IsMinFixed
>> +    MaxFixed,             // IsMaxFixed
>> +    NonCacheable,         // Cacheable
>> +    ReadWrite,            // ReadAndWrite
>> +    0x0000000000000000,   // AddressGranularity - GRA
>> +    0x0000500012500000,   // AddressMinimum - MIN
>> +    0x00005000164fffff,   // AddressMaximum - MAX
>> +    0x0000000000000000,   // AddressTranslation - TRA
>> +    0x0000000004000000    // RangeLength - LEN
>> +  )
>> +  Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 634 }
>> +  })
>> +}
>> +
>> +Device(MC10) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 8)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU0"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008C000A00,   // AddressMinimum - MIN
>> +      0x000050008C000BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC11) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 9)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008C400A00,   // AddressMinimum - MIN
>> +      0x000050008C400BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC12) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xa)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU2"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008C800A00,   // AddressMinimum - MIN
>> +      0x000050008C800BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC13) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xb)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU3"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008CC00A00,   // AddressMinimum - MIN
>> +      0x000050008CC00BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC14) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xc)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU4"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008D000A00,   // AddressMinimum - MIN
>> +      0x000050008D000BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC15) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xd)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU5"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008D400A00,   // AddressMinimum - MIN
>> +      0x000050008D400BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC16) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xe)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU6"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008D800A00,   // AddressMinimum - MIN
>> +      0x000050008D800BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(MC17) {
>> +  Name(_HID, "ARMHD620")
>> +  Name(_CID, "ARMHD620")
>> +  Name(_UID, 0xf)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("Socket 1: MCU7"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    QWordMemory (
>> +      ResourceProducer,     // ResourceUsage
>> +      PosDecode,            // Decode
>> +      MinFixed,             // IsMinFixed
>> +      MaxFixed,             // IsMaxFixed
>> +      NonCacheable,         // Cacheable
>> +      ReadWrite,            // ReadAndWrite
>> +      0x0000000000000000,   // AddressGranularity - GRA
>> +      0x000050008DC00A00,   // AddressMinimum - MIN
>> +      0x000050008DC00BFF,   // AddressMaximum - MAX
>> +      0x0000000000000000,   // AddressTranslation - TRA
>> +      0x0000000000000200    // RangeLength - LEN
>> +    )
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 632 }
>> +  })
>> +}
>> +
>> +Device(DU40) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x40)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x40 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 384 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100000000,
>> +          0x100000100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU41) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x41)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x41 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 385 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100010000,
>> +          0x100010100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU42) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x42)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x42 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 386 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100020000,
>> +          0x100020100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU43) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x43)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x43 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 387 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100030000,
>> +          0x100030100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU44) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x44)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x44 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 388 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100040000,
>> +          0x100040100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU45) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x45)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x45 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 389 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100050000,
>> +          0x100050100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU46) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x46)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x46 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 391 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100060000,
>> +          0x100060100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU47) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x47)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x47 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 400 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100070000,
>> +          0x100070100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU48) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x48)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x48 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 401 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100080000,
>> +          0x100080100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU49) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x49)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x49 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 402 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100090000,
>> +          0x100090100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4A) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4A)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4A Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 403 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000A0000,
>> +          0x1000A0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4B) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4B)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4B Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 435 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000B0000,
>> +          0x1000B0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4C) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4C)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4C Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 436 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000C0000,
>> +          0x1000C0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4D) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4D)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4D Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 541 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000D0000,
>> +          0x1000D0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4E) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4E)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4E Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 542 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000E0000,
>> +          0x1000E0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU4F) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x4F)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x4F Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 543 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1000F0000,
>> +          0x1000F0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU50) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x50)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x50 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 568 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100100000,
>> +          0x100100100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU51) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x51)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x51 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 569 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100110000,
>> +          0x100110100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU52) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x52)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x52 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 570 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100120000,
>> +          0x100120100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU53) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x53)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x53 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 571 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100130000,
>> +          0x100130100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU54) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x54)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x54 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 572 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100140000,
>> +          0x100140100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU55) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x55)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x55 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 573 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100150000,
>> +          0x100150100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU56) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x56)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x56 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 574 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100160000,
>> +          0x100160100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU57) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x57)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x57 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 575 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100170000,
>> +          0x100170100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU58) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x58)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x58 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 617 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100180000,
>> +          0x100180100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU59) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x59)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x59 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 618 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100190000,
>> +          0x100190100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5A) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5A)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5A Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 619 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001A0000,
>> +          0x1001A0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5B) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5B)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5B Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 620 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001B0000,
>> +          0x1001B0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5C) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5C)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5C Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 621 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001C0000,
>> +          0x1001C0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5D) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5D)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5D Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 633 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001D0000,
>> +          0x1001D0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5E) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5E)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5E Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 636 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001E0000,
>> +          0x1001E0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU5F) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x5F)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x5F Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 637 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x1001F0000,
>> +          0x1001F0100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU60) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x60)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x60 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 638 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100200000,
>> +          0x100200100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU61) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x61)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x61 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 639 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100210000,
>> +          0x100210100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU62) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x62)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x62 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 664 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100220000,
>> +          0x100220100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU63) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x63)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x63 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 665 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100230000,
>> +          0x100230100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU64) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x64)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x64 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 666 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100240000,
>> +          0x100240100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU65) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x65)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x65 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 667 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100250000,
>> +          0x100250100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU66) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x66)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x66 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 668 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100260000,
>> +          0x100260100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> +
>> +Device(DU67) {
>> +  Name(_HID, "ARMHD500")
>> +  Name(_CID, "ARMHD500")
>> +  Name(_UID, 0x67)
>> +  Name(_CCA, ONE)
>> +  Name(_STR, Unicode("DSU CPM 0x67 Socket 1"))
>> +  Method(_STA, 0, NotSerialized) {
>> +    Return (0x0f)
>> +  }
>> +  Name(_CRS, ResourceTemplate() {
>> +    Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 669 }
>> +  })
>> +  Name (_DSD, Package () {
>> +    ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
>> +    Package () {
>> +      Package (2) {
>> +        "cpus",
>> +        Package (2) {
>> +          0x100270000,
>> +          0x100270100
>> +        }
>> +      }
>> +    }
>> +  })
>> +}
>> diff --git a/Platform/Ampere/JadePkg/AcpiTables/PMU.asi b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
>> new file mode 100644
>> index 000000000000..0d177de8696d
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/AcpiTables/PMU.asi
>> @@ -0,0 +1,10 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +Include ("PMU-S0.asi")
>> +Include ("PMU-S1.asi")
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
>> new file mode 100644
>> index 000000000000..a80f1e81b24f
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Bert.aslc
>> @@ -0,0 +1,33 @@
>> +/** @file
>> +
>> +  Copyright (c) 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <IndustryStandard/Acpi.h>
>> +#include <AcpiHeader.h>
>> +
>> +#define BOOT_ERROR_REGION_LENGTH  0x50000
>> +#define BOOT_ERROR_REGION_BASE    0x0000000088230000
>> +
>> +#pragma pack(1)
>> +
>> +EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER Bert = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_SIGNATURE,
>> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_HEADER,
>> +    EFI_ACPI_6_3_BOOT_ERROR_RECORD_TABLE_REVISION
>> +  ),
>> +  BOOT_ERROR_REGION_LENGTH,
>> +  BOOT_ERROR_REGION_BASE
>> +};
>> +
>> +#pragma pack()
>> +
>> +//
>> +// Reference the table being generated to prevent the optimizer from removing
>> +// the data structure from the executable
>> +//
>> +VOID* CONST ReferenceAcpiTable = &Bert;
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
>> new file mode 100644
>> index 000000000000..bc2bbded11fd
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Dbg2.aslc
>> @@ -0,0 +1,87 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/AcpiLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <IndustryStandard/Acpi.h>
>> +#include <IndustryStandard/DebugPort2Table.h>
>> +#include <AcpiHeader.h>
>> +
>> +#pragma pack(1)
>> +
>> +#define DBG2_NUM_DEBUG_PORTS                       1
>> +#define DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS   1
>> +#define DBG2_NAMESPACESTRING_FIELD_SIZE            10
>> +#define SERIAL_PORT_PL011_UART_ADDR_SIZE           0x8
>> +
>> +#define NAME_STR_UART2     {'\\', '_', 'S', 'B', '.', 'U', 'R', 'T', '2', '\0'}
>> +
>> +typedef struct {
>> +  EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT Dbg2Device;
>> +  EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE        BaseAddressRegister;
>> +  UINT32                                        AddressSize;
>> +  UINT8                                         NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE];
>> +} DBG2_DEBUG_DEVICE_INFORMATION;
>> +
>> +typedef struct {
>> +  EFI_ACPI_DEBUG_PORT_2_DESCRIPTION_TABLE       Description;
>> +  DBG2_DEBUG_DEVICE_INFORMATION                 Dbg2DeviceInfo[DBG2_NUM_DEBUG_PORTS];
>> +} DBG2_TABLE;
>> +
>> +
>> +#define DBG2_DEBUG_PORT_DDI(NumReg, SubType, UartBase, UartAddrLen, UartNameStr) {                                    \
>> +    {                                                                                                                 \
>> +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION,         /* UINT8     Revision */                        \
>> +      sizeof (DBG2_DEBUG_DEVICE_INFORMATION),                         /* UINT16    Length */                          \
>> +      NumReg,                                                         /* UINT8     NumberofGenericAddressRegisters */ \
>> +      DBG2_NAMESPACESTRING_FIELD_SIZE,                                /* UINT16    NameSpaceStringLength */           \
>> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, NameSpaceString),     /* UINT16    NameSpaceStringOffset */           \
>> +      0,                                                              /* UINT16    OemDataLength */                   \
>> +      0,                                                              /* UINT16    OemDataOffset */                   \
>> +      EFI_ACPI_DBG2_PORT_TYPE_SERIAL,                                 /* UINT16    Port Type */                       \
>> +      SubType,                                                        /* UINT16    Port Subtype */                    \
>> +      {EFI_ACPI_RESERVED_BYTE, EFI_ACPI_RESERVED_BYTE},               /* UINT8     Reserved[2] */                     \
>> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, BaseAddressRegister), /* UINT16    BaseAddressRegister Offset */      \
>> +      OFFSET_OF (DBG2_DEBUG_DEVICE_INFORMATION, AddressSize)          /* UINT16    AddressSize Offset */              \
>> +    },                                                                                                                \
>> +    ARM_GAS32 (UartBase),                            /* EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister */ \
>> +    UartAddrLen,                                     /* UINT32  AddressSize */                                        \
>> +    UartNameStr                                      /* UINT8   NameSpaceString[DBG2_NAMESPACESTRING_FIELD_SIZE] */   \
>> +  }
>> +
>> +
>> +STATIC DBG2_TABLE Dbg2 = {
>> +  {
>> +    __ACPI_HEADER (
>> +      EFI_ACPI_6_3_DEBUG_PORT_2_TABLE_SIGNATURE,
>> +      DBG2_TABLE,
>> +      EFI_ACPI_DBG2_DEBUG_DEVICE_INFORMATION_STRUCT_REVISION
>> +    ),
>> +    OFFSET_OF (DBG2_TABLE, Dbg2DeviceInfo),
>> +    DBG2_NUM_DEBUG_PORTS                                 /* UINT32  NumberDbgDeviceInfo */
>> +  },
>> +  {
>> +    // Kernel Debug Port
>> +    DBG2_DEBUG_PORT_DDI (
>> +      DBG2_NUMBER_OF_GENERIC_ADDRESS_REGISTERS,
>> +      EFI_ACPI_DBG2_PORT_SUBTYPE_SERIAL_ARM_SBSA_GENERIC_UART,
>> +      FixedPcdGet64 (PcdSerialDbgRegisterBase),
>> +      SERIAL_PORT_PL011_UART_ADDR_SIZE,
>> +      NAME_STR_UART2
>> +      ),
>> +  }
>> +};
>> +
>> +#pragma pack()
>> +
>> +//
>> +// Reference the table being generated to prevent the optimizer from removing
>> +// the data structure from the executable
>> +//
>> +VOID* CONST ReferenceAcpiTable = &Dbg2;
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
>> new file mode 100755
>> index 000000000000..9607b2e403e0
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Einj.asl
>> @@ -0,0 +1,165 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +[0004]                          Signature : "EINJ"    [Error Injection table]
>> +[0004]                       Table Length : 00000150
>> +[0001]                           Revision : 01
>> +[0001]                           Checksum : 09
>> +[0006]                             Oem ID : "Ampere"
>> +[0008]                       Oem Table ID : "Altra   "
>> +[0004]                       Oem Revision : 00000001
>> +[0004]                    Asl Compiler ID : "INTL"
>> +[0004]              Asl Compiler Revision : 20100528
>> +
>> +[0004]            Injection Header Length : 00000030
>> +[0001]                              Flags : 00
>> +[0003]                           Reserved : 000000
>> +[0004]              Injection Entry Count : 00000009
>> +
>> +[0001]                             Action : 00 [Begin Operation]
>> +[0001]                        Instruction : 00 [Read Register]
>> +[0001]              Flags (decoded below) : 00
>> +                   Preserve Register Bits : 0
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088220000
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 01 [Get Trigger Table]
>> +[0001]                        Instruction : 00 [Read Register]
>> +[0001]              Flags (decoded below) : 00
>> +                   Preserve Register Bits : 0
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088220040
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 08 [Set Error Type With Address]
>> +[0001]                        Instruction : 02 [Write Register]
>> +[0001]              Flags (decoded below) : 01
>> +                   Preserve Register Bits : 1
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 20
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 03 [DWord Access:32]
>> +[0008]                            Address : 0000000088221000
>> +
>> +[0008]                              Value : 00000000
>> +[0008]                               Mask : FFFFFFFF
>> +
>> +[0001]                             Action : 02 [Set Error Type]
>> +[0001]                        Instruction : 02 [Write Register]
>> +[0001]              Flags (decoded below) : 01
>> +                   Preserve Register Bits : 1
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 20
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [DWord Access:64]
>> +[0008]                            Address : 0000000088220080
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 03 [Get Error Type]
>> +[0001]                        Instruction : 00 [Read Register]
>> +[0001]              Flags (decoded below) : 00
>> +                   Preserve Register Bits : 0
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 00000000882200c0
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 04 [End Operation]
>> +[0001]                        Instruction : 03 [Write Register Value]
>> +[0001]              Flags (decoded below) : 01
>> +                   Preserve Register Bits : 1
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088220100
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 05 [Execute Operation]
>> +[0001]                        Instruction : 03 [Write Register Value]
>> +[0001]              Flags (decoded below) : 01
>> +                   Preserve Register Bits : 1
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 20
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 03 [DWord Access:32]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                              Value : B1A00000
>> +[0008]                               Mask : FFFFFFFF
>> +
>> +[0001]                             Action : 06 [Check Busy Status]
>> +[0001]                        Instruction : 01 [Read Register Value]
>> +[0001]              Flags (decoded below) : 00
>> +                   Preserve Register Bits : 0
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088220140
>> +
>> +[0008]                              Value : 0000000000000001
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> +
>> +[0001]                             Action : 07 [Get Command Status]
>> +[0001]                        Instruction : 00 [Read Register]
>> +[0001]              Flags (decoded below) : 01
>> +                   Preserve Register Bits : 1
>> +[0001]                           Reserved : 00
>> +
>> +[0012]                    Register Region : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088220180
>> +
>> +[0008]                              Value : 0000000000000000
>> +[0008]                               Mask : FFFFFFFFFFFFFFFF
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
>> new file mode 100644
>> index 000000000000..5be828f1cdf0
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Fadt.aslc
>> @@ -0,0 +1,87 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/AcpiLib.h>
>> +#include <IndustryStandard/Acpi63.h>
>> +#include <AcpiHeader.h>
>> +
>> +//
>> +// This macro defines the FADT flag options.
>> +//
>> +#define FADT_FLAGS  (EFI_ACPI_6_3_HW_REDUCED_ACPI | \
>> +                     EFI_ACPI_6_3_PWR_BUTTON)
>> +
>> +
>> +EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE Fadt = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE,
>> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE,
>> +    EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_REVISION
>> +  ),
>> +  0,                                                                        // UINT32     FirmwareCtrl
>> +  0,                                                                        // UINT32     Dsdt
>> +  EFI_ACPI_RESERVED_BYTE,                                                   // UINT8      Reserved0
>> +  EFI_ACPI_6_3_PM_PROFILE_PERFORMANCE_SERVER,                               // UINT8      PreferredPmProfile
>> +  0,                                                                        // UINT16     SciInt
>> +  0,                                                                        // UINT32     SmiCmd
>> +  0,                                                                        // UINT8      AcpiEnable
>> +  0,                                                                        // UINT8      AcpiDisable
>> +  0,                                                                        // UINT8      S4BiosReq
>> +  0,                                                                        // UINT8      PstateCnt
>> +  0,                                                                        // UINT32     Pm1aEvtBlk
>> +  0,                                                                        // UINT32     Pm1bEvtBlk
>> +  0,                                                                        // UINT32     Pm1aCntBlk
>> +  0,                                                                        // UINT32     Pm1bCntBlk
>> +  0,                                                                        // UINT32     Pm2CntBlk
>> +  0,                                                                        // UINT32     PmTmrBlk
>> +  0,                                                                        // UINT32     Gpe0Blk
>> +  0,                                                                        // UINT32     Gpe1Blk
>> +  0,                                                                        // UINT8      Pm1EvtLen
>> +  0,                                                                        // UINT8      Pm1CntLen
>> +  0,                                                                        // UINT8      Pm2CntLen
>> +  0,                                                                        // UINT8      PmTmrLen
>> +  0,                                                                        // UINT8      Gpe0BlkLen
>> +  0,                                                                        // UINT8      Gpe1BlkLen
>> +  0,                                                                        // UINT8      Gpe1Base
>> +  0,                                                                        // UINT8      CstCnt
>> +  0,                                                                        // UINT16     PLvl2Lat
>> +  0,                                                                        // UINT16     PLvl3Lat
>> +  0,                                                                        // UINT16     FlushSize
>> +  0,                                                                        // UINT16     FlushStride
>> +  0,                                                                        // UINT8      DutyOffset
>> +  0,                                                                        // UINT8      DutyWidth
>> +  0,                                                                        // UINT8      DayAlrm
>> +  0,                                                                        // UINT8      MonAlrm
>> +  0,                                                                        // UINT8      Century
>> +  0,                                                                        // UINT16     IaPcBootArch
>> +  0,                                                                        // UINT8      Reserved1
>> +  FADT_FLAGS,                                                               // UINT32     Flags
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  ResetReg
>> +  0,                                                                        // UINT8      ResetValue
>> +  EFI_ACPI_6_3_ARM_PSCI_COMPLIANT,                                          // UINT16     ArmBootArchFlags
>> +  EFI_ACPI_6_3_FIXED_ACPI_DESCRIPTION_TABLE_MINOR_REVISION,                 // UINT8      MinorRevision
>> +  0,                                                                        // UINT64     XFirmwareCtrl
>> +  0,                                                                        // UINT64     XDsdt
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aEvtBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bEvtBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1aCntBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm1bCntBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPm2CntBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XPmTmrBlk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe0Blk
>> +  NULL_GAS,                                                                 // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  XGpe1Blk
>> +  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepControlReg
>> +  ARM_GAS32(0),                                                             // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  SleepStatusReg
>> +  0                                                                         // UINT64 HypervisorVendorIdentity
>> +};
>> +
>> +//
>> +// Reference the table being generated to prevent the optimizer from removing the
>> +// data structure from the executable
>> +//
>> +VOID* CONST ReferenceAcpiTable = &Fadt;
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
>> new file mode 100644
>> index 000000000000..3824bd6bb956
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Gtdt.aslc
>> @@ -0,0 +1,180 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/PcdLib.h>
>> +#include <Library/AcpiLib.h>
>> +#include <IndustryStandard/Acpi63.h>
>> +#include <AcpiHeader.h>
>> +
>> +#define SYSTEM_TIMER_BASE_ADDRESS       0xFFFFFFFFFFFFFFFF
>> +#define CNT_READ_BASE_ADDRESS           0xFFFFFFFFFFFFFFFF
>> +
>> +#define SECURE_TIMER_EL1_GSIV           0x1D
>> +#define NON_SECURE_TIMER_EL1_GSIV       0x1E
>> +#define VIRTUAL_TIMER_GSIV              0x1B
>> +#define NON_SECURE_EL2_GSIV             0x1A
>> +
>> +#define GTDT_TIMER_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_MODE
>> +#define GTDT_TIMER_LEVEL_TRIGGERED  0
>> +#define GTDT_TIMER_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
>> +#define GTDT_TIMER_ACTIVE_HIGH      0
>> +#define GTDT_TIMER_SAVE_CONTEXT     EFI_ACPI_6_3_GTDT_TIMER_FLAG_ALWAYS_ON_CAPABILITY
>> +#define GTDT_TIMER_LOSE_CONTEXT     0
>> +
>> +#define GTDT_GTIMER_FLAGS          (GTDT_TIMER_LOSE_CONTEXT | GTDT_TIMER_ACTIVE_HIGH | GTDT_TIMER_LEVEL_TRIGGERED)
>> +
>> +#define WATCHDOG_COUNT              FixedPcdGet32 (PcdWatchdogCount)
>> +#define PLATFORM_TIMER_COUNT        (WATCHDOG_COUNT + 1)
>> +#define TIMER_FRAMES_COUNT          3
>> +
>> +#define GT_BLOCK_CTL_BASE               0x0000100002700000
>> +#define GT_BLOCK_FRAME0_CTL_BASE        0x0000100002710000
>> +#define GT_BLOCK_FRAME0_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
>> +#define GT_BLOCK_FRAME0_GSIV            0x58
>> +
>> +#define GT_BLOCK_FRAME1_CTL_BASE        0x0000100002720000
>> +#define GT_BLOCK_FRAME1_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
>> +#define GT_BLOCK_FRAME1_GSIV            0x59
>> +
>> +#define GT_BLOCK_FRAME2_CTL_BASE        0x0000100002730000
>> +#define GT_BLOCK_FRAME2_CTL_EL0_BASE    0xFFFFFFFFFFFFFFFF
>> +#define GT_BLOCK_FRAME2_GSIV            0x5A
>> +
>> +#define GTX_TIMER_EDGE_TRIGGERED        EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_MODE
>> +#define GTX_TIMER_LEVEL_TRIGGERED       0
>> +#define GTX_TIMER_ACTIVE_LOW            EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_FLAG_TIMER_INTERRUPT_POLARITY
>> +#define GTX_TIMER_ACTIVE_HIGH           0
>> +
>> +#define GTX_TIMER_FLAGS                 (GTX_TIMER_ACTIVE_HIGH | GTX_TIMER_LEVEL_TRIGGERED)
>> +
>> +#define GTX_TIMER_SECURE                EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_SECURE_TIMER
>> +#define GTX_TIMER_NON_SECURE            0
>> +#define GTX_TIMER_SAVE_CONTEXT          EFI_ACPI_6_3_GTDT_GT_BLOCK_COMMON_FLAG_ALWAYS_ON_CAPABILITY
>> +#define GTX_TIMER_LOSE_CONTEXT          0
>> +
>> +#define GTX_COMMON_FLAGS_S              (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_SECURE)
>> +#define GTX_COMMON_FLAGS_NS             (GTX_TIMER_SAVE_CONTEXT | GTX_TIMER_NON_SECURE)
>> +
>> +#define SBSA_WATCHDOG_REFRESH_BASE     0x00001000027D0000
>> +#define SBSA_WATCHDOG_CONTROL_BASE     0x00001000027C0000
>> +#define SBSA_WATCHDOG_GSIV             0x5C
>> +
>> +#define SBSA_WATCHDOG_EDGE_TRIGGERED   EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_MODE
>> +#define SBSA_WATCHDOG_LEVEL_TRIGGERED  0
>> +#define SBSA_WATCHDOG_ACTIVE_LOW       EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_TIMER_INTERRUPT_POLARITY
>> +#define SBSA_WATCHDOG_ACTIVE_HIGH      0
>> +#define SBSA_WATCHDOG_SECURE           EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_FLAG_SECURE_TIMER
>> +#define SBSA_WATCHDOG_NON_SECURE       0
>> +
>> +#define SBSA_WATCHDOG_FLAGS            (SBSA_WATCHDOG_NON_SECURE | SBSA_WATCHDOG_ACTIVE_HIGH | SBSA_WATCHDOG_LEVEL_TRIGGERED)
>> +
>> +#pragma pack (1)
>> +
>> +typedef struct {
>> +  EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE          Gtdt;
>> +  EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE                  GtBlock;
>> +  EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE            Frames[TIMER_FRAMES_COUNT];
>> +#if (WATCHDOG_COUNT != 0)
>> +  EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE     Watchdogs[WATCHDOG_COUNT];
>> +#endif
>> +} EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES;
>> +
>> +#pragma pack ()
>> +
>> +EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES Gtdt = {
>> +  {
>> +    __ACPI_HEADER (
>> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_SIGNATURE,
>> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLES,
>> +      EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE_REVISION
>> +    ),
>> +    SYSTEM_TIMER_BASE_ADDRESS,                              // UINT64  CntControlBasePhysicalAddress
>> +    EFI_ACPI_RESERVED_DWORD,                                // UINT32  Reserved
>> +    SECURE_TIMER_EL1_GSIV,                                  // UINT32  SecurePL1TimerGSIV
>> +    GTDT_GTIMER_FLAGS,                                      // UINT32  SecurePL1TimerFlags
>> +    NON_SECURE_TIMER_EL1_GSIV,                              // UINT32  NonSecurePL1TimerGSIV
>> +    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL1TimerFlags
>> +    VIRTUAL_TIMER_GSIV,                                     // UINT32  VirtualTimerGSIV
>> +    GTDT_GTIMER_FLAGS,                                      // UINT32  VirtualTimerFlags
>> +    NON_SECURE_EL2_GSIV,                                    // UINT32  NonSecurePL2TimerGSIV
>> +    GTDT_GTIMER_FLAGS,                                      // UINT32  NonSecurePL2TimerFlags
>> +    CNT_READ_BASE_ADDRESS,                                  // UINT64  CntReadBasePhysicalAddress
>> +    PLATFORM_TIMER_COUNT,                                   // UINT32  PlatformTimerCount
>> +    sizeof (EFI_ACPI_6_3_GENERIC_TIMER_DESCRIPTION_TABLE),  // UINT32  PlatformTimerOffset
>> +  },
>> +  {
>> +    EFI_ACPI_6_3_GTDT_GT_BLOCK,                           // UINT8 Type
>> +    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT16 Length
>> +      + sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_TIMER_STRUCTURE) *
>> +        TIMER_FRAMES_COUNT,
>> +    EFI_ACPI_RESERVED_BYTE,                               // UINT8 Reserved
>> +    GT_BLOCK_CTL_BASE,                                    // UINT64 CntCtlBase
>> +    TIMER_FRAMES_COUNT,                                   // UINT32 GTBlockTimerCount
>> +    sizeof(EFI_ACPI_6_3_GTDT_GT_BLOCK_STRUCTURE)          // UINT32 GTBlockTimerOffset
>> +  },
>> +  {
>> +    {
>> +      0,                                                    // UINT8 GTFrameNumber
>> +      {EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
>> +      GT_BLOCK_FRAME0_CTL_BASE,                             // UINT64 CntBaseX
>> +      GT_BLOCK_FRAME0_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
>> +      GT_BLOCK_FRAME0_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
>> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
>> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
>> +      0,                                                    // UINT32 GTxVirtualTimerFlags
>> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
>> +    },
>> +    {
>> +      1,                                                    // UINT8 GTFrameNumber
>> +      {EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
>> +      GT_BLOCK_FRAME1_CTL_BASE,                             // UINT64 CntBaseX
>> +      GT_BLOCK_FRAME1_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
>> +      GT_BLOCK_FRAME1_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
>> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
>> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
>> +      0,                                                    // UINT32 GTxVirtualTimerFlags
>> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
>> +    },
>> +    {
>> +      2,                                                    // UINT8 GTFrameNumber
>> +      {EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE,
>> +       EFI_ACPI_RESERVED_BYTE},                             // UINT8 Reserved[3]
>> +      GT_BLOCK_FRAME2_CTL_BASE,                             // UINT64 CntBaseX
>> +      GT_BLOCK_FRAME2_CTL_EL0_BASE,                         // UINT64 CntEL0BaseX
>> +      GT_BLOCK_FRAME2_GSIV,                                 // UINT32 GTxPhysicalTimerGSIV
>> +      GTX_TIMER_FLAGS,                                      // UINT32 GTxPhysicalTimerFlags
>> +      0,                                                    // UINT32 GTxVirtualTimerGSIV
>> +      0,                                                    // UINT32 GTxVirtualTimerFlags
>> +      GTX_COMMON_FLAGS_NS                                   // UINT32 GTxCommonFlags
>> +    },
>> +  },
>> +#if (WATCHDOG_COUNT != 0)
>> +  {
>> +    {
>> +      EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG,                      // UINT8 Type
>> +      sizeof(EFI_ACPI_6_3_GTDT_SBSA_GENERIC_WATCHDOG_STRUCTURE),    // UINT16 Length
>> +      EFI_ACPI_RESERVED_BYTE,                                       // UINT8 Reserved
>> +      SBSA_WATCHDOG_REFRESH_BASE,                                   // UINT64 RefreshFramePhysicalAddress
>> +      SBSA_WATCHDOG_CONTROL_BASE,                                   // UINT64 WatchdogControlFramePhysicalAddress
>> +      SBSA_WATCHDOG_GSIV,                                           // UINT32 WatchdogTimerGSIV
>> +      SBSA_WATCHDOG_FLAGS                                           // UINT32 WatchdogTimerFlags
>> +    }
>> +  }
>> +#endif
>> +};
>> +
>> +//
>> +// Reference the table being generated to prevent the optimizer from removing the
>> +// data structure from the executable
>> +//
>> +VOID* CONST ReferenceAcpiTable = &Gtdt;
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
>> new file mode 100644
>> index 000000000000..4413428719b8
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Hest.asl
>> @@ -0,0 +1,330 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +[0004]                          Signature : "HEST"    [Hardware Error Source Table]
>> +[0004]                       Table Length : 00000308
>> +[0001]                           Revision : 01
>> +[0001]                           Checksum : 20
>> +[0006]                             Oem ID : "Ampere"
>> +[0008]                       Oem Table ID : "Altra   "
>> +[0004]                       Oem Revision : 00000001
>> +[0004]                    Asl Compiler ID : "INTL"
>> +[0004]              Asl Compiler Revision : 20100528
>> +
>> +[0004]                 Error Source Count : 00000008
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0000
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200000
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1D00000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0001
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200008
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 00 [Polled]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1C00000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0002
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200010
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1F00000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0006
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200030
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1900000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0007
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200038
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000100000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1900001
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0003
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200018
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000500000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1D00000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0004
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200020
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 00 [Polled]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000500000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1C00000
>> +
>> +[0002]                      Subtable Type : 000A [Generic Hardware Error Source v2]
>> +[0002]                          Source Id : 0005
>> +[0002]                  Related Source Id : FFFF
>> +[0001]                           Reserved : 00
>> +[0001]                            Enabled : 01
>> +[0004]             Records To Preallocate : 00000001
>> +[0004]            Max Sections Per Record : 00000001
>> +[0004]                Max Raw Data Length : 00001000
>> +
>> +[0012]               Error Status Address : [Generic Address Structure]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000000088200028
>> +
>> +[0028]                             Notify : [Hardware Error Notification Structure]
>> +[0001]                        Notify Type : 03 [SCI]
>> +[0001]                      Notify Length : 1C
>> +[0002]         Configuration Write Enable : 0000
>> +[0004]                       PollInterval : 00000BB8
>> +[0004]                             Vector : 00000000
>> +[0004]            Polling Threshold Value : 00000000
>> +[0004]           Polling Threshold Window : 00000000
>> +[0004]              Error Threshold Value : 00000000
>> +[0004]             Error Threshold Window : 00000000
>> +
>> +[0004]          Error Status Block Length : 00001000
>> +
>> +[0012]                  Read Ack Register : [Generic Address Structure v2]
>> +[0001]                           Space ID : 00 [SystemMemory]
>> +[0001]                          Bit Width : 40
>> +[0001]                         Bit Offset : 00
>> +[0001]               Encoded Access Width : 04 [QWord Access:64]
>> +[0008]                            Address : 0000500000543010
>> +
>> +[0008]                  Read Ack Preserve : 00000000
>> +[0008]                     Read Ack Write : B1F00000
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
>> new file mode 100644
>> index 000000000000..3c0a048552cf
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Sdei.asl
>> @@ -0,0 +1,17 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +[0004]                          Signature : "SDEI"
>> +[0004]                       Table Length : 0000003E
>> +[0001]                           Revision : 01
>> +[0001]                           Checksum : 59
>> +[0006]                             Oem ID : "Ampere"
>> +[0008]                       Oem Table ID : "Altra "
>> +[0004]                       Oem Revision : 00000001
>> +[0004]                    Asl Compiler ID : "INTL"
>> +[0004]              Asl Compiler Revision : 20160930
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
>> new file mode 100644
>> index 000000000000..42042f8a3474
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Spcr.aslc
>> @@ -0,0 +1,81 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/PcdLib.h>
>> +#include <Library/AcpiLib.h>
>> +#include <IndustryStandard/Acpi63.h>
>> +#include <IndustryStandard/SerialPortConsoleRedirectionTable.h>
>> +#include <AcpiHeader.h>
>> +
>> +STATIC EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE Spcr = {
>> +  __ACPI_HEADER (
>> +    EFI_ACPI_6_3_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
>> +    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE,
>> +    EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_REVISION
>> +    ),
>> +  // UINT8                                   InterfaceType;
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERFACE_TYPE_ARM_PL011_UART,
>> +  // UINT8                                   Reserved1[3];
>> +  {
>> +    EFI_ACPI_RESERVED_BYTE,
>> +    EFI_ACPI_RESERVED_BYTE,
>> +    EFI_ACPI_RESERVED_BYTE
>> +  },
>> +  // EFI_ACPI_6_3_GENERIC_ADDRESS_STRUCTURE  BaseAddress;
>> +  ARM_GAS32 (FixedPcdGet64 (PcdSerialRegisterBase)),
>> +  // UINT8                                   InterruptType;
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_INTERRUPT_TYPE_GIC,
>> +  // UINT8                                   Irq;
>> +  0,                                         // Not used on ARM
>> +  // UINT32                                  GlobalSystemInterrupt;
>> +  FixedPcdGet32 (PL011UartInterrupt),
>> +  // UINT8                                   BaudRate;
>> +#if (FixedPcdGet64 (PcdUartDefaultBaudRate) == 9600)
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_9600,
>> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 19200)
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_19200,
>> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 57600)
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_57600,
>> +#elif (FixedPcdGet64 (PcdUartDefaultBaudRate) == 115200)
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_BAUD_RATE_115200,
>> +#else
>> +#error Unsupported SPCR Baud Rate
>> +#endif
>> +  // UINT8                                   Parity;
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_PARITY_NO_PARITY,
>> +  // UINT8                                   StopBits;
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_STOP_BITS_1,
>> +  // UINT8                                   FlowControl;
>> +  0,
>> +  // UINT8                                   TerminalType;
>> +  EFI_ACPI_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_TERMINAL_TYPE_VT_UTF8,
>> +  // UINT8                                   Reserved2;
>> +  EFI_ACPI_RESERVED_BYTE,
>> +  // UINT16                                  PciDeviceId;
>> +  0xFFFF,
>> +  // UINT16                                  PciVendorId;
>> +  0xFFFF,
>> +  // UINT8                                   PciBusNumber;
>> +  0x00,
>> +  // UINT8                                   PciDeviceNumber;
>> +  0x00,
>> +  // UINT8                                   PciFunctionNumber;
>> +  0x00,
>> +  // UINT32                                  PciFlags;
>> +  0x00000000,
>> +  // UINT8                                   PciSegment;
>> +  0x00,
>> +  // UINT32                                  Reserved3;
>> +  EFI_ACPI_RESERVED_DWORD
>> +};
>> +
>> +//
>> +// Reference the table being generated to prevent the optimizer from removing the
>> +// data structure from the executable
>> +//
>> +VOID* CONST ReferenceAcpiTable = &Spcr;
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
>> new file mode 100755
>> index 000000000000..cdb4bf5de9bf
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/Ssdt.asl
>> @@ -0,0 +1,15 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +DefinitionBlock("Ssdt.aml", "SSDT", 2, "Ampere", "Altra   ", 0x00000001)
>> +{
>> +    Method (MAIN, 0, NotSerialized)
>> +    {
>> +        Return (Zero)
>> +    }
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib library instance
  2021-06-07 22:45   ` Leif Lindholm
@ 2021-06-15 16:50     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:50 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

Hi Leif,

Thanks for reviewing. Will address all your comments from this patch.

Best regards,
Nhi

On 6/8/21 05:45, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:07 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> Provides basic features like:
>> * Screen menu to change bifurcation setting of each Root Complex. Note
>>    that we can only change the option for Root Complex which doesn't have
>>    default value in the BoardSetting.
>> * Parsing the BoardSetting and coordinate with saved setting to enable
>>    corresponding PCIe controller of each Root Complex.
>> * Config speed and lane of enabled controller.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec                 |    3 +
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf    |   60 ++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h       |   89 ++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h   |  138 +++
>>   Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h     |  102 ++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr             |  212 ++++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c         |  438 ++++++++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c   |  327 ++++++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c   | 1120 ++++++++++++++++++++
>>   Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni |   99 ++
>>   10 files changed, 2588 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> index 0d79673ce50a..a372a4e0078b 100644
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> @@ -40,6 +40,9 @@ [LibraryClasses]
>>     ##  @libraryclass  Defines a set of methods to initialize Pcie
>>     PcieCoreLib|Silicon/Ampere/AmpereAltraP/Include/Library/PcieCoreLib.h
>>   
>> +  ##  @libraryclass  Defines a set of miscellaneous PCIe functions
>> +  PcieBoardLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
>> +
>>     ##  @libraryclass  Defines a set of methods to access flash memory.
>>     FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h
>>   
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
>> new file mode 100644
>> index 000000000000..6be78f8936d7
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardLib.inf
>> @@ -0,0 +1,60 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = PcieBoardLib
>> +  FILE_GUID                      = 062191A6-E113-4FD6-84C7-E400B4B34759
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  LIBRARY_CLASS                  = PcieBoardLib
>> +
>> +[Sources]
>> +  PcieBoard.c
>> +  PcieBoardCommon.c
>> +  PcieBoardScreen.c
>> +  PcieBoardScreen.h
>> +  PcieBoardScreen.uni
>> +  NVDataStruc.h
>> +  Vfr.vfr
>> +
>> +[Packages]
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  AmpereCpuLib
>> +  BaseLib
>> +  DevicePathLib
>> +  GpioLib
>> +  HiiLib
>> +  HobLib
>> +  MemoryAllocationLib
>> +  SystemFirmwareInterfaceLib
>> +  UefiBootServicesTableLib
>> +  UefiLib
>> +  UefiRuntimeServicesTableLib
>> +
>> +[Protocols]
>> +  gEfiDevicePathProtocolGuid
>> +  gEfiHiiStringProtocolGuid                     ## CONSUMES
>> +  gEfiHiiConfigRoutingProtocolGuid              ## CONSUMES
>> +  gEfiHiiConfigAccessProtocolGuid               ## PRODUCES
>> +  gEfiHiiDatabaseProtocolGuid                   ## CONSUMES
>> +  gEfiConfigKeywordHandlerProtocolGuid          ## CONSUMES
>> +
>> +[Guids]
>> +  gEfiIfrTianoGuid                              ## CONSUMES
>> +  gPlatformManagerFormsetGuid                   ## CONSUMES
>> +  gPlatformHobGuid                              ## CONSUMES
>> +
>> +[Depex]
>> +  TRUE
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
>> new file mode 100644
>> index 000000000000..f94f12d968fd
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/NVDataStruc.h
> (Should this not be NVDataStruct.h?
>
>> @@ -0,0 +1,89 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef NVDATASTRUC_H_
>> +#define NVDATASTRUC_H_
>> +
>> +#define MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX 16
>> +
>> +#define PCIE_VARSTORE_NAME        L"PcieIfrNVData"
>> +#define PCIE_VARSTORE_ID          0x1234
>> +#define PCIE_FORM_ID              0x1235
>> +#define PCIE_RC0_FORM_ID          0x1236
>> +#define PCIE_RC1_FORM_ID          0x1237
>> +#define PCIE_RC2_FORM_ID          0x1238
>> +#define PCIE_RC3_FORM_ID          0x1239
>> +#define PCIE_RC4_FORM_ID          0x123A
>> +#define PCIE_RC5_FORM_ID          0x123B
>> +#define PCIE_RC6_FORM_ID          0x123C
>> +#define PCIE_RC7_FORM_ID          0x123D
>> +#define PCIE_RC8_FORM_ID          0x123E
>> +#define PCIE_RC9_FORM_ID          0x123F
>> +#define PCIE_RC10_FORM_ID         0x1240
>> +#define PCIE_RC11_FORM_ID         0x1241
>> +#define PCIE_RC12_FORM_ID         0x1242
>> +#define PCIE_RC13_FORM_ID         0x1243
>> +#define PCIE_RC14_FORM_ID         0x1244
>> +#define PCIE_RC15_FORM_ID         0x1245
>> +#define PCIE_FORM_SET_GUID        { 0xe84e70d6, 0xe4b2, 0x4c6e, { 0x98,  0x51, 0xcb, 0x2b, 0xac, 0x77, 0x7d, 0xbb } }
>> +
>> +#define PCIE_GOTO_ID_BASE         0x8040
> Would recommend prefix before PCIE.
> Or, given this is a fully local include - dropping the PCIE prefix.
>
>> +
>> +#pragma pack(1)
>> +
>> +//
>> +// NV data structure definition
>> +//
>> +typedef struct {
>> +  BOOLEAN RCStatus[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
>> +  UINT8   RCBifurLo[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
>> +  UINT8   RCBifurHi[MAX_AC01_PCIE_SCREEN_ROOT_COMPLEX];
>> +  UINT32  SmmuPmu;
>> +} PCIE_VARSTORE_DATA;
> Same.
>
>> +
>> +//
>> +// Labels definition
>> +//
>> +#define LABEL_UPDATE             0x2223
>> +#define LABEL_END                0x2224
>> +#define LABEL_RC0_UPDATE         0x2225
>> +#define LABEL_RC0_END            0x2226
>> +#define LABEL_RC1_UPDATE         0x2227
>> +#define LABEL_RC1_END            0x2228
>> +#define LABEL_RC2_UPDATE         0x2229
>> +#define LABEL_RC2_END            0x222A
>> +#define LABEL_RC3_UPDATE         0x222B
>> +#define LABEL_RC3_END            0x222C
>> +#define LABEL_RC4_UPDATE         0x222D
>> +#define LABEL_RC4_END            0x222E
>> +#define LABEL_RC5_UPDATE         0x222F
>> +#define LABEL_RC5_END            0x2230
>> +#define LABEL_RC6_UPDATE         0x2231
>> +#define LABEL_RC6_END            0x2232
>> +#define LABEL_RC7_UPDATE         0x2233
>> +#define LABEL_RC7_END            0x2234
>> +#define LABEL_RC8_UPDATE         0x2235
>> +#define LABEL_RC8_END            0x2236
>> +#define LABEL_RC9_UPDATE         0x2237
>> +#define LABEL_RC9_END            0x2238
>> +#define LABEL_RC10_UPDATE        0x2239
>> +#define LABEL_RC10_END           0x223A
>> +#define LABEL_RC11_UPDATE        0x223B
>> +#define LABEL_RC11_END           0x223C
>> +#define LABEL_RC12_UPDATE        0x223D
>> +#define LABEL_RC12_END           0x223E
>> +#define LABEL_RC13_UPDATE        0x223F
>> +#define LABEL_RC13_END           0x2240
>> +#define LABEL_RC14_UPDATE        0x2241
>> +#define LABEL_RC14_END           0x2242
>> +#define LABEL_RC15_UPDATE        0x2243
>> +#define LABEL_RC15_END           0x2244
>> +
>> +#pragma pack()
> Move this to just after the struct? Nothing to pack beyond that.
>
>> +
>> +#endif
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
>> new file mode 100644
>> index 000000000000..c5c50060870c
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.h
>> @@ -0,0 +1,138 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef PCIE_SCREEN_H_
>> +#define PCIE_SCREEN_H_
> Needs to not start with PCIE - additional prefix is fine.
>
>> +
>> +#include <Guid/MdeModuleHii.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/DevicePathLib.h>
>> +#include <Library/HiiLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PrintLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiDriverEntryPoint.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <Protocol/FormBrowser2.h>
>> +#include <Protocol/HiiConfigAccess.h>
>> +#include <Protocol/HiiConfigKeyword.h>
>> +#include <Protocol/HiiConfigRouting.h>
>> +#include <Protocol/HiiDatabase.h>
>> +#include <Protocol/HiiString.h>
> Move all include statements not needed by this header file to the .c
> file that actually uses them.
>
>> +
>> +#include "NVDataStruc.h"
>> +
>> +//
>> +// This is the generated IFR binary data for each formset defined in VFR.
>> +// This data array is ready to be used as input of HiiAddPackages() to
>> +// create a packagelist (which contains Form packages, String packages, etc).
>> +//
>> +extern UINT8 VfrBin[];
> Add some descriptive prefix.
> PcieBoardVfrBin?
>
>> +
>> +//
>> +// This is the generated String package data for all .UNI files.
>> +// This data array is ready to be used as input of HiiAddPackages() to
>> +// create a packagelist (which contains Form packages, String packages, etc).
>> +//
>> +extern UINT8 PcieDxeStrings[];
> Not part of PCIE or PI spec - add "Platform" or something prefix.
>
>> +
>> +#define MAX_EDITABLE_ELEMENTS 3
>> +#define PCIE_RC0_STATUS_OFFSET  \
>> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCStatus[0])
>> +#define PCIE_RC0_BIFUR_LO_OFFSET  \
>> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurLo[0])
>> +#define PCIE_RC0_BIFUR_HI_OFFSET  \
>> +  OFFSET_OF (PCIE_VARSTORE_DATA, RCBifurHi[0])
>> +#define PCIE_SMMU_PMU_OFFSET  \
>> +  OFFSET_OF (PCIE_VARSTORE_DATA, SmmuPmu)
>> +
>> +#define PCIE_SCREEN_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('P', 'C', 'I', 'E')
> This signature is supposed to be at least potentially unique.
>
>> +
>> +typedef struct {
>> +  UINTN Signature;
>> +
>> +  EFI_HANDLE         DriverHandle;
>> +  EFI_HII_HANDLE     HiiHandle;
>> +  PCIE_VARSTORE_DATA VarStoreConfig;
>> +
>> +  //
>> +  // Consumed protocol
>> +  //
>> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
>> +  EFI_HII_STRING_PROTOCOL             *HiiString;
>> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
>> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
>> +
>> +  //
>> +  // Produced protocol
>> +  //
>> +  EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
>> +} PCIE_SCREEN_PRIVATE_DATA;
> Structs need more unique prefixes.
>
>> +
>> +typedef union {
>> +  UINT16 VAR_ID;
>> +  struct _PCIE_VAR_ID {
>> +    UINT16 PciDevIndex     : 12;
>> +    UINT16 DataType        : 3;
>> +    UINT16 Always1         : 1;
>> +  } IdField;
>> +} PCIE_VAR_ID;
>> +
>> +typedef struct {
>> +  UINTN         PciDevIdx;
>> +  EFI_STRING_ID GotoStringId;
>> +  EFI_STRING_ID GotoHelpStringId;
>> +  UINT16        GotoKey;
>> +  BOOLEAN       ShowItem;
>> +} PCIE_SETUP_GOTO_DATA;
>> +
>> +typedef struct {
>> +  VOID               *StartOpCodeHandle;
>> +  VOID               *EndOpCodeHandle;
>> +  EFI_IFR_GUID_LABEL *StartLabel;
>> +  EFI_IFR_GUID_LABEL *EndLabel;
>> +
>> +} PCIE_IFR_INFO;
>> +
>> +#define PCIE_SCREEN_PRIVATE_FROM_THIS(a)  \
>> +  CR (a, PCIE_SCREEN_PRIVATE_DATA, ConfigAccess, PCIE_SCREEN_PRIVATE_DATA_SIGNATURE)
>> +
>> +#pragma pack(1)
>> +
>> +///
>> +/// HII specific Vendor Device Path definition.
>> +///
>> +typedef struct {
>> +  VENDOR_DEVICE_PATH       VendorDevicePath;
>> +  EFI_DEVICE_PATH_PROTOCOL End;
>> +} HII_VENDOR_DEVICE_PATH;
>> +
>> +#pragma pack()
>> +
>> +UINT8
>> +PcieRCDevMapLoDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  );
>> +
>> +UINT8
>> +PcieRCDevMapHiDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  );
>> +
>> +BOOLEAN
>> +PcieRCActiveDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  );
>> +
>> +#endif /* PCIE_SCREEN_H_ */
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
>> new file mode 100644
>> index 000000000000..bff5b62ba13b
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/PcieBoardLib.h
>> @@ -0,0 +1,102 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#ifndef PCIE_BOARD_LIB_H_
>> +#define PCIE_BOARD_LIB_H_
>> +
>> +#include "Pcie.h"
> OK, I'm going to stop pointing this out from this point on, but
> anything that is not referencing a direct aspect of the PCIe
> specification should not be named PCIE*/Pcie*, ...
> These names are reserved.
>
> Since most of these symbols are internal anyway, and reference only
> settings inside the PCIE configuration screen, I think the cleanest
> thing would be to drop the PCIE/Pcie prefixes altogether.
>
>> +
>> +/**
>> +
>> +  Check if a PCIE port enabled in the board configuration.
>> +
>> +  @param  Index                     The port index.
>> +
>> +  @retval                           TRUE if the port enabled, otherwise FALSE.
>> +
>> +**/
>> +BOOLEAN
>> +PcieBoardCheckSysSlotEnabled (
>> +  IN UINTN Index
>> +  );
>> +
>> +VOID
>> +PcieBoardGetRCSegmentNumber (
>> +  IN  AC01_RC *RC,
>> +  OUT UINTN   *SegmentNumber
>> +  );
>> +
>> +/**
>> +
>> +  Check if SMM PMU enabled in board screen
>> +
>> +  @retval                           TRUE if the SMMU PMU enabled, otherwise FALSE.
>> +
>> +**/
>> +BOOLEAN
>> +PcieBoardCheckSmmuPmuEnabled (
>> +  VOID
>> +  );
>> +
>> +/**
>> +
>> +  Build UEFI menu.
>> +
>> +  @param  ImageHandle               Handle.
>> +  @param  SystemTable               Pointer to System Table.
>> +  @param  RCList                    List of Root Complex with properties.
>> +
>> +  @retval                           EFI_SUCCESS if successful, otherwise EFI_ERROR.
>> +
>> +**/
>> +EFI_STATUS
>> +PcieBoardScreenInitialize (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable,
>> +  IN AC01_RC          *RCList
>> +  );
>> +
>> +BOOLEAN
>> +IsEmptyRC (
>> +  IN AC01_RC *RC
>> +  );
>> +
>> +VOID
>> +PcieBoardSetupDevmap (
>> +  IN AC01_RC *RC
>> +  );
>> +
>> +VOID
>> +PcieBoardGetLaneAllocation (
>> +  IN AC01_RC *RC
>> +  );
>> +
>> +VOID
>> +PcieBoardGetSpeed (
>> +  IN AC01_RC *RC
>> +  );
>> +
>> +VOID
>> +PcieBoardParseRCParams (
>> +  IN AC01_RC *RC
>> +  );
>> +
>> +VOID
>> +PcieBoardAssertPerst (
>> +  AC01_RC *RC,
>> +  UINT32  PcieIndex,
>> +  UINT8   Bifurcation,
>> +  BOOLEAN isPullToHigh
>> +  );
>> +
>> +BOOLEAN
>> +PcieBoardCheckSmmuPmuEnabled (
>> +  VOID
>> +  );
>> +
>> +#endif /* PCIE_BOARD_LIB_H_ */
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
>> new file mode 100644
>> index 000000000000..a596d5ac9a92
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/Vfr.vfr
>> @@ -0,0 +1,212 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include "NVDataStruc.h"
>> +
>> +formset
>> +  guid    = PCIE_FORM_SET_GUID,
>> +  title   = STRING_TOKEN(STR_PCIE_FORM),
>> +  help    = STRING_TOKEN(STR_PCIE_FORM_HELP),
>> +  classguid = gPlatformManagerFormsetGuid,
>> +
>> +  //
>> +  // Define a variable Storage
>> +  //
>> +  varstore PCIE_VARSTORE_DATA,
>> +    varid = PCIE_VARSTORE_ID,
>> +    name  = PcieIfrNVData,
>> +    guid  = PCIE_FORM_SET_GUID;
>> +
>> +  form
>> +    formid = PCIE_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_FORM);
>> +
>> +    label LABEL_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC0_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC0_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC0_FORM);
>> +
>> +    label LABEL_RC0_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC0_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC1_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC1_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC1_FORM);
>> +
>> +    label LABEL_RC1_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC1_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC2_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC2_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC2_FORM);
>> +
>> +    label LABEL_RC2_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC2_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC3_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC3_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC3_FORM);
>> +
>> +    label LABEL_RC3_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC3_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC4_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC4_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC4_FORM);
>> +
>> +    label LABEL_RC4_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC4_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC5_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC5_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC5_FORM);
>> +
>> +    label LABEL_RC5_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC5_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC6_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC6_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC6_FORM);
>> +
>> +    label LABEL_RC6_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC6_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC7_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC7_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC7_FORM);
>> +
>> +    label LABEL_RC7_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC7_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC8_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC8_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC8_FORM);
>> +
>> +    label LABEL_RC8_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC8_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC9_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC9_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC9_FORM);
>> +
>> +    label LABEL_RC9_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC9_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC10_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC10_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC10_FORM);
>> +
>> +    label LABEL_RC10_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC10_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC11_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC11_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC11_FORM);
>> +
>> +    label LABEL_RC11_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC11_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC12_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC12_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC12_FORM);
>> +
>> +    label LABEL_RC12_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC12_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC13_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC13_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC13_FORM);
>> +
>> +    label LABEL_RC13_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC13_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC14_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC14_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC14_FORM);
>> +
>> +    label LABEL_RC14_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC14_END;
>> +  endform;
>> +
>> +  form
>> +    formid = PCIE_RC15_FORM_ID,
>> +    title = STRING_TOKEN(STR_PCIE_RC15_FORM);
>> +
>> +    subtitle text = STRING_TOKEN(STR_PCIE_RC15_FORM);
>> +
>> +    label LABEL_RC15_UPDATE;
>> +    // dynamic content here
>> +    label LABEL_RC15_END;
>> +  endform;
>> +
>> +endformset;
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
>> new file mode 100644
>> index 000000000000..c0c94d349b5b
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoard.c
>> @@ -0,0 +1,438 @@
>> +/** @file
>> +
>> +  Pcie board specific driver to handle asserting PERST signal to Endpoint
>> +  card and parsing NVPARAM board settings for bifurcation programming.
>> +
>> +  PERST asserting is via group of GPIO pins to CPLD as Platform Specification.
>> +
>> +  NVPARAM board settings is spec-ed within Firmware Interface Requirement.
>> +  Bifuration devmap is programmed before at SCP following the rule
>> +
>> +  Root Complex Type-A devmap settings (RP == Root Port)
>> +  -----------------------------------------
>> +  | RP0   | RP1  | RP2  | RP3  | Devmap   |
>> +  | (x16) | (x4) | (x8) | (x4) | (output) |
>> +  -------------------------------------------
>> +  |  Y    |  N   |  N   |  N   | 0        |
>> +  |  Y    |  N   |  Y   |  N   | 1        |
>> +  |  Y    |  N   |  Y   |  Y   | 2        |
>> +  |  Y    |  Y   |  Y   |  Y   | 3        |
>> +  -----------------------------------------
>> +
>> +  Root Complex Type-B LO (aka RCBxA) devmap settings (RP == Root Port)
>> +  ----------------------------------------
>> +  | RP0  | RP1  | RP2  | RP3  | Devmap   |
>> +  | (x8) | (x2) | (x4) | (x3) | (output) |
>> +  ----------------------------------------
>> +  |  Y   |  N   |  N   |  N   | 0        |
>> +  |  Y   |  N   |  Y   |  N   | 1        |
>> +  |  Y   |  N   |  Y   |  Y   | 2        |
>> +  |  Y   |  Y   |  Y   |  Y   | 3        |
>> +  ----------------------------------------
>> +
>> +  Root Complex Type-B LO (aka RCBxB) devmap settings (RP == Root Port)
>> +  ----------------------------------------
>> +  | RP4  | RP5  | RP6  | RP7  | Devmap   |
>> +  | (x8) | (x2) | (x4) | (x3) | (output) |
>> +  ----------------------------------------
>> +  |  Y   |  N   |  N   |  N   | 0        |
>> +  |  Y   |  N   |  Y   |  N   | 1        |
>> +  |  Y   |  N   |  Y   |  Y   | 2        |
>> +  |  Y   |  Y   |  Y   |  Y   | 3        |
>> +  ----------------------------------------
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/GpioLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/PcieBoardLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <NVDataStruc.h>
>> +#include <NVParamDef.h>
>> +#include <Pcie.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +#ifndef BIT
>> +#define BIT(nr)                         (1 << (nr))
>> +#endif
>> +
>> +extern CHAR16   VariableName[];
>> +extern EFI_GUID gPcieFormSetGuid;
>> +
>> +VOID
>> +EFIAPI
>> +PcieBoardLoadPreset (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  UINT32 Nv;
>> +  INTN   NvParam;
>> +  INTN   Ret;
>> +  INTN   i;
>> +
>> +  // Load default value
>> +  for (i = 0; i < MAX_PCIE_B; i++) {
>> +    RC->PresetGen3[i] = PRESET_INVALID;
>> +    RC->PresetGen4[i] = PRESET_INVALID;
>> +  }
>> +
>> +  // Load override value
>> +  if (RC->Socket == 0) {
>> +    if (RC->Type == RCA) {
>> +      if (RC->ID < 4) {
> There are various live-coded values of 4 and 2 in this function.
> Please replace them with #defines with descriptive names to improve readability.
>
>> +        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G3PRESET + RC->ID * NVPARAM_SIZE;
>> +      } else {
>> +        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
>> +      }
>> +    } else {
>> +      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
>> +    }
>> +  } else if (RC->Type == RCA) {
>> +    if (RC->ID < 4) {
>> +      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G3PRESET + (RC->ID - 2) * NVPARAM_SIZE;
>> +    } else {
>> +      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G3PRESET + (RC->ID - 4) * NVPARAM_SIZE;
>> +    }
>> +  } else {
>> +    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G3PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
>> +  }
>> +
>> +  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
>> +  if (Ret == EFI_SUCCESS) {
>> +    for (i = 0; i < 4; i++) {
>> +      RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
>> +    }
>> +  }
>> +
>> +  if (RC->Type == RCB) {
>> +    NvParam += NVPARAM_SIZE;
>> +    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
>> +    if (Ret == EFI_SUCCESS) {
>> +      for (i = 0; i < 4; i++) {
>> +        RC->PresetGen3[i] = (Nv >> (NVPARAM_SIZE * i)) & 0xFF;
>> +      }
>> +    }
>> +  }
>> +
>> +  if (RC->Socket == 0) {
>> +    if (RC->Type == RCA) {
>> +      if (RC->ID < 4) {
>> +        NvParam = NV_SI_RO_BOARD_S0_RCA0_TXRX_G4PRESET + RC->ID * NVPARAM_SIZE;
>> +      } else {
>> +        NvParam = NV_SI_RO_BOARD_S0_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
>> +      }
>> +    } else {
>> +      NvParam = NV_SI_RO_BOARD_S0_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
>> +    }
>> +  } else if (RC->Type == RCA) {
>> +    if (RC->ID < 4) {
>> +      NvParam = NV_SI_RO_BOARD_S1_RCA2_TXRX_G4PRESET + (RC->ID - 2) * NVPARAM_SIZE;
>> +    } else {
>> +      NvParam = NV_SI_RO_BOARD_S1_RCA4_TXRX_G4PRESET + (RC->ID - 4) * NVPARAM_SIZE;
>> +    }
>> +  } else {
>> +    NvParam = NV_SI_RO_BOARD_S1_RCB0A_TXRX_G4PRESET + (RC->ID - 4) * (2 * NVPARAM_SIZE);
>> +  }
>> +
>> +  Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
>> +  if (Ret == EFI_SUCCESS) {
>> +    for (i = 0; i < 4; i++) {
>> +      RC->PresetGen4[i] = (Nv >> (8 * i)) & 0xFF;
>> +    }
>> +  }
>> +
>> +  if (RC->Type == RCB) {
>> +    NvParam += NVPARAM_SIZE;
>> +    Ret = NVParamGet ((NVPARAM)NvParam, NV_PERM_ALL, &Nv);
>> +    if (Ret == EFI_SUCCESS) {
>> +      for (i = 0; i < 4; i++) {
>> +        RC->PresetGen4[i + 4] = (Nv >> (8 * i)) & 0xFF;
>> +      }
>> +    }
>> +  }
>> +}
>> +
>> +VOID
>> +EFIAPI
>> +PcieBoardParseRCParams (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  UINT32             Efuse;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  UINT8              PlatRCId;
>> +  EFI_STATUS         Status;
>> +  VOID               *Hob;
>> +  UINTN              BufferSize;
>> +  PCIE_VARSTORE_DATA VarStoreConfig = {
>> +    .RCStatus = {TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE,
>> +                 TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE},
>> +    .RCBifurLo = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
>> +    .RCBifurHi = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
>> +    .SmmuPmu = 0
>> +  };
>> +
>> +  PCIE_DEBUG ("%a - Socket%d RC%d\n", __FUNCTION__, RC->Socket, RC->ID);
>> +
>> +  PlatRCId = RC->Socket * RCS_PER_SOCKET + RC->ID;
>> +  // Get RC activation status
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = gRT->GetVariable (
>> +                  VariableName,
>> +                  &gPcieFormSetGuid,
>> +                  NULL,
>> +                  &BufferSize,
>> +                  &VarStoreConfig
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    PCIE_DEBUG ("%a - Failed to read PCIE variable data from config store.\n", __FUNCTION__);
>> +  }
>> +
>> +  RC->Active = VarStoreConfig.RCStatus[PlatRCId];
>> +  RC->DevMapLo = VarStoreConfig.RCBifurLo[PlatRCId];
>> +  RC->DevMapHi = VarStoreConfig.RCBifurHi[PlatRCId];
>> +
>> +  PCIE_DEBUG (
>> +    "%a - Socket%d RC%d is %s\n",
>> +    __FUNCTION__,
>> +    RC->Socket,
>> +    RC->ID,
>> +    (RC->Active) ? "ACTIVE" : "INACTIVE"
>> +    );
>> +
>> +  if (!IsSlaveSocketActive () && RC->Socket == 1) {
>> +    RC->Active = FALSE;
>> +  }
>> +
>> +  if (RC->Active) {
>> +    //
>> +    // Consolidate with E-fuse
>> +    //
>> +    Efuse = 0;
>> +    Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +    if (Hob != NULL) {
>> +      PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +      Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
>> +      PCIE_DEBUG (
>> +        "RcDisableMask[0]: 0x%x [1]: 0x%x\n",
>> +        PlatformHob->RcDisableMask[0],
>> +        PlatformHob->RcDisableMask[1]
>> +        );
>> +
>> +      // Update errata flags for Ampere Altra
>> +      if ((PlatformHob->ScuProductId[0] & 0xff) == 0x01) {
>> +        if (PlatformHob->AHBCId[0] == 0x20100
>> +            || PlatformHob->AHBCId[0] == 0x21100
>> +            || (IsSlaveSocketActive ()
>> +                && (PlatformHob->AHBCId[1] == 0x20100
>> +                    || PlatformHob->AHBCId[1] == 0x21100)))
>> +        {
>> +          RC->Flags |= PCIE_ERRATA_SPEED1;
>> +          PCIE_DEBUG ("RC[%d]: Flags 0x%x\n", RC->ID, RC->Flags);
>> +        }
>> +      }
>> +    }
>> +
>> +    RC->Active = (RC->Active && !(Efuse & BIT (PlatRCId))) ? TRUE : FALSE;
>> +  }
>> +
>> +  /* Load Gen3/Gen4 preset */
>> +  PcieBoardLoadPreset (RC);
>> +  PcieBoardGetLaneAllocation (RC);
>> +  PcieBoardSetupDevmap (RC);
>> +  PcieBoardGetSpeed (RC);
>> +}
>> +
>> +VOID
>> +EFIAPI
>> +PcieBoardReleaseAllPerst (
>> +  IN UINT8 SocketId
>> +  )
>> +{
>> +  UINT32 GpioIndex, GpioPin;
>> +
>> +  // Write 1 to all GPIO[16..21] to release all PERST
>> +  GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * SocketId + 16;
>> +  for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
>> +    GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
>> +  }
>> +}
>> +
>> +VOID
>> +EFIAPI
>> +PcieBoardAssertPerst (
>> +  AC01_RC *RC,
>> +  UINT32  PcieIndex,
>> +  UINT8   Bifurcation,
>> +  BOOLEAN isPullToHigh
> CamelCase uses leading capital letter.
>
>> +  )
>> +{
>> +  UINT32 GpioGroupVal, Val, GpioIndex, GpioPin;
>> +
>> +  /*
>> +   * For Post-silicon, Fansipan board is using GPIO combination (GPIO[16..21])
>> +   * to control CPLD.
>> +   * It should be follow PCIE RESET TABLE in Fansipan schematic.
>> +   *
>> +   * Depend on Bifurcation settings, will active corresponding PERST pin or not
>> +   */
>> +
>> +  if (RC->Type == RCA) {
>> +    switch (Bifurcation) {
>> +    case 0:                 // RCA_BIFURCATION_ONE_X16:
>> +      if (PcieIndex != 0) { // 1,2,3
>> +      }
>> +      break;
>> +
>> +    case 1:                                       // RCA_BIFURCATION_TWO_X8:
> Wouldn't this look an awful lot better as
>    case RCA_BIFURCATION_TWO_X8:
> than with a live-coded integer, followed by a comment explaining what
> that integer means?
> This appplies throughout this function.
>
>> +      if ((PcieIndex == 1) || (PcieIndex == 3)) { // 1,3
>> +      }
>> +      break;
>> +
>> +    case 2:                 // RCA_BIFURCATION_ONE_X8_TWO_X4:
>> +      if (PcieIndex == 1) { // 1
>> +      }
>> +      break;
>> +
>> +    case 3: // RCA_BIFURCATION_FOUR_X4:
>> +      break;
>> +
>> +    default:
>> +      PCIE_DEBUG ("Invalid Bifurcation setting\n");
>> +      break;
>> +    }
>> +  } else { // RCB
>> +    switch (Bifurcation) {
>> +    case 0:                                       // RCB_BIFURCATION_ONE_X8:
>> +      if ((PcieIndex != 0) && (PcieIndex != 4)) { // 1,2,3,5,6,7
>> +      }
>> +      break;
>> +
>> +    case 1:                       // RCB_BIFURCATION_TWO_X4:
>> +      if ((PcieIndex % 2) != 0) { // 1,3,5,7
>> +      }
>> +      break;
>> +
>> +    case 2: // RCB_BIFURCATION_ONE_X4_TWO_X2:
>> +      if ((PcieIndex == 1) || (PcieIndex == 5)) {
>> +      }
>> +      break;
>> +
>> +    case 3: // RCB_BIFURCATION_FOUR_X2:
>> +      break;
>> +
>> +    default:
>> +      PCIE_DEBUG ("Invalid Bifurcation setting\n");
>> +      break;
>> +    }
>> +  }
>> +
>> +  if (!isPullToHigh) { // Pull PERST to Low
>> +    if (RC->Type == RCA) { // RCA: RC->ID: 0->3 ; PcieIndex: 0->3
>> +      GpioGroupVal = 62 - RC->ID*4 - PcieIndex;
> That 62 needs to be a #define.
>
>> +    }
>> +    else { // RCB: RC->ID: 4->7 ; PcieIndex: 0->7
> else on same line as }
>
>> +      GpioGroupVal = 46 - (RC->ID - 4)*8 - PcieIndex;
>> +    }
>> +
>> +    GpioPin = GPIO_DWAPB_PINS_PER_SOCKET * RC->Socket + 16;
>> +    for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
>> +      // 6: Number of GPIO pins to control via CPLD
>> +      Val = (GpioGroupVal & 0x3F) & (1 << GpioIndex);
>> +      if (Val == 0) {
>> +        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_LOW);
>> +      } else {
>> +        GpioModeConfig (GpioPin + GpioIndex, GPIO_CONFIG_OUT_HI);
>> +      }
>> +    }
>> +
>> +    // Keep reset as low as 100 ms as specification
>> +    MicroSecondDelay (100 * 1000);
>> +  } else { // Pull PERST to High
>> +    PcieBoardReleaseAllPerst (RC->Socket);
>> +  }
>> +}
>> +
>> +/**
>> + * Overrride the segment number for a root complex with
>> + * a board specific number.
>> + **/
>> +VOID
>> +EFIAPI
>> +PcieBoardGetRCSegmentNumber (
>> +  IN  AC01_RC *RC,
>> +  OUT UINTN   *SegmentNumber
>> +  )
>> +{
>> +  if (RC->Socket == 0) {
>> +    if (RC->Type == RCA) {
>> +      switch (RC->ID) {
>> +      case 0:
>> +        *SegmentNumber = 12;
>> +        break;
>> +
>> +      case 1:
>> +        *SegmentNumber = 13;
>> +        break;
>> +
>> +      case 2:
>> +        *SegmentNumber = 1;
>> +        break;
>> +
>> +      case 3:
>> +        *SegmentNumber = 0;
>> +        break;
>> +
>> +        default:
>> +          *SegmentNumber = 16;
>> +      }
>> +    } else { /* Socket0, CCIX: RCA0 and RCA1 */
>> +      *SegmentNumber = RC->ID - 2;
>> +    }
>> +  } else { /* Socket1, CCIX: RCA0 and RCA1 */
>> +    if (RC->ID == 0 || RC->ID == 1) {
>> +      *SegmentNumber = 16;
>> +    } else {
>> +      *SegmentNumber = 4 + RC->ID;
>> +    }
>> +  }
>> +}
>> +
>> +BOOLEAN
>> +EFIAPI
>> +PcieBoardCheckSmmuPmuEnabled (
>> +  VOID
>> +  )
>> +{
>> +  EFI_GUID           PcieFormSetGuid = PCIE_FORM_SET_GUID;
>> +  PCIE_VARSTORE_DATA VarStoreConfig;
>> +  UINTN              BufferSize;
>> +  EFI_STATUS         Status;
>> +
>> +  // Get Buffer Storage data from EFI variable
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = gRT->GetVariable (
>> +                  PCIE_VARSTORE_NAME,
>> +                  &PcieFormSetGuid,
>> +                  NULL,
>> +                  &BufferSize,
>> +                  &VarStoreConfig
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return FALSE;
>> +  }
>> +
>> +  return VarStoreConfig.SmmuPmu;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
>> new file mode 100644
>> index 000000000000..a8accbf53047
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardCommon.c
>> @@ -0,0 +1,327 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Library/DebugLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/SystemFirmwareInterfaceLib.h>
>> +#include <NVParamDef.h>
>> +
>> +#include "Pcie.h"
>> +
>> +/* Host bridge registers */
>> +#define HBRCAPDMR    0x0
>> +#define HBRCBPDMR    0x4
> Inappropriate names for this codebase.
> Are these the actual register names as described in hardware manuals
> for this device? If so, they can be permitted. But every file where
> these names are used need to contain a glossary section at the start
> of it, explaining what these actually are.
> Applies also below.
>
>> +
>> +/* HBRCAPDMR */
>> +#define RCAPCIDEVMAP_SET(dst, src) \
>> +  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
>> +
>> +/* HBRCBPDMR */
>> +#define RCBPCIDEVMAPLO_SET(dst, src) \
>> +  (((dst) & ~0x7) | (((UINT32)(src)) & 0x7))
>> +#define RCBPCIDEVMAPHI_SET(dst, src) \
>> +  (((dst) & ~0x70) | (((UINT32)(src) << 4) & 0x70))
>> +
>> +#define PCIE_GET_MAX_WIDTH(Pcie, Max) \
>> +  !((Pcie).MaxWidth) ? (Max) : MIN((Pcie).MaxWidth, (Max))
>> +
>> +BOOLEAN
>> +IsEmptyRC (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  INTN Idx;
>> +
>> +  for (Idx = PCIE_0; Idx < MAX_PCIE; Idx++) {
>> +    if (RC->Pcie[Idx].Active) {
>> +      return FALSE;
>> +    }
>> +  }
>> +
>> +  return TRUE;
>> +}
>> +
>> +VOID
>> +PcieBoardSetRCBifur (
>> +  IN AC01_RC *RC,
>> +  IN UINT8   RPStart,
>> +  IN UINT8   DevMap
>> +  )
>> +{
>> +  UINT8 MaxWidth;
>> +
>> +  if (RPStart != PCIE_0 && RPStart != PCIE_4) {
>> +    return;
>> +  }
>> +
>> +  if (RC->Type != RCB && RPStart == PCIE_4) {
>> +    return;
>> +  }
>> +
>> +  if (RC->Type == RCA && RC->Pcie[RPStart].MaxWidth == LNKW_X16) {
>> +    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X4;
>> +    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X8;
>> +    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X4;
>> +  }
>> +
>> +  if (RC->Type == RCB && RC->Pcie[RPStart].MaxWidth == LNKW_X8) {
>> +    RC->Pcie[RPStart + 1].MaxWidth = LNKW_X2;
>> +    RC->Pcie[RPStart + 2].MaxWidth = LNKW_X4;
>> +    RC->Pcie[RPStart + 3].MaxWidth = LNKW_X2;
>> +  }
>> +
>> +  switch (DevMap) {
>> +  case 1:
> Would benefit from #defines with descriptive names rather than just
> live-coded integers. (All cases in switch.)
>
>> +    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
>> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
>> +    RC->Pcie[RPStart + 1].Active = 0;
>> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
>> +    RC->Pcie[RPStart + 2].Active = 1;
>> +    RC->Pcie[RPStart + 3].Active = 0;
>> +    break;
>> +
>> +  case 2:
>> +    MaxWidth = (RC->Type == RCA) ? LNKW_X8 : LNKW_X4;
>> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
>> +    RC->Pcie[RPStart + 1].Active = 0;
>> +    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
>> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
>> +    RC->Pcie[RPStart + 2].Active = 1;
>> +    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
>> +    RC->Pcie[RPStart + 3].Active = 1;
>> +    break;
>> +
>> +  case 3:
>> +    MaxWidth = (RC->Type == RCA) ? LNKW_X4 : LNKW_X2;
>> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
>> +    RC->Pcie[RPStart + 1].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 1], MaxWidth);
>> +    RC->Pcie[RPStart + 1].Active = 1;
>> +    RC->Pcie[RPStart + 2].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 2], MaxWidth);
>> +    RC->Pcie[RPStart + 2].Active = 1;
>> +    RC->Pcie[RPStart + 3].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart + 3], MaxWidth);
>> +    RC->Pcie[RPStart + 3].Active = 1;
>> +    break;
>> +
>> +  case 0:
>> +  default:
>> +    MaxWidth = (RC->Type == RCA) ? LNKW_X16 : LNKW_X8;
>> +    RC->Pcie[RPStart].MaxWidth = PCIE_GET_MAX_WIDTH (RC->Pcie[RPStart], MaxWidth);
>> +    RC->Pcie[RPStart + 1].Active = 0;
>> +    RC->Pcie[RPStart + 2].Active = 0;
>> +    RC->Pcie[RPStart + 3].Active = 0;
>> +    break;
>> +  }
>> +}
>> +
>> +VOID
>> +PcieBoardGetLaneAllocation (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  INTN    RPIndex, Ret;
>> +  UINT32  Nv, Width;
>> +  NVPARAM NvParam;
>> +
>> +  // Retrieve lane allocation and capabilities for each controller
>> +  if (RC->Type == RCA) {
>> +    NvParam = NV_SI_RO_BOARD_S0_RCA0_CFG + RC->Socket * 96 +
>> +                RC->ID * 8;
>> +  } else {
>> +    NvParam = NV_SI_RO_BOARD_S0_RCB0_LO_CFG + RC->Socket * 96 +
>> +              (RC->ID - MAX_RCA) * 16;
>> +  }
> Please create descriptively named #defines for that 96, 16, and 8.
>
>> +
>> +  Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
>> +  Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
>> +
>> +  for (RPIndex = 0; RPIndex < MAX_PCIE_A; RPIndex++) {
>> +    Width = (Nv >> (RPIndex * 8)) & 0xF;
>> +    switch (Width) {
>> +    case 1:
>> +    case 2:
>> +    case 3:
>> +    case 4:
>> +      RC->Pcie[RPIndex].MaxWidth = 1 << Width;
>> +      RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
>> +      RC->Pcie[RPIndex].Active = TRUE;
>> +      break;
>> +
>> +    case 0:
>> +    default:
>> +      RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
>> +      RC->Pcie[RPIndex].MaxGen = 0;
>> +      RC->Pcie[RPIndex].Active = FALSE;
>> +      break;
>> +    }
>> +  }
>> +
>> +  if (RC->Type == RCB) {
>> +    // Processing Hi
>> +    NvParam += 8;
>> +    Ret = NVParamGet (NvParam, NV_PERM_ALL, &Nv);
>> +    Nv = (Ret != EFI_SUCCESS) ? 0 : Nv;
>> +
>> +    for (RPIndex = MAX_PCIE_A; RPIndex < MAX_PCIE; RPIndex++) {
>> +      Width = (Nv >> ((RPIndex - MAX_PCIE_A) * 8)) & 0xF;
> Same 8?
>
>> +      switch (Width) {
>> +      case 1:
>> +      case 2:
>> +      case 3:
>> +      case 4:
>> +        RC->Pcie[RPIndex].MaxWidth = 1 << Width;
>> +        RC->Pcie[RPIndex].MaxGen = SPEED_GEN3;
>> +        RC->Pcie[RPIndex].Active = TRUE;
>> +        break;
>> +
>> +      case 0:
>> +      default:
>> +        RC->Pcie[RPIndex].MaxWidth = LNKW_NONE;
>> +        RC->Pcie[RPIndex].MaxGen = 0;
>> +        RC->Pcie[RPIndex].Active = FALSE;
>> +        break;
>> +      }
>> +    }
>> +  }
>> +
>> +  // Do not proceed if no Root Port enabled
>> +  if (IsEmptyRC (RC)) {
>> +    RC->Active = FALSE;
>> +  }
>> +}
>> +
>> +VOID
>> +PcieBoardSetupDevmap (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  UINT32 Val;
>> +
>> +  if (RC->Pcie[PCIE_0].Active
>> +      && RC->Pcie[PCIE_1].Active
>> +      && RC->Pcie[PCIE_2].Active
>> +      && RC->Pcie[PCIE_3].Active)
>> +  {
>> +    RC->DefaultDevMapLo = 3;
> What's a DefaultDevMapLo?
> The *only* benefit of SuperLongCamelCaseNames is that they actually
> completely spell out what things are. This makes abbreviating them
> extremely unfortunate, except where the abbreviation is completely
> obvious regardless of context.
>
> I also have a feeling these 0, 1, 2, 3 could benefit from being
> replaced by descriptively named #defines.
>
>> +  } else if (RC->Pcie[PCIE_0].Active
>> +             && RC->Pcie[PCIE_2].Active
>> +             && RC->Pcie[PCIE_3].Active)
>> +  {
>> +    RC->DefaultDevMapLo = 2;
>> +  } else if (RC->Pcie[PCIE_0].Active
>> +             && RC->Pcie[PCIE_2].Active)
>> +  {
>> +    RC->DefaultDevMapLo = 1;
>> +  } else {
>> +    RC->DefaultDevMapLo = 0;
>> +  }
>> +
>> +  if (RC->Pcie[PCIE_4].Active
>> +      && RC->Pcie[PCIE_5].Active
>> +      && RC->Pcie[PCIE_6].Active
>> +      && RC->Pcie[PCIE_7].Active)
>> +  {
>> +    RC->DefaultDevMapHi = 3;
>> +  } else if (RC->Pcie[PCIE_4].Active
>> +             && RC->Pcie[PCIE_6].Active
>> +             && RC->Pcie[PCIE_7].Active)
>> +  {
>> +    RC->DefaultDevMapHi = 2;
>> +  } else if (RC->Pcie[PCIE_4].Active
>> +             && RC->Pcie[PCIE_6].Active)
>> +  {
>> +    RC->DefaultDevMapHi = 1;
>> +  } else {
>> +    RC->DefaultDevMapHi = 0;
>> +  }
>> +
>> +  if (RC->DevMapLo == 0) {
>> +    RC->DevMapLo = RC->DefaultDevMapLo;
>> +  }
>> +
>> +  if (RC->Type == RCB && RC->DevMapHi == 0) {
>> +    RC->DevMapHi = RC->DefaultDevMapHi;
>> +  }
>> +
>> +  PcieBoardSetRCBifur (RC, PCIE_0, RC->DevMapLo);
>> +  if (RC->Type == RCB) {
>> +    PcieBoardSetRCBifur (RC, PCIE_4, RC->DevMapHi);
>> +  }
>> +
>> +  if (RC->Active) {
>> +    if (RC->Type == RCA) {
>> +      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCAPDMR, &Val))) {
>> +        Val = RCAPCIDEVMAP_SET (Val, RC->DevMapLo & 0x7);
> Is this actively trying to obscure away runtime errors, or
> are there valid situations where RC->DevMapLo may be higher than 7
> and only the bottom 3 bits should be respected?
> If so, a comment should explain.
>
>> +        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCAPDMR, Val);
>> +      }
>> +    } else {
>> +      if (!EFI_ERROR (MailboxMsgRegisterRead (RC->Socket, RC->HBAddr + HBRCBPDMR, &Val))) {
>> +        Val = RCBPCIDEVMAPLO_SET (Val, RC->DevMapLo & 0x7);
>> +        Val = RCBPCIDEVMAPHI_SET (Val, RC->DevMapHi & 0x7);
> Is this actively trying to obscure away runtime errors, or
> are there valid situations where RC->DevMapLo or RC->DevMapHi may be
> higher than 7 and only the bottom 3 bits should be respected?
> If so, a comment should explain.
>
>> +        MailboxMsgRegisterWrite (RC->Socket, RC->HBAddr + HBRCBPDMR, Val);
>> +      }
>> +    }
>> +  }
>> +}
>> +
>> +VOID
>> +PcieBoardGetSpeed (
>> +  IN AC01_RC *RC
>> +  )
>> +{
>> +  UINT8 MaxGenTbl[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN4, SPEED_GEN4 };         // Bifurcation 0: RCA x16 / RCB x8
>> +  UINT8 MaxGenTblX8X4X4[MAX_PCIE_A] = { SPEED_GEN4, SPEED_GEN4, SPEED_GEN1, SPEED_GEN1 };   // Bifurcation 2: x8 x4 x4 (PCIE_ERRATA_SPEED1)
>> +  UINT8 MaxGenTblX4X4X4X4[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 }; // Bifurcation 3: x4 x4 x4 x4 (PCIE_ERRATA_SPEED1)
>> +  UINT8 MaxGenTblRCB[MAX_PCIE_A] = { SPEED_GEN1, SPEED_GEN1, SPEED_GEN1, SPEED_GEN1 };      // RCB PCIE_ERRATA_SPEED1
>> +  INTN  RPIdx;
>> +  UINT8 *MaxGen;
>> +
>> +  ASSERT (MAX_PCIE_A == 4);
>> +  ASSERT (MAX_PCIE == 8);
>> +
>> +  //
>> +  // Due to hardware errata, for A0/A1*
>> +  //  RCB is limited to Gen1 speed.
>> +  //  RCA x16, x8 port supports up to Gen4,
>> +  //  RCA x4 port only supports Gen1.
>> +  //
>> +  MaxGen = MaxGenTbl;
>> +  if (RC->Type == RCB) {
>> +    if (RC->Flags & PCIE_ERRATA_SPEED1) {
>> +      MaxGen = MaxGenTblRCB;
>> +    }
>> +  } else {
>> +    switch (RC->DevMapLo) {
>> +    case 2: /* x8 x4 x4 */
> #define for these 2, 3, and 1.
>
>> +      if (RC->Flags & PCIE_ERRATA_SPEED1) {
>> +        MaxGen = MaxGenTblX8X4X4;
>> +      }
>> +      break;
>> +
>> +    case 3: /* X4 x4 x4 x4 */
>> +      if (RC->Flags & PCIE_ERRATA_SPEED1) {
>> +        MaxGen = MaxGenTblX4X4X4X4;
>> +      }
>> +      break;
>> +
>> +    case 1: /* x8 x8 */
>> +    default:
>> +      break;
>> +    }
>> +  }
>> +
>> +  for (RPIdx = 0; RPIdx < MAX_PCIE_A; RPIdx++) {
>> +    RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ? MaxGen[RPIdx] : 0;
>> +  }
>> +
>> +  if (RC->Type == RCB) {
>> +    for (RPIdx = MAX_PCIE_A; RPIdx < MAX_PCIE; RPIdx++) {
>> +      RC->Pcie[RPIdx].MaxGen = RC->Pcie[RPIdx].Active ?
>> +                               MaxGen[RPIdx - MAX_PCIE_A] : 0;
>> +    }
>> +  }
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
>> new file mode 100644
>> index 000000000000..309cc8857b8c
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.c
>> @@ -0,0 +1,1120 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/PcieBoardLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +#include <NVParamDef.h>
>> +#include <Pcie.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +#include "PcieBoardScreen.h"
>> +
>> +#ifndef BIT
>> +#define BIT(nr) (1 << (nr))
>> +#endif
>> +
>> +#define MAX_STRING_SIZE     32
>> +
>> +CHAR16   VariableName[]     = PCIE_VARSTORE_NAME;
>> +EFI_GUID gPcieFormSetGuid   = PCIE_FORM_SET_GUID;
>> +
>> +EFI_HANDLE               DriverHandle = NULL;
>> +PCIE_SCREEN_PRIVATE_DATA *mPrivateData = NULL;
>> +
>> +AC01_RC RCList[MAX_AC01_PCIE_ROOT_COMPLEX];
>> +
>> +HII_VENDOR_DEVICE_PATH mHiiVendorDevicePath = {
>> +  {
>> +    {
>> +      HARDWARE_DEVICE_PATH,
>> +      HW_VENDOR_DP,
>> +      {
>> +        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
>> +        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
>> +      }
>> +    },
>> +    PCIE_FORM_SET_GUID
>> +  },
>> +  {
>> +    END_DEVICE_PATH_TYPE,
>> +    END_ENTIRE_DEVICE_PATH_SUBTYPE,
>> +    {
>> +      (UINT8)(END_DEVICE_PATH_LENGTH),
>> +      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
>> +    }
>> +  }
>> +};
>> +
>> +/**
>> +  This function allows a caller to extract the current configuration for one
>> +  or more named elements from the target driver.
>> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
>> +  @param  Request                A null-terminated Unicode string in
>> +                                 <ConfigRequest> format.
>> +  @param  Progress               On return, points to a character in the Request
>> +                                 string. Points to the string's null terminator if
>> +                                 request was successful. Points to the most recent
>> +                                 '&' before the first failing name/value pair (or
>> +                                 the beginning of the string if the failure is in
>> +                                 the first name/value pair) if the request was not
>> +                                 successful.
>> +  @param  Results                A null-terminated Unicode string in
>> +                                 <ConfigAltResp> format which has all values filled
>> +                                 in for the names in the Request string. String to
>> +                                 be allocated by the called function.
>> +  @retval EFI_SUCCESS            The Results is filled with the requested values.
>> +  @retval EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
>> +  @retval EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
>> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
>> +                                 driver.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +ExtractConfig (
>> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
>> +  IN CONST EFI_STRING                     Request,
>> +  OUT      EFI_STRING                     *Progress,
>> +  OUT      EFI_STRING                     *Results
>> +  )
>> +{
>> +  EFI_STATUS                      Status;
>> +  UINTN                           BufferSize;
>> +  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
>> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
>> +  EFI_STRING                      ConfigRequest;
>> +  EFI_STRING                      ConfigRequestHdr;
>> +  UINTN                           Size;
>> +  CHAR16                          *StrPointer;
>> +  BOOLEAN                         AllocatedRequest;
>> +  PCIE_VARSTORE_DATA              *VarStoreConfig;
>> +
>> +  if (Progress == NULL || Results == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  //
>> +  // Initialize the local variables.
>> +  //
>> +  ConfigRequestHdr  = NULL;
>> +  ConfigRequest     = NULL;
>> +  Size              = 0;
>> +  *Progress         = Request;
>> +  AllocatedRequest  = FALSE;
>> +
>> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
>> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
>> +  VarStoreConfig = &PrivateData->VarStoreConfig;
>> +  ASSERT (VarStoreConfig != NULL);
>> +
>> +  //
>> +  // Get Buffer Storage data from EFI variable.
>> +  // Try to get the current setting from variable.
>> +  //
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = gRT->GetVariable (
>> +                  VariableName,
>> +                  &gPcieFormSetGuid,
>> +                  NULL,
>> +                  &BufferSize,
>> +                  VarStoreConfig
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  if (Request == NULL) {
>> +    //
>> +    // Request is set to NULL, construct full request string.
>> +    //
>> +
>> +    //
>> +    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
>> +    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a
>> +    // Null-terminator
>> +    //
>> +    ConfigRequestHdr = HiiConstructConfigHdr (
>> +                         &gPcieFormSetGuid,
>> +                         VariableName,
>> +                         PrivateData->DriverHandle
>> +                         );
>> +    if (ConfigRequestHdr == NULL) {
>> +      return EFI_OUT_OF_RESOURCES;
>> +    }
>> +    Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
>> +    ConfigRequest = AllocateZeroPool (Size);
>> +    ASSERT (ConfigRequest != NULL);
>> +    AllocatedRequest = TRUE;
>> +    UnicodeSPrint (
>> +      ConfigRequest,
>> +      Size,
>> +      L"%s&OFFSET=0&WIDTH=%016LX",
>> +      ConfigRequestHdr,
>> +      (UINT64)BufferSize
>> +      );
>> +    FreePool (ConfigRequestHdr);
>> +    ConfigRequestHdr = NULL;
>> +  } else {
>> +    //
>> +    // Check routing data in <ConfigHdr>.
>> +    // Note: if only one Storage is used, then this checking could be skipped.
>> +    //
>> +    if (!HiiIsConfigHdrMatch (Request, &gPcieFormSetGuid, NULL)) {
>> +      return EFI_NOT_FOUND;
>> +    }
>> +
>> +    //
>> +    // Set Request to the unified request string.
>> +    //
>> +    ConfigRequest = Request;
>> +
>> +    //
>> +    // Check whether Request includes Request Element.
>> +    //
>> +    if (StrStr (Request, L"OFFSET") == NULL) {
>> +      //
>> +      // Check Request Element does exist in Request String
>> +      //
>> +      StrPointer = StrStr (Request, L"PATH");
>> +      if (StrPointer == NULL) {
>> +        return EFI_INVALID_PARAMETER;
>> +      }
>> +      if (StrStr (StrPointer, L"&") == NULL) {
>> +        Size = (StrLen (Request) + 32 + 1) * sizeof (CHAR16);
> What is 32?
>
>> +        ConfigRequest    = AllocateZeroPool (Size);
>> +        ASSERT (ConfigRequest != NULL);
>> +        AllocatedRequest = TRUE;
>> +        UnicodeSPrint (
>> +          ConfigRequest,
>> +          Size,
>> +          L"%s&OFFSET=0&WIDTH=%016LX",
>> +          Request,
>> +          (UINT64)BufferSize
>> +          );
>> +      }
>> +    }
>> +  }
>> +
>> +  //
>> +  // Check if requesting Name/Value storage
>> +  //
>> +  if (StrStr (ConfigRequest, L"OFFSET") == NULL) {
>> +    //
>> +    // Don't have any Name/Value storage names
>> +    //
>> +    Status = EFI_SUCCESS;
>> +  } else {
>> +    //
>> +    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
>> +    //
>> +    Status = HiiConfigRouting->BlockToConfig (
>> +                                 HiiConfigRouting,
>> +                                 ConfigRequest,
>> +                                 (UINT8 *)VarStoreConfig,
>> +                                 BufferSize,
>> +                                 Results,
>> +                                 Progress
>> +                                 );
>> +  }
>> +
>> +  //
>> +  // Free the allocated config request string.
>> +  //
>> +  if (AllocatedRequest) {
>> +    FreePool (ConfigRequest);
>> +  }
>> +
>> +  if (ConfigRequestHdr != NULL) {
>> +    FreePool (ConfigRequestHdr);
>> +  }
>> +  //
>> +  // Set Progress string to the original request string.
>> +  //
>> +  if (Request == NULL) {
>> +    *Progress = NULL;
>> +  } else if (StrStr (Request, L"OFFSET") == NULL) {
>> +    *Progress = Request + StrLen (Request);
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  This function processes the results of changes in configuration.
>> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
>> +  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
>> +                                 format.
>> +  @param  Progress               A pointer to a string filled in with the offset of
>> +                                 the most recent '&' before the first failing
>> +                                 name/value pair (or the beginning of the string if
>> +                                 the failure is in the first name/value pair) or
>> +                                 the terminating NULL if all was successful.
>> +  @retval EFI_SUCCESS            The Results is processed successfully.
>> +  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
>> +  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
>> +                                 driver.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +RouteConfig (
>> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
>> +  IN CONST EFI_STRING                     Configuration,
>> +  OUT      EFI_STRING                     *Progress
>> +  )
>> +{
>> +  EFI_STATUS                      Status;
>> +  UINTN                           BufferSize;
>> +  PCIE_SCREEN_PRIVATE_DATA        *PrivateData;
>> +  EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;
>> +  PCIE_VARSTORE_DATA              *VarStoreConfig;
>> +
>> +  if (Configuration == NULL || Progress == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
>> +  HiiConfigRouting = PrivateData->HiiConfigRouting;
>> +  *Progress = Configuration;
>> +  VarStoreConfig = &PrivateData->VarStoreConfig;
>> +  ASSERT (VarStoreConfig != NULL);
>> +
>> +  //
>> +  // Check routing data in <ConfigHdr>.
>> +  // Note: if only one Storage is used, then this checking could be skipped.
>> +  //
>> +  if (!HiiIsConfigHdrMatch (Configuration, &gPcieFormSetGuid, NULL)) {
>> +    return EFI_NOT_FOUND;
>> +  }
>> +
>> +  //
>> +  // Get Buffer Storage data from EFI variable
>> +  //
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = gRT->GetVariable (
>> +                  VariableName,
>> +                  &gPcieFormSetGuid,
>> +                  NULL,
>> +                  &BufferSize,
>> +                  VarStoreConfig
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Check if configuring Name/Value storage
>> +  //
>> +  if (StrStr (Configuration, L"OFFSET") == NULL) {
>> +    //
>> +    // Don't have any Name/Value storage names
>> +    //
>> +    return EFI_SUCCESS;
>> +  }
>> +
>> +  //
>> +  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
>> +  //
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = HiiConfigRouting->ConfigToBlock (
>> +                               HiiConfigRouting,
>> +                               Configuration,
>> +                               (UINT8 *)VarStoreConfig,
>> +                               &BufferSize,
>> +                               Progress
>> +                               );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //
>> +  // Store Buffer Storage back to variable
>> +  //
>> +  Status = gRT->SetVariable (
>> +                  VariableName,
>> +                  &gPcieFormSetGuid,
>> +                  EFI_VARIABLE_NON_VOLATILE |
>> +                  EFI_VARIABLE_BOOTSERVICE_ACCESS |
>> +                  EFI_VARIABLE_RUNTIME_ACCESS,
>> +                  sizeof (PCIE_VARSTORE_DATA),
>> +                  VarStoreConfig
>> +                  );
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +  This function processes the results of changes in configuration.
>> +  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
>> +  @param  Action                 Specifies the type of action taken by the browser.
>> +  @param  QuestionId             A unique value which is sent to the original
>> +                                 exporting driver so that it can identify the type
>> +                                 of data to expect.
>> +  @param  Type                   The type of value for the question.
>> +  @param  Value                  A pointer to the data being sent to the original
>> +                                 exporting driver.
>> +  @param  ActionRequest          On return, points to the action requested by the
>> +                                 callback function.
>> +  @retval EFI_SUCCESS            The callback successfully handled the action.
>> +  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
>> +                                 variable and its data.
>> +  @retval EFI_DEVICE_ERROR       The variable could not be saved.
>> +  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
>> +                                 callback.
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +DriverCallback (
>> +  IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
>> +  IN       EFI_BROWSER_ACTION             Action,
>> +  IN       EFI_QUESTION_ID                QuestionId,
>> +  IN       UINT8                          Type,
>> +  IN       EFI_IFR_TYPE_VALUE             *Value,
>> +  OUT      EFI_BROWSER_ACTION_REQUEST     *ActionRequest
>> +  )
>> +{
>> +  PCIE_VARSTORE_DATA       *VarStoreConfig;
>> +  PCIE_SCREEN_PRIVATE_DATA *PrivateData;
>> +  EFI_STATUS               Status;
>> +
>> +  if (((Value == NULL) &&
>> +       (Action != EFI_BROWSER_ACTION_FORM_OPEN) &&
>> +       (Action != EFI_BROWSER_ACTION_FORM_CLOSE)) ||
>> +      (ActionRequest == NULL))
>> +  {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  PrivateData = PCIE_SCREEN_PRIVATE_FROM_THIS (This);
>> +  VarStoreConfig = &PrivateData->VarStoreConfig;
>> +  ASSERT (VarStoreConfig != NULL);
>> +
>> +  Status = EFI_SUCCESS;
>> +
>> +  switch (Action) {
>> +  case EFI_BROWSER_ACTION_FORM_OPEN:
>> +    break;
>> +
>> +  case EFI_BROWSER_ACTION_FORM_CLOSE:
>> +    break;
>> +
>> +  case EFI_BROWSER_ACTION_DEFAULT_STANDARD:
>> +  case EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING:
>> +    if (QuestionId == 0x9000) {
>> +      /* SMMU PMU */
>> +      Value->u32 = 0; /* default disable */
>> +      break;
>> +    }
>> +
>> +    switch ((QuestionId - 0x8002) % MAX_EDITABLE_ELEMENTS) {
>> +    case 0:
>> +      Value->u8 = PcieRCActiveDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
>> +      break;
>> +
>> +    case 1:
>> +      Value->u8 = PcieRCDevMapLoDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
>> +      break;
>> +
>> +    case 2:
>> +      Value->u8 = PcieRCDevMapHiDefaultSetting ((QuestionId - 0x8002) / MAX_EDITABLE_ELEMENTS, PrivateData);
>> +      break;
>> +    }
>> +    break;
>> +
>> +  case EFI_BROWSER_ACTION_RETRIEVE:
>> +  case EFI_BROWSER_ACTION_CHANGING:
>> +  case EFI_BROWSER_ACTION_SUBMITTED:
>> +    break;
>> +
>> +  default:
>> +    Status = EFI_UNSUPPORTED;
>> +    break;
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +PcieScreenUnload (
>> +  IN EFI_HANDLE ImageHandle
>> +  )
>> +{
>> +  ASSERT (mPrivateData != NULL);
>> +
>> +  if (DriverHandle != NULL) {
>> +    gBS->UninstallMultipleProtocolInterfaces (
>> +           DriverHandle,
>> +           &gEfiDevicePathProtocolGuid,
>> +           &mHiiVendorDevicePath,
>> +           &gEfiHiiConfigAccessProtocolGuid,
>> +           &mPrivateData->ConfigAccess,
>> +           NULL
>> +           );
>> +    DriverHandle = NULL;
>> +  }
>> +
>> +  if (mPrivateData->HiiHandle != NULL) {
>> +    HiiRemovePackages (mPrivateData->HiiHandle);
>> +  }
>> +
>> +  FreePool (mPrivateData);
>> +  mPrivateData = NULL;
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  This function return default settings for Dev Map LO.
>> +  @param  RC                     Root Complex ID.
>> +  @param  PrivateData            Private data.
>> +
>> +  @retval Default dev settings.
>> +**/
>> +UINT8
>> +PcieRCDevMapLoDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  )
>> +{
>> +  AC01_RC *RC = &RCList[RCIndex];
>> +
>> +  return RC->DefaultDevMapLo;
>> +}
>> +
>> +/**
>> +  This function return default settings for Dev Map HI.
>> +  @param  RC                     Root Complex ID.
>> +  @param  PrivateData            Private data.
>> +
>> +  @retval Default dev settings.
>> +**/
>> +UINT8
>> +PcieRCDevMapHiDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  )
>> +{
>> +  AC01_RC *RC = &RCList[RCIndex];
>> +
>> +  return RC->DefaultDevMapHi;
>> +}
>> +
>> +BOOLEAN
>> +PcieRCActiveDefaultSetting (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  )
>> +{
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  VOID               *Hob;
>> +  UINT32             Efuse;
>> +
>> +  // FIXME: Disable Root Complex 6 (USB and VGA) as default
> Please get rid of the FIXME
>
>> +  if (RCIndex == 6) {
>> +    return FALSE;
>> +  }
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob != NULL) {
>> +    PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +    Efuse = PlatformHob->RcDisableMask[0] | (PlatformHob->RcDisableMask[1] << RCS_PER_SOCKET);
>> +    return (!(Efuse & BIT (RCIndex))) ? TRUE : FALSE;
>> +  }
>> +
>> +  return FALSE;
>> +}
>> +
>> +/**
>> +  This function sets up the first elements of the form.
>> +  @param  RC                     Root Complex ID.
>> +  @param  PrivateData            Private data.
>> +  @retval EFI_SUCCESS            The form is set up successfully.
>> +**/
>> +EFI_STATUS
>> +PcieRCScreenSetup (
>> +  IN UINTN                    RCIndex,
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  )
>> +{
>> +  VOID               *StartOpCodeHandle;
>> +  EFI_IFR_GUID_LABEL *StartLabel;
>> +  VOID               *EndOpCodeHandle;
>> +  EFI_IFR_GUID_LABEL *EndLabel;
>> +  VOID               *OptionsOpCodeHandle;
>> +  VOID               *OptionsHiOpCodeHandle;
>> +  CHAR16             Str[MAX_STRING_SIZE];
>> +  UINT16             DisabledStatusVarOffset;
>> +  UINT16             BifurLoVarOffset;
>> +  UINT16             BifurHiVarOffset;
>> +  UINT8              QuestionFlags, QuestionFlagsSubItem;
>> +  AC01_RC            *RC;
>> +
>> +  RC = &RCList[RCIndex];
>> +
>> +  // Initialize the container for dynamic opcodes
>> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +  ASSERT (StartOpCodeHandle != NULL);
>> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +  ASSERT (EndOpCodeHandle != NULL);
>> +
>> +  // Create Hii Extend Label OpCode as the start opcode
>> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
>> +                                       StartOpCodeHandle,
>> +                                       &gEfiIfrTianoGuid,
>> +                                       NULL,
>> +                                       sizeof (EFI_IFR_GUID_LABEL)
>> +                                       );
>> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
>> +  StartLabel->Number       = LABEL_RC0_UPDATE + 2 * RCIndex;
>> +
>> +  // Create Hii Extend Label OpCode as the end opcode
>> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
>> +                                     EndOpCodeHandle,
>> +                                     &gEfiIfrTianoGuid,
>> +                                     NULL,
>> +                                     sizeof (EFI_IFR_GUID_LABEL)
>> +                                     );
>> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
>> +  EndLabel->Number       = LABEL_RC0_END + 2 * RCIndex;
>> +
>> +  // Create textbox to tell socket
>> +  HiiCreateTextOpCode (
>> +    StartOpCodeHandle,
>> +    STRING_TOKEN (STR_PCIE_SOCKET),
>> +    STRING_TOKEN (STR_PCIE_SOCKET_HELP),
>> +    HiiSetString (
>> +      PrivateData->HiiHandle,
>> +      0,
>> +      (RC->Socket) ? L"1" : L"0",
>> +      NULL
>> +      )
>> +    );
>> +
>> +  // Create textbox to tell Root Complex type
>> +  HiiCreateTextOpCode (
>> +    StartOpCodeHandle,
>> +    STRING_TOKEN (STR_PCIE_RC_TYPE),
>> +    STRING_TOKEN (STR_PCIE_RC_TYPE_HELP),
>> +    HiiSetString (
>> +      PrivateData->HiiHandle,
>> +      0,
>> +      (RC->Type == RCA) ? L"Root Complex Type-A" : L"Root Complex Type-B",
>> +      NULL
>> +      )
>> +    );
>> +
>> +  UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RCIndex);
>> +
>> +  DisabledStatusVarOffset = (UINT16)PCIE_RC0_STATUS_OFFSET +
>> +                            sizeof (BOOLEAN) * RCIndex;
>> +  BifurLoVarOffset = (UINT16)PCIE_RC0_BIFUR_LO_OFFSET +
>> +                     sizeof (UINT8) * RCIndex;
>> +  BifurHiVarOffset = (UINT16)PCIE_RC0_BIFUR_HI_OFFSET +
>> +                     sizeof (UINT8) * RCIndex;
>> +
>> +  QuestionFlags = EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_CALLBACK;
>> +  if (IsEmptyRC (RC)
>> +      || (GetNumberOfActiveSockets () == 1 && RC->Socket == 1))
>> +  {
>> +    //
>> +    // Do not allow changing if none of Root Port underneath enabled
>> +    // or slave Root Complex on 1P system.
>> +    //
>> +    QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
>> +  }
>> +  // Create the RC disabled checkbox
>> +  HiiCreateCheckBoxOpCode (
>> +    StartOpCodeHandle,                        // Container for dynamic created opcodes
>> +    0x8002 + MAX_EDITABLE_ELEMENTS * RCIndex, // QuestionId (or "key")
>> +    PCIE_VARSTORE_ID,                         // VarStoreId
>> +    DisabledStatusVarOffset,                  // VarOffset in Buffer Storage
>> +    HiiSetString (
>> +      PrivateData->HiiHandle,
>> +      0,
>> +      Str,
>> +      NULL
>> +      ),                                       // Prompt
>> +    STRING_TOKEN (STR_PCIE_RC_STATUS_HELP),    // Help
>> +    QuestionFlags,                             // QuestionFlags
>> +    0,                                         // CheckBoxFlags
>> +    NULL                                       // DefaultsOpCodeHandle
>> +    );
>> +
>> +  if (RC->Type == RCA) {
>> +    // Create Option OpCode to display bifurcation for RCA
>> +    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +    ASSERT (OptionsOpCodeHandle != NULL);
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE0),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      0 // Devmap=0
>> +      );
>> +
>> +
>> +    if (RC->DefaultDevMapLo != 0) {
>> +      QuestionFlags |= EFI_IFR_FLAG_READ_ONLY;
>> +    }
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE1),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      1 // Devmap=1
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE2),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      2 // Devmap=2
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE3),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      3 // Devmap=3
>> +      );
>> +
>> +    HiiCreateOneOfOpCode (
>> +      StartOpCodeHandle,                        // Container for dynamic created opcodes
>> +      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex, // Question ID (or call it "key")
>> +      PCIE_VARSTORE_ID,                         // VarStore ID
>> +      BifurLoVarOffset,                         // Offset in Buffer Storage
>> +      STRING_TOKEN (STR_PCIE_RCA_BIFUR),        // Question prompt text
>> +      STRING_TOKEN (STR_PCIE_RCA_BIFUR_HELP),   // Question help text
>> +      QuestionFlags,                            // Question flag
>> +      EFI_IFR_NUMERIC_SIZE_1,                   // Data type of Question Value
>> +      OptionsOpCodeHandle,                      // Option Opcode list
>> +      NULL                                      // Default Opcode is NULl
>> +      );
>> +  } else {
>> +    // Create Option OpCode to display bifurcation for RCB-Lo
>> +    OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +    ASSERT (OptionsOpCodeHandle != NULL);
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      0 // Devmap=0
>> +      );
>> +
>> +    QuestionFlagsSubItem = QuestionFlags;
>> +    if (RC->DefaultDevMapLo != 0) {
>> +      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
>> +    }
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      1 // Devmap=1
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      2 // Devmap=2
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      3 // Devmap=3
>> +      );
>> +
>> +    HiiCreateOneOfOpCode (
>> +      StartOpCodeHandle,                         // Container for dynamic created opcodes
>> +      0x8003 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
>> +      PCIE_VARSTORE_ID,                          // VarStore ID
>> +      BifurLoVarOffset,                          // Offset in Buffer Storage
>> +      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR),      // Question prompt text
>> +      STRING_TOKEN (STR_PCIE_RCB_LO_BIFUR_HELP), // Question help text
>> +      QuestionFlagsSubItem,                      // Question flag
>> +      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
>> +      OptionsOpCodeHandle,                       // Option Opcode list
>> +      NULL                                       // Default Opcode is NULl
>> +      );
>> +
>> +    // Create Option OpCode to display bifurcation for RCB-Hi
>> +    OptionsHiOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +    ASSERT (OptionsHiOpCodeHandle != NULL);
>> +
>> +    QuestionFlagsSubItem = QuestionFlags;
>> +    if (RC->DefaultDevMapHi != 0) {
>> +      QuestionFlagsSubItem |= EFI_IFR_FLAG_READ_ONLY;
>> +    }
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsHiOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE4),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      0 // Devmap=0
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsHiOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE5),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      1 // Devmap=1
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsHiOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE6),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      2 // Devmap=2
>> +      );
>> +
>> +    HiiCreateOneOfOptionOpCode (
>> +      OptionsHiOpCodeHandle,
>> +      STRING_TOKEN (STR_PCIE_BIFUR_SELECT_VALUE7),
>> +      0,
>> +      EFI_IFR_NUMERIC_SIZE_1,
>> +      3 // Devmap=3
>> +      );
>> +
>> +    HiiCreateOneOfOpCode (
>> +      StartOpCodeHandle,                         // Container for dynamic created opcodes
>> +      0x8004 + MAX_EDITABLE_ELEMENTS * RCIndex,  // Question ID (or call it "key")
>> +      PCIE_VARSTORE_ID,                          // VarStore ID
>> +      BifurHiVarOffset,                          // Offset in Buffer Storage
>> +      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR),      // Question prompt text
>> +      STRING_TOKEN (STR_PCIE_RCB_HI_BIFUR_HELP), // Question help text
>> +      QuestionFlagsSubItem,                      // Question flag
>> +      EFI_IFR_NUMERIC_SIZE_1,                    // Data type of Question Value
>> +      OptionsHiOpCodeHandle,                     // Option Opcode list
>> +      NULL                                       // Default Opcode is NULl
>> +      );
>> +  }
>> +
>> +  HiiUpdateForm (
>> +    PrivateData->HiiHandle,     // HII handle
>> +    &gPcieFormSetGuid,          // Formset GUID
>> +    PCIE_RC0_FORM_ID + RCIndex, // Form ID
>> +    StartOpCodeHandle,          // Label for where to insert opcodes
>> +    EndOpCodeHandle             // Insert data
>> +    );
>> +
>> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
>> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  This function sets up the first elements of the form.
>> +  @param  PrivateData            Private data.
>> +  @retval EFI_SUCCESS            The form is set up successfully.
>> +**/
>> +EFI_STATUS
>> +PcieMainScreenSetup (
>> +  IN PCIE_SCREEN_PRIVATE_DATA *PrivateData
>> +  )
>> +{
>> +  VOID                 *StartOpCodeHandle;
>> +  EFI_IFR_GUID_LABEL   *StartLabel;
>> +  VOID                 *EndOpCodeHandle;
>> +  EFI_IFR_GUID_LABEL   *EndLabel;
>> +  CHAR16               Str[MAX_STRING_SIZE];
>> +  UINTN                RC;
>> +  PCIE_SETUP_GOTO_DATA *GotoItem = NULL;
>> +  EFI_QUESTION_ID      GotoId;
>> +
>> +  // Initialize the container for dynamic opcodes
>> +  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +  ASSERT (StartOpCodeHandle != NULL);
>> +  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
>> +  ASSERT (EndOpCodeHandle != NULL);
>> +
>> +  // Create Hii Extend Label OpCode as the start opcode
>> +  StartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
>> +                                       StartOpCodeHandle,
>> +                                       &gEfiIfrTianoGuid,
>> +                                       NULL,
>> +                                       sizeof (EFI_IFR_GUID_LABEL)
>> +                                       );
>> +  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
>> +  StartLabel->Number       = LABEL_UPDATE;
>> +
>> +  // Create Hii Extend Label OpCode as the end opcode
>> +  EndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
>> +                                     EndOpCodeHandle,
>> +                                     &gEfiIfrTianoGuid,
>> +                                     NULL,
>> +                                     sizeof (EFI_IFR_GUID_LABEL)
>> +                                     );
>> +  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
>> +  EndLabel->Number       = LABEL_END;
>> +
>> +  HiiCreateCheckBoxOpCode (
>> +    StartOpCodeHandle,                       // Container for dynamic created opcodes
>> +    0x9000,                                  // Question ID
>> +    PCIE_VARSTORE_ID,                        // VarStore ID
>> +    (UINT16)PCIE_SMMU_PMU_OFFSET,            // Offset in Buffer Storage
>> +    STRING_TOKEN (STR_PCIE_SMMU_PMU_PROMPT), // Question prompt text
>> +    STRING_TOKEN (STR_PCIE_SMMU_PMU_HELP),   // Question help text
>> +    EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED,
>> +    0,
>> +    NULL
>> +    );
>> +
>> +  //
>> +  // Create the a seperated line
>> +  //
>> +  HiiCreateTextOpCode (
>> +    StartOpCodeHandle,
>> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
>> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE),
>> +    STRING_TOKEN (STR_PCIE_FORM_SEPERATE_LINE)
>> +    );
>> +
>> +  // Create Goto form for each RC
>> +  for (RC = 0; RC < MAX_AC01_PCIE_ROOT_COMPLEX; RC++) {
>> +
>> +    GotoItem = AllocateZeroPool (sizeof (PCIE_SETUP_GOTO_DATA));
>> +    if (GotoItem == NULL) {
>> +      return EFI_OUT_OF_RESOURCES;
>> +    }
>> +    GotoItem->PciDevIdx = RC;
>> +
>> +    GotoId = PCIE_GOTO_ID_BASE + (UINT16)RC;
>> +
>> +    // Update HII string
>> +    UnicodeSPrint (Str, sizeof (Str), L"Root Complex #%2d", RC);
>> +    GotoItem->GotoStringId = HiiSetString (
>> +                               PrivateData->HiiHandle,
>> +                               0,
>> +                               Str,
>> +                               NULL
>> +                               );
>> +    GotoItem->GotoHelpStringId = STRING_TOKEN (STR_PCIE_GOTO_HELP);
>> +    GotoItem->ShowItem = TRUE;
>> +
>> +    // Add goto control
>> +    HiiCreateGotoOpCode (
>> +      StartOpCodeHandle,
>> +      PCIE_RC0_FORM_ID + RC,
>> +      GotoItem->GotoStringId,
>> +      GotoItem->GotoHelpStringId,
>> +      EFI_IFR_FLAG_CALLBACK,
>> +      GotoId
>> +      );
>> +  }
>> +
>> +  HiiUpdateForm (
>> +    PrivateData->HiiHandle,  // HII handle
>> +    &gPcieFormSetGuid,       // Formset GUID
>> +    PCIE_FORM_ID,            // Form ID
>> +    StartOpCodeHandle,       // Label for where to insert opcodes
>> +    EndOpCodeHandle          // Insert data
>> +    );
>> +
>> +  HiiFreeOpCodeHandle (StartOpCodeHandle);
>> +  HiiFreeOpCodeHandle (EndOpCodeHandle);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +PcieBoardScreenInitialize (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable,
>> +  IN AC01_RC          *NewRCList
>> +  )
>> +{
>> +  EFI_STATUS                          Status;
>> +  EFI_HII_HANDLE                      HiiHandle;
>> +  EFI_HII_DATABASE_PROTOCOL           *HiiDatabase;
>> +  EFI_HII_STRING_PROTOCOL             *HiiString;
>> +  EFI_HII_CONFIG_ROUTING_PROTOCOL     *HiiConfigRouting;
>> +  EFI_CONFIG_KEYWORD_HANDLER_PROTOCOL *HiiKeywordHandler;
>> +  UINTN                               BufferSize;
>> +  BOOLEAN                             IsUpdated;
>> +  PCIE_VARSTORE_DATA                  *VarStoreConfig;
>> +  UINT8                               RCIndex;
>> +  AC01_RC                             *RC;
>> +
>> +  //
>> +  // Initialize driver private data
>> +  //
>> +  mPrivateData = AllocateZeroPool (sizeof (PCIE_SCREEN_PRIVATE_DATA));
>> +  if (mPrivateData == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  mPrivateData->Signature = PCIE_SCREEN_PRIVATE_DATA_SIGNATURE;
>> +
>> +  mPrivateData->ConfigAccess.ExtractConfig = ExtractConfig;
>> +  mPrivateData->ConfigAccess.RouteConfig = RouteConfig;
>> +  mPrivateData->ConfigAccess.Callback = DriverCallback;
>> +
>> +  //
>> +  // Locate Hii Database protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiHiiDatabaseProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&HiiDatabase
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  mPrivateData->HiiDatabase = HiiDatabase;
>> +
>> +  //
>> +  // Locate HiiString protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiHiiStringProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&HiiString
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  mPrivateData->HiiString = HiiString;
>> +
>> +  //
>> +  // Locate ConfigRouting protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiHiiConfigRoutingProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&HiiConfigRouting
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  mPrivateData->HiiConfigRouting = HiiConfigRouting;
>> +
>> +  //
>> +  // Locate keyword handler protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiConfigKeywordHandlerProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&HiiKeywordHandler
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +  mPrivateData->HiiKeywordHandler = HiiKeywordHandler;
>> +
>> +  Status = gBS->InstallMultipleProtocolInterfaces (
>> +                  &DriverHandle,
>> +                  &gEfiDevicePathProtocolGuid,
>> +                  &mHiiVendorDevicePath,
>> +                  &gEfiHiiConfigAccessProtocolGuid,
>> +                  &mPrivateData->ConfigAccess,
>> +                  NULL
>> +                  );
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  mPrivateData->DriverHandle = DriverHandle;
>> +
>> +  //
>> +  // Publish our HII data
>> +  //
>> +  HiiHandle = HiiAddPackages (
>> +                &gPcieFormSetGuid,
>> +                DriverHandle,
>> +                PcieBoardLibStrings,
>> +                VfrBin,
>> +                NULL
>> +                );
>> +  if (HiiHandle == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  mPrivateData->HiiHandle = HiiHandle;
>> +
>> +  // Make a shadow copy all Root Complexes' properties
>> +  CopyMem ((VOID *)RCList, (VOID *)NewRCList, sizeof (RCList));
>> +
>> +  //
>> +  // Initialize efi varstore configuration data
>> +  //
>> +  VarStoreConfig = &mPrivateData->VarStoreConfig;
>> +  ZeroMem (VarStoreConfig, sizeof (PCIE_VARSTORE_DATA));
>> +
>> +  // Get Buffer Storage data from EFI variable
>> +  BufferSize = sizeof (PCIE_VARSTORE_DATA);
>> +  Status = gRT->GetVariable (
>> +                  VariableName,
>> +                  &gPcieFormSetGuid,
>> +                  NULL,
>> +                  &BufferSize,
>> +                  VarStoreConfig
>> +                  );
>> +
>> +  IsUpdated = FALSE;
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    VarStoreConfig->SmmuPmu = 0; /* Disable by default */
>> +    IsUpdated = TRUE;
>> +  }
>> +  // Update board settings to menu
>> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
>> +    RC = &RCList[RCIndex];
>> +
>> +    if (EFI_ERROR (Status)) {
>> +      VarStoreConfig->RCBifurLo[RCIndex] = RC->DevMapLo;
>> +      VarStoreConfig->RCBifurHi[RCIndex] = RC->DevMapHi;
>> +      VarStoreConfig->RCStatus[RCIndex] = RC->Active;
>> +      IsUpdated = TRUE;
>> +    }
>> +    // FIXME: Disable Root Complex 6 (USB and VGA) as default
> Please get rid of the FIXME.
>
> /
>      Leif
>
>> +    if (EFI_ERROR (Status) && RCIndex == 6) {
>> +      VarStoreConfig->RCStatus[RCIndex] = 0;
>> +    }
>> +  }
>> +
>> +  if (IsUpdated) {
>> +    // Update Buffer Storage
>> +    Status = gRT->SetVariable (
>> +                    VariableName,
>> +                    &gPcieFormSetGuid,
>> +                    EFI_VARIABLE_NON_VOLATILE |
>> +                    EFI_VARIABLE_BOOTSERVICE_ACCESS |
>> +                    EFI_VARIABLE_RUNTIME_ACCESS,
>> +                    sizeof (PCIE_VARSTORE_DATA),
>> +                    VarStoreConfig
>> +                    );
>> +    if (EFI_ERROR (Status)) {
>> +      return Status;
>> +    }
>> +  }
>> +  Status = PcieMainScreenSetup (mPrivateData);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  for (RCIndex = 0; RCIndex < MAX_AC01_PCIE_ROOT_COMPLEX; RCIndex++) {
>> +    Status = PcieRCScreenSetup (RCIndex, mPrivateData);
>> +    ASSERT_EFI_ERROR (Status);
>> +  }
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
>> new file mode 100644
>> index 000000000000..776eaa476787
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Library/PcieBoardLib/PcieBoardScreen.uni
>> @@ -0,0 +1,99 @@
>> +//
>> +// Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +//
>> +// SPDX-License-Identifier: BSD-2-Clause-Patent
>> +//
>> +
>> +#langdef en-US "English"
>> +
>> +#string STR_PCIE_FORM                   #language en-US "PCIE Root Complex Configuration"
>> +#string STR_PCIE_FORM_HELP              #language en-US "Configure Root Complex"
>> +
>> +#string STR_PCIE_FORM_SEPERATE_LINE     #language en-US ""
>> +
>> +/////
>> +
>> +#string STR_PCIE_GOTO                   #language en-US ""
>> +#string STR_PCIE_GOTO_HELP              #language en-US "Change On Board Root Complex Settings."
>> +
>> +#string STR_PCIE_RC_STATUS              #language en-US ""
>> +#string STR_PCIE_RC_STATUS_HELP         #language en-US "Enable / Disable Root Complex"
>> +
>> +#string STR_PCIE_RCA_BIFUR              #language en-US "Bifurcation x16"
>> +#string STR_PCIE_RCA_BIFUR_HELP         #language en-US "Set bifurcation mode for x16 Root Complex Type-A"
>> +
>> +#string STR_PCIE_RCB_LO_BIFUR           #language en-US "Bifurcation 1st x8"
>> +#string STR_PCIE_RCB_LO_BIFUR_HELP      #language en-US "Set bifurcation mode for 1st x8 Root Complex Type-B"
>> +
>> +#string STR_PCIE_RCB_HI_BIFUR           #language en-US "Bifurcation 2nd x8"
>> +#string STR_PCIE_RCB_HI_BIFUR_HELP      #language en-US "Set bifurcation mode for 2nd x8 Root Complex Type-B"
>> +
>> +/////
>> +
>> +#string STR_PCIE_RC0_FORM               #language en-US "Root Complex 0 Configuration"
>> +#string STR_PCIE_RC0_FORM_HELP          #language en-US "Root Complex 0 Configuration"
>> +
>> +#string STR_PCIE_RC1_FORM               #language en-US "Root Complex 1 Configuration"
>> +#string STR_PCIE_RC1_FORM_HELP          #language en-US "Root Complex 1 Configuration"
>> +
>> +#string STR_PCIE_RC2_FORM               #language en-US "Root Complex 2 Configuration"
>> +#string STR_PCIE_RC2_FORM_HELP          #language en-US "Root Complex 2 Configuration"
>> +
>> +#string STR_PCIE_RC3_FORM               #language en-US "Root Complex 3 Configuration"
>> +#string STR_PCIE_RC3_FORM_HELP          #language en-US "Root Complex 3 Configuration"
>> +
>> +#string STR_PCIE_RC4_FORM               #language en-US "Root Complex 4 Configuration"
>> +#string STR_PCIE_RC4_FORM_HELP          #language en-US "Root Complex 4 Configuration"
>> +
>> +#string STR_PCIE_RC5_FORM               #language en-US "Root Complex 5 Configuration"
>> +#string STR_PCIE_RC5_FORM_HELP          #language en-US "Root Complex 5 Configuration"
>> +
>> +#string STR_PCIE_RC6_FORM               #language en-US "Root Complex 6 Configuration"
>> +#string STR_PCIE_RC6_FORM_HELP          #language en-US "Root Complex 6 Configuration"
>> +
>> +#string STR_PCIE_RC7_FORM               #language en-US "Root Complex 7 Configuration"
>> +#string STR_PCIE_RC7_FORM_HELP          #language en-US "Root Complex 7 Configuration"
>> +
>> +#string STR_PCIE_RC8_FORM               #language en-US "Root Complex 8 Configuration"
>> +#string STR_PCIE_RC8_FORM_HELP          #language en-US "Root Complex 8 Configuration"
>> +
>> +#string STR_PCIE_RC9_FORM               #language en-US "Root Complex 9 Configuration"
>> +#string STR_PCIE_RC9_FORM_HELP          #language en-US "Root Complex 9 Configuration"
>> +
>> +#string STR_PCIE_RC10_FORM              #language en-US "Root Complex 10 Configuration"
>> +#string STR_PCIE_RC10_FORM_HELP         #language en-US "Root Complex 10 Configuration"
>> +
>> +#string STR_PCIE_RC11_FORM              #language en-US "Root Complex 11 Configuration"
>> +#string STR_PCIE_RC11_FORM_HELP         #language en-US "Root Complex 11 Configuration"
>> +
>> +#string STR_PCIE_RC12_FORM              #language en-US "Root Complex 12 Configuration"
>> +#string STR_PCIE_RC12_FORM_HELP         #language en-US "Root Complex 12 Configuration"
>> +
>> +#string STR_PCIE_RC13_FORM              #language en-US "Root Complex 13 Configuration"
>> +#string STR_PCIE_RC13_FORM_HELP         #language en-US "Root Complex 13 Configuration"
>> +
>> +#string STR_PCIE_RC14_FORM              #language en-US "Root Complex 14 Configuration"
>> +#string STR_PCIE_RC14_FORM_HELP         #language en-US "Root Complex 14 Configuration"
>> +
>> +#string STR_PCIE_RC15_FORM              #language en-US "Root Complex 15 Configuration"
>> +#string STR_PCIE_RC15_FORM_HELP         #language en-US "Root Complex 15 Configuration"
>> +
>> +#string STR_PCIE_BIFUR_SELECT_VALUE0    #language en-US "x16"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE1    #language en-US "x8+x8"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE2    #language en-US "x8+x4+x4"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE3    #language en-US "x4+x4+x4+x4"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE4    #language en-US "x8"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE5    #language en-US "x4+x4"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE6    #language en-US "x4+x2+x2"
>> +#string STR_PCIE_BIFUR_SELECT_VALUE7    #language en-US "x2+x2+x2+x2"
>> +
>> +#string STR_PCIE_SOCKET                 #language en-US "Socket"
>> +#string STR_PCIE_SOCKET_HELP            #language en-US "Socket 0 - Master; Socket 1 - Slave"
>> +#string STR_PCIE_SOCKET_VALUE           #language en-US ""
>> +
>> +#string STR_PCIE_RC_TYPE                #language en-US "Type"
>> +#string STR_PCIE_RC_TYPE_HELP           #language en-US "Type-A: x16 lanes bifurcated down to x4; Type-B: 2 of x8 lanes, each bifurcated down to x2"
>> +#string STR_PCIE_RC_TYPE_VALUE          #language en-US ""
>> +
>> +#string STR_PCIE_SMMU_PMU_PROMPT        #language en-US "SMMU Pmu"
>> +#string STR_PCIE_SMMU_PMU_HELP          #language en-US "Enable/Disable PMU feature for SMMU"
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support
  2021-06-07 23:00   ` Leif Lindholm
@ 2021-06-15 16:51     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:51 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Quan Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/8/21 06:00, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:12 +0700, Nhi Pham wrote:
>> From: Quan Nguyen <quan@os.amperecomputing.com>
>>
>> This supports various SMBIOS tables type 0, 1, 2, 3, 4, 7, 8, 9, 11,
>> 13, 16, 17, 19, 24 and 32.
>>
>> SMBIOS Type 1, 2 and 3 are hardcoded as Host-BMC communication is not
>> supported yet. And, this module does not support fixup tables to reflect
>> changes of the system at booting time.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Quan Nguyen <quan@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec                    |   12 +
>>   Platform/Ampere/JadePkg/Jade.dsc                                        |   26 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                        |    8 +
>>   Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf           |   45 +
>>   Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf   |   45 +
>>   Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf |   52 +
>>   Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c             |  709 +++++++++++++
>>   Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c     |  705 +++++++++++++
>>   Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c   | 1049 ++++++++++++++++++++
>>   9 files changed, 2651 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> index 0ac075047276..368136b5342f 100755
>> --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> @@ -63,11 +63,23 @@ [PcdsFixedAtBuild]
>>     gAmpereTokenSpaceGuid.PcdSmproNsMailboxIndex|0x1|UINT32|0x00000003
>>     gAmpereTokenSpaceGuid.PcdPmproDbBaseReg|0x100001540000|UINT64|0x00000004
>>   
>> +  #
>> +  # SMBIOS Type 1 Pcd
>> +  #
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|0|UINT8|0x00000005
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|0|UINT8|0x00000006
>> +
>>   [PcdsFixedAtBuild, PcdsDynamic, PcdsDynamicEx]
>>     #
>>     # Firmware Volume Pcds
>>     #
>>     gAmpereTokenSpaceGuid.PcdFvBlockSize|0|UINT32|0xB0000001
>>   
>> +  #
>> +  # SMBIOS, default or template values
>> +  #
>> +  # SMBIOS Type 0 - BIOS Information
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"|VOID*|0xB0000002 # Must follow this MM/DD/YYYY SMBIOS date format
>> +
>>     # NVRam Pcds
>>     gAmpereTokenSpaceGuid.PcdNvramErased|FALSE|BOOLEAN|0xB0000009
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index 6aaa644ad298..9c7d7cad4915 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -104,7 +104,22 @@ [PcdsFeatureFlag.common]
>>     #
>>     gEfiMdeModulePkgTokenSpaceGuid.PcdInstallAcpiSdtProtocol|TRUE
>>   
>> +[PcdsFixedAtBuild]
>> +!ifdef $(FIRMWARE_VER)
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"$(FIRMWARE_VER)"
>> +!endif
>> +
>>   [PcdsFixedAtBuild.common]
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion|$(MAJOR_VER)
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion|$(MINOR_VER)
>> +
>> +  # Clearing BIT0 in this PCD prevents installing a 32-bit SMBIOS entry point,
>> +  # if the entry point version is >= 3.0. AARCH64 OSes cannot assume the
>> +  # presence of the 32-bit entry point anyway (because many AARCH64 systems
>> +  # don't have 32-bit addressable physical RAM), and the additional allocations
>> +  # below 4 GB needlessly fragment the memory map. So expose the 64-bit entry
>> +  # point only, for entry point versions >= 3.0.
>> +  gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosEntryPointProvideMethod|0x2
>>   
>>   !if $(SECURE_BOOT_ENABLE) == TRUE
>>     # Override the default values from SecurityPkg to ensure images
>> @@ -114,6 +129,9 @@ [PcdsFixedAtBuild.common]
>>     gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
>>   !endif
>>   
>> +[PcdsDynamicDefault.common.DEFAULT]
>> +  # SMBIOS Type 0 - BIOS Information
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate|"MM/DD/YYYY"
>>   
>>   [PcdsPatchableInModule]
>>     #
>> @@ -148,3 +166,11 @@ [Components.common]
>>     # VGA Aspeed
>>     #
>>     Drivers/ASpeed/ASpeedGopBinPkg/ASpeedAst2500GopDxe.inf
>> +
>> +  #
>> +  # SMBIOS
>> +  #
>> +  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> +  Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index ef24e6f1f8e0..3d5d857178b3 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -340,4 +340,12 @@ [FV.FvMain]
>>     INF RuleOverride=ACPITABLE Silicon/Ampere/AmpereAltraPkg/AcpiCommonTables/AcpiCommonTables.inf
>>     INF RuleOverride=ACPITABLE Platform/Ampere/JadePkg/AcpiTables/AcpiTables.inf
>>   
>> +  #
>> +  # SMBIOS
>> +  #
>> +  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> +  INF Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> +
>>   !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> new file mode 100644
>> index 000000000000..f723ad612a52
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.inf
>> @@ -0,0 +1,45 @@
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = SmbiosCpuDxe
>> +  FILE_GUID                      = 4DD7C2E4-E6A6-11EA-8736-D3C56ABBB5C4
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = SmbiosCpuDxeEntry
>> +
>> +[Sources]
>> +  SmbiosCpuDxe.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  AmpereCpuLib
>> +  ArmLib
>> +  BaseLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  HobLib
>> +  MemoryAllocationLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +
>> +[Protocols]
>> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
>> +
>> +[Guids]
>> +  gPlatformHobGuid
>> +
>> +[Depex]
>> +  gEfiSmbiosProtocolGuid
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> new file mode 100644
>> index 000000000000..87b9123df856
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.inf
>> @@ -0,0 +1,45 @@
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = SmbiosMemInfoDxe
>> +  FILE_GUID                      = ECF38190-EBF8-11EA-B646-830715BDF83A
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = SmbiosMemInfoDxeEntry
>> +
>> +[Sources]
>> +  SmbiosMemInfoDxe.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  AmpereCpuLib
>> +  ArmLib
>> +  BaseLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  HobLib
>> +  MemoryAllocationLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +
>> +[Protocols]
>> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
>> +
>> +[Guids]
>> +  gPlatformHobGuid
>> +
>> +[Depex]
>> +  gEfiSmbiosProtocolGuid
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> new file mode 100755
>> index 000000000000..73a601b0df08
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.inf
>> @@ -0,0 +1,52 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = SmbiosPlatformDxe
>> +  FILE_GUID                      = F0CC7D0B-CD83-4DDA-A5D4-613AB02D4E52
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = SmbiosPlatformDxeEntry
>> +
>> +[Sources]
>> +  SmbiosPlatformDxe.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseLib
>> +  BaseMemoryLib
>> +  DebugLib
>> +  HobLib
>> +  MemoryAllocationLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +
>> +[Protocols]
>> +  gEfiSmbiosProtocolGuid                     ## CONSUMED
>> +
>> +[Pcd]
>> +  # Type 0
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables0BiosReleaseDate
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MajorVersion
>> +  gAmpereTokenSpaceGuid.PcdSmbiosTables1MinorVersion
>> +
>> +  gArmTokenSpaceGuid.PcdFdSize
>> +
>> +[Guids]
>> +  gPlatformHobGuid
>> +
>> +[Depex]
>> +  gEfiSmbiosProtocolGuid
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
>> new file mode 100644
>> index 000000000000..659212a2cc90
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosCpuDxe/SmbiosCpuDxe.c
>> @@ -0,0 +1,709 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Guid/SmBios.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/ArmLib/ArmLibPrivate.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PrintLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Protocol/Smbios.h>
>> +
>> +#define CPU_CACHE_LEVEL_MAX 3
>> +
>> +#define MHZ_SCALE_FACTOR 1000000
>> +
>> +#define CACHE_SIZE(x)   (UINT16) (0x8000 | (x) >> 16)
>> +#define CACHE_SIZE_2(x) (0x80000000 | (x) >> 16)
>> +
>> +#define TYPE4_ADDITIONAL_STRINGS                                  \
>> +  "SOCKET 0\0"                       /* socket type */            \
>> +  "Ampere(R)\0"                      /* manufacturer */           \
>> +  "Ampere(R) Altra(R) Processor\0"   /* processor description */  \
>> +  "NotSet\0"                         /* part number */
>> +
>> +#define TYPE7_ADDITIONAL_STRINGS                                  \
>> +  "L1 Cache\0" /* L1 Cache  */
>> +
>> +//
>> +// Type definition and contents of the default SMBIOS table.
>> +// This table covers only the minimum structures required by
>> +// the SMBIOS specification (section 6.2, version 3.0)
>> +//
>> +#pragma pack(1)
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE4 Base;
>> +  CHAR8              Strings[sizeof (TYPE4_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE4;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE7 Base;
>> +  CHAR8              Strings[sizeof (TYPE7_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE7;
>> +
>> +#pragma pack()
>> +//-------------------------------------
>> +//        SMBIOS Platform Common
>> +//-------------------------------------
>> +enum {
>> +  ADDITIONAL_STR_INDEX_1 = 1,
>> +  ADDITIONAL_STR_INDEX_2,
>> +  ADDITIONAL_STR_INDEX_3,
>> +  ADDITIONAL_STR_INDEX_4,
>> +  ADDITIONAL_STR_INDEX_5,
>> +  ADDITIONAL_STR_INDEX_6,
>> +  ADDITIONAL_STR_INDEX_7,
>> +  ADDITIONAL_STR_INDEX_8,
>> +  ADDITIONAL_STR_INDEX_9,
>> +  ADDITIONAL_STR_INDEX_MAX
>> +};
>> +
>> +// Type 4 Processor Socket 0
>> +STATIC ARM_TYPE4 mArmDefaultType4Sk0 = {
>> +  {
>> +    {                                        // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,          // socket type
>> +    3,                               // processor type CPU
>> +    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
>> +    ADDITIONAL_STR_INDEX_2,          // manufacturer
>> +    {{0,},{0.}},                     // processor id
>> +    ADDITIONAL_STR_INDEX_3,          // version
>> +    {0,0,0,0,0,1},                   // voltage
>> +    0,                               // external clock
>> +    3000,                            // max speed
>> +    3000,                            // current speed
>> +    0x41,                            // status
>> +    ProcessorUpgradeOther,
>> +    0xFFFF,                 // l1 cache handle
>> +    0xFFFF,                 // l2 cache handle
>> +    0xFFFF,                 // l3 cache handle
>> +    0,                      // serial not set
>> +    0,                      // asset not set
>> +    ADDITIONAL_STR_INDEX_4, // part number
>> +    80,                     // core count in socket
>> +    80,                     // enabled core count in socket
>> +    0,                      // threads per socket
>> +    0xEC,                   // processor characteristics
>> +    ProcessorFamilyARMv8,   // ARM core
>> +  },
>> +  TYPE4_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 4 Processor Socket 1
>> +STATIC ARM_TYPE4 mArmDefaultType4Sk1 = {
>> +  {
>> +    {                                        // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE4),           // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,          // socket type
>> +    3,                               // processor type CPU
>> +    ProcessorFamilyIndicatorFamily2, // processor family, acquire from field2
>> +    ADDITIONAL_STR_INDEX_2,          // manufacturer
>> +    {{0,},{0.}},                     // processor id
>> +    ADDITIONAL_STR_INDEX_3,          // version
>> +    {0,0,0,0,0,1},                   // voltage
>> +    0,                               // external clock
>> +    3000,                            // max speed
>> +    3000,                            // current speed
>> +    0x41,                            // status
>> +    ProcessorUpgradeOther,
>> +    0xFFFF,                 // l1 cache handle
>> +    0xFFFF,                 // l2 cache handle
>> +    0xFFFF,                 // l3 cache handle
>> +    0,                      // serial not set
>> +    0,                      // asset not set
>> +    ADDITIONAL_STR_INDEX_4, // part number
>> +    80,                     // core count in socket
>> +    80,                     // enabled core count in socket
>> +    0,                      // threads per socket
>> +    0xEC,                   // processor characteristics
>> +    ProcessorFamilyARMv8,   // ARM core
>> +  },
>> +  TYPE4_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L1 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x180,                  // L1 enabled, Write Back
>> +    0x8001,                 // 64k i cache max
>> +    0x8001,                 // 64k installed
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    0,                      // unkown speed
>> +    CacheErrorParity,       // parity checking
>> +    CacheTypeUnified,       // Unified cache
>> +    CacheAssociativity4Way, // 4-way
>> +  },
>> +  "L1 Cache\0"
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L2 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x181,                  // L2 enabled, Write Back
>> +    0x8010,                 // 1M cache max
>> +    0x8010,                 // 1M installed
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    0,                      // unkown speed
>> +    CacheErrorSingleBit,    // single bit ECC
>> +    CacheTypeUnified,       // Unified cache
>> +    CacheAssociativity8Way, // 8-way
>> +  },
>> +  "L2 Cache\0"
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk0L3 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x182,                   // L3 enabled, Write Back
>> +    0x8200,                  // 32M cache max
>> +    0x8200,                  // 32M installed
>> +    {0, 0, 0, 0, 0, 1},      // SRAM type
>> +    {0, 0, 0, 0, 0, 1},      // SRAM type
>> +    0,                       // unkown speed
>> +    CacheErrorParity,        // parity checking
>> +    CacheTypeUnified,        // Unified cache
>> +    CacheAssociativity16Way, // 16-way
>> +  },
>> +  "L3 Cache\0"
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L1 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x180,                  // L1 enabled, Write Back
>> +    0x8001,                 // 64k i cache max
>> +    0x8001,                 // 64k installed
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    0,                      // unkown speed
>> +    CacheErrorParity,       // parity checking
>> +    CacheTypeUnified,       // Unified cache
>> +    CacheAssociativity4Way, // 4-way
>> +  },
>> +  "L1 Cache\0"
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L2 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x181,                  // L2 enabled, Write Back
>> +    0x8010,                 // 1M cache max
>> +    0x8010,                 // 1M installed
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    {0, 0, 0, 0, 0, 1},     // SRAM type
>> +    0,                      // unkown speed
>> +    CacheErrorSingleBit,    // single bit ECC
>> +    CacheTypeUnified,       // Unified cache
>> +    CacheAssociativity8Way, // 8-way
>> +  },
>> +  "L2 Cache\0"
>> +};
>> +
>> +// Type 7 Cache Information
>> +STATIC ARM_TYPE7 mArmDefaultType7Sk1L3 = {
>> +  {
>> +    {                                    // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_CACHE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE7),       // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    0x182,                   // L3 enabled, Write Back
>> +    0x8200,                  // 32M cache max
>> +    0x8200,                  // 32M installed
>> +    {0, 0, 0, 0, 0, 1},      // SRAM type
>> +    {0, 0, 0, 0, 0, 1},      // SRAM type
>> +    0,                       // unkown speed
>> +    CacheErrorParity,        // parity checking
>> +    CacheTypeUnified,        // Unified cache
>> +    CacheAssociativity16Way, // 16-way
>> +  },
>> +  "L3 Cache\0"
>> +};
>> +
>> +STATIC CONST VOID *DefaultCommonTables[] =
>> +{
>> +  &mArmDefaultType4Sk0,
>> +  &mArmDefaultType4Sk1,
>> +  NULL
>> +};
>> +
>> +STATIC CONST VOID *DefaultType7Sk0Tables[] =
>> +{
>> +  &mArmDefaultType7Sk0L1,
>> +  &mArmDefaultType7Sk0L2,
>> +  &mArmDefaultType7Sk0L3,
>> +  NULL
>> +};
>> +
>> +STATIC CONST VOID *DefaultType7Sk1Tables[] =
>> +{
>> +  &mArmDefaultType7Sk1L1,
>> +  &mArmDefaultType7Sk1L2,
>> +  &mArmDefaultType7Sk1L3,
>> +  NULL
>> +};
>> +
>> +STATIC
>> +UINT32
>> +GetCacheConfig (
>> +  UINT32 Level
>> +  )
>> +{
>> +  UINT64  Val;
>> +  BOOLEAN SupportWB;
>> +  BOOLEAN SupportWT;
>> +
>> +  Val = ReadCCSIDR (Level);
>> +  SupportWT = (Val & (1 << 31)) ? TRUE : FALSE;
>> +  SupportWB = (Val & (1 << 30)) ? TRUE : FALSE;
>> +  if (SupportWT && SupportWB) {
>> +    return 2; /* Varies with Memory Address */
>> +  }
>> +
>> +  if (SupportWT) {
>> +    return 0;
>> +  }
>> +
>> +  return 1; /* WB */
>> +}
>> +
>> +STATIC
>> +UINTN
>> +GetStringPackSize (
>> +  CHAR8 *StringPack
>> +  )
>> +{
>> +  UINTN StrCount;
>> +  CHAR8 *StrStart;
>> +
>> +  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
>> +    return 0;
>> +  }
>> +
>> +  // String section ends in double-null (0000h)
>> +  for (StrCount = 0, StrStart = StringPack;
>> +       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
>> +  {
>> +  }
>> +
>> +  return StrCount + 2; // Included the double NULL
>> +}
>> +
>> +// Update String at String number to String Pack
>> +EFI_STATUS
>> +UpdateStringPack (
>> +  CHAR8 *StringPack,
>> +  CHAR8 *String,
>> +  UINTN StringNumber
>> +  )
>> +{
>> +  CHAR8 *StrStart;
>> +  UINTN StrIndex;
>> +  UINTN InputStrLen;
>> +  UINTN TargetStrLen;
>> +  UINTN BufferSize;
>> +  CHAR8 *Buffer;
>> +
>> +  StrStart = StringPack;
>> +  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
>> +    // A string ends in 00h
>> +    if (*StrStart == 0) {
>> +      StrIndex++;
>> +    }
>> +    // String section ends in double-null (0000h)
>> +    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
>> +      return EFI_NOT_FOUND;
>> +    }
>> +  }
>> +
>> +  if (*StrStart == 0) {
>> +    StrStart++;
>> +  }
>> +
>> +  InputStrLen = AsciiStrLen (String);
>> +  TargetStrLen = AsciiStrLen (StrStart);
>> +  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
>> +
>> +  // Replace the String if length matched
>> +  // OR this is the last string
>> +  if (InputStrLen == TargetStrLen || (BufferSize == 0)) {
>> +    CopyMem (StrStart, String, InputStrLen);
>> +  }
>> +  // Otherwise, buffer is needed to apply new string
>> +  else {
> Move else to same line as {
>
> Apart from that, with the understanding that this is a work in
> progress, but provides some value already:
>
> Reviewed-by: Leif Lindholm <leif@nuviainc.com>
>
> For the improvement works, I would appreciate if you could look at
> what we've done so far both with regards to ArmPkg/Universal/Smbios
> and the helper functions added for that, to see how we could reduce
> the amount of platform-specific code.

Because the cache-related functions/definitions in the AmpereCpuLib will 
be replaced by ArmLib so I'm going to replace the SmbiosCpuDxe by 
ArmPkg/Universal/Smbios/ProcessorSubClassDxe/ProcessorSubClassDxe.inf in 
the v3.

Other SMBIOS Types will be improved in the future.

Best regards,

Nhi

>
> /
>      Leif
>
>> +    Buffer = AllocateZeroPool (BufferSize);
>> +    if (Buffer == NULL) {
>> +      return EFI_OUT_OF_RESOURCES;
>> +    }
>> +
>> +    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
>> +    CopyMem (StrStart, String, InputStrLen + 1);
>> +    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
>> +
>> +    FreePool (Buffer);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +VOID
>> +UpdateSmbiosType4 (
>> +  PLATFORM_INFO_HOB  *PlatformHob
>> +  )
>> +{
>> +  UINTN              Index;
>> +  CHAR8              Str[40];
>> +  CHAR8              *StringPack;
>> +  SMBIOS_TABLE_TYPE4 *Table;
>> +
>> +  ASSERT (PlatformHob != NULL);
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    if (Index == 0) {
>> +      Table = &mArmDefaultType4Sk0.Base;
>> +      StringPack = mArmDefaultType4Sk0.Strings;
>> +    } else {
>> +      Table = &mArmDefaultType4Sk1.Base;
>> +      StringPack = mArmDefaultType4Sk1.Strings;
>> +    }
>> +
>> +    AsciiSPrint (Str, sizeof (Str), "CPU %d", Index);
>> +    UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_1);
>> +
>> +    Table->CoreCount = (UINT8)GetMaximumNumberOfCores ();
>> +    Table->ThreadCount = (UINT8)GetMaximumNumberOfCores ();
>> +    Table->EnabledCoreCount = (UINT8)GetNumberOfActiveCoresPerSocket (Index);
>> +
>> +    if (Table->EnabledCoreCount) {
>> +      Table->CurrentSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
>> +      Table->ExternalClock = (UINT16)(PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
>> +      Table->MaxSpeed = (UINT16)(PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
>> +      if (PlatformHob->TurboCapability[Index]) {
>> +        Table->MaxSpeed = (UINT16)(PlatformHob->TurboFrequency[Index]);
>> +      }
>> +    } else {
>> +      Table->CurrentSpeed = 0;
>> +      Table->ExternalClock = 0;
>> +      Table->MaxSpeed = 0;
>> +      Table->Status = 0;
>> +    }
>> +
>> +    *((UINT32 *)&Table->ProcessorId) = (UINT32)ArmReadMidr ();
>> +    *((UINT32 *)&Table->ProcessorId + 1) = 0;
>> +    *((UINT8 *)&Table->Voltage) = 0x80 | PlatformHob->CoreVoltage[Index] / 100;
>> +
>> +    /* Type 4 Part number */
>> +    if (Table->EnabledCoreCount) {
>> +      if ((PlatformHob->ScuProductId[Index] & 0xff) == 0x01) {
>> +        AsciiSPrint (
>> +          Str,
>> +          sizeof (Str),
>> +          "Q%02d-%02X",
>> +          PlatformHob->SkuMaxCore[Index],
>> +          PlatformHob->SkuMaxTurbo[Index]
>> +          );
>> +      } else {
>> +        AsciiSPrint (
>> +          Str,
>> +          sizeof (Str),
>> +          "M%02d%02X",
>> +          PlatformHob->SkuMaxCore[Index],
>> +          PlatformHob->SkuMaxTurbo[Index]
>> +          );
>> +      }
>> +
>> +      UpdateStringPack (StringPack, Str, ADDITIONAL_STR_INDEX_4);
>> +    }
>> +  }
>> +}
>> +
>> +STATIC
>> +VOID
>> +UpdateSmbiosType7 (
>> +  PLATFORM_INFO_HOB  *PlatformHob
>> +  )
>> +{
>> +  UINTN              Index;
>> +  SMBIOS_TABLE_TYPE7 *Table;
>> +
>> +  ASSERT (PlatformHob != NULL);
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets (); Index++) {
>> +    if (Index == 0) {
>> +      Table = &mArmDefaultType7Sk0L1.Base;
>> +    } else {
>> +      Table = &mArmDefaultType7Sk1L1.Base;
>> +    }
>> +
>> +    Table->Associativity = (UINT8)CpuGetAssociativity (1);
>> +    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (1) << 8); /* Enabled, Internal, L1 */
>> +    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (1));
>> +    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (1));
>> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (1));
>> +    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (1));
>> +
>> +    if (Index == 0) {
>> +      Table = &mArmDefaultType7Sk0L2.Base;
>> +    } else {
>> +      Table = &mArmDefaultType7Sk1L2.Base;
>> +    }
>> +
>> +    Table->Associativity = (UINT8)CpuGetAssociativity (2);
>> +    Table->CacheConfiguration = (1 << 7 | GetCacheConfig (2) << 8 | 1); /* Enabled, Internal, L2 */
>> +    Table->MaximumCacheSize  = CACHE_SIZE (CpuGetCacheSize (2));
>> +    Table->InstalledSize     = CACHE_SIZE (CpuGetCacheSize (2));
>> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (CpuGetCacheSize (2));
>> +    Table->InstalledSize2    = CACHE_SIZE_2 (CpuGetCacheSize (2));
>> +
>> +    if (Index == 0) {
>> +      Table = &mArmDefaultType7Sk0L3.Base;
>> +    } else {
>> +      Table = &mArmDefaultType7Sk1L3.Base;
>> +    }
>> +
>> +    // CpuGetCacheSize() not return L3 size, set it to 32MB
>> +    Table->MaximumCacheSize  = CACHE_SIZE (32 << 20);
>> +    Table->InstalledSize     = CACHE_SIZE (32 << 20);
>> +    Table->MaximumCacheSize2 = CACHE_SIZE_2 (32 << 20);
>> +    Table->InstalledSize2    = CACHE_SIZE_2 (32 << 20);
>> +  }
>> +
>> +  if (GetNumberOfSupportedSockets () == 2 && GetNumberOfActiveCoresPerSocket (1) == 0) {
>> +    mArmDefaultType7Sk1L1.Base.InstalledSize = 0;
>> +    mArmDefaultType7Sk1L1.Base.InstalledSize2 = 0;
>> +    mArmDefaultType7Sk1L2.Base.InstalledSize = 0;
>> +    mArmDefaultType7Sk1L2.Base.InstalledSize2 = 0;
>> +    mArmDefaultType7Sk1L3.Base.InstalledSize = 0;
>> +    mArmDefaultType7Sk1L3.Base.InstalledSize2 = 0;
>> +  }
>> +
>> +}
>> +
>> +STATIC
>> +VOID
>> +UpdateSmbiosInfo (
>> +  VOID
>> +  )
>> +{
>> +  VOID               *Hob;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  ASSERT (Hob != NULL);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  UpdateSmbiosType4 (PlatformHob);
>> +  UpdateSmbiosType7 (PlatformHob);
>> +}
>> +
>> +/**
>> +   Install SMBIOS Type 7 table
>> +
>> +   @param  Smbios               SMBIOS protocol.
>> +**/
>> +EFI_STATUS
>> +InstallType7Structures (
>> +  IN EFI_SMBIOS_PROTOCOL *Smbios
>> +  )
>> +{
>> +  EFI_STATUS         Status = EFI_SUCCESS;
>> +  EFI_SMBIOS_HANDLE  SmbiosHandle;
>> +  SMBIOS_TABLE_TYPE4 *Type4Table;
>> +  CONST VOID         **Tables;
>> +  UINTN              Index;
>> +  UINTN              Level;
>> +
>> +  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
>> +    if ( Index == 0) {
>> +      Tables = DefaultType7Sk0Tables;
>> +      Type4Table = &mArmDefaultType4Sk0.Base;
>> +    } else {
>> +      Tables = DefaultType7Sk1Tables;
>> +      Type4Table = &mArmDefaultType4Sk1.Base;
>> +    }
>> +
>> +    for (Level = 0; Level < CPU_CACHE_LEVEL_MAX; Level++ ) {
>> +      SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)Tables[Level])->Handle;
>> +      Status = Smbios->Add (
>> +                         Smbios,
>> +                         NULL,
>> +                         &SmbiosHandle,
>> +                         (EFI_SMBIOS_TABLE_HEADER *)Tables[Level]
>> +                         );
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((
>> +          DEBUG_ERROR,
>> +          "%a: adding SMBIOS type 7 Socket %d L%d cache failed\n",
>> +          __FUNCTION__,
>> +          Index,
>> +          Level + 1
>> +          ));
>> +        // stop adding rather than continuing
>> +        return Status;
>> +      }
>> +
>> +      // Save handle to Type 4
>> +      if (Level == 0) { // L1 cache
>> +        Type4Table->L1CacheHandle = SmbiosHandle;
>> +      } else if (Level == 1) { // L2 cache
>> +        Type4Table->L2CacheHandle = SmbiosHandle;
>> +      } else if (Level == 2) { // L3 cache
>> +        Type4Table->L3CacheHandle = SmbiosHandle;
>> +      }
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +   Install a whole table worth of structructures
>> +
>> +   @param  Smbios               SMBIOS protocol.
>> +   @param  DefaultTables        A pointer to the default SMBIOS table structure.
>> +**/
>> +EFI_STATUS
>> +InstallStructures (
>> +  IN       EFI_SMBIOS_PROTOCOL *Smbios,
>> +  IN CONST VOID                *DefaultTables[]
>> +  )
>> +{
>> +  EFI_STATUS        Status = EFI_SUCCESS;
>> +  EFI_SMBIOS_HANDLE SmbiosHandle;
>> +  UINTN             Index;
>> +
>> +  for (Index = 0; Index < GetNumberOfSupportedSockets () && DefaultTables[Index] != NULL; Index++) {
>> +    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index])->Handle;
>> +    Status = Smbios->Add (
>> +                       Smbios,
>> +                       NULL,
>> +                       &SmbiosHandle,
>> +                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[Index]
>> +                       );
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, Index));
>> +
>> +      // stop adding rather than continuing
>> +      return Status;
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +   Install all structures from the DefaultTables structure
>> +
>> +   @param  Smbios               SMBIOS protocol
>> +
>> +**/
>> +EFI_STATUS
>> +InstallAllStructures (
>> +  IN EFI_SMBIOS_PROTOCOL *Smbios
>> +  )
>> +{
>> +  EFI_STATUS Status = EFI_SUCCESS;
>> +
>> +  UpdateSmbiosInfo ();
>> +
>> +  // Install Type 7 structures
>> +  InstallType7Structures (Smbios);
>> +
>> +  // Install Tables
>> +  Status = InstallStructures (Smbios, DefaultCommonTables);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return Status;
>> +}
>> +
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +SmbiosCpuDxeEntry (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS          Status;
>> +  EFI_SMBIOS_PROTOCOL *Smbios;
>> +
>> +  //
>> +  // Find the SMBIOS protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiSmbiosProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&Smbios
>> +                  );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
>> +    ASSERT_EFI_ERROR (Status);
>> +    return Status;
>> +  }
>> +
>> +  Status = InstallAllStructures (Smbios);
>> +  DEBUG ((DEBUG_ERROR, "SmbiosCpu install: %r\n", Status));
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
>> new file mode 100644
>> index 000000000000..a262239b53ba
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosMemInfoDxe/SmbiosMemInfoDxe.c
>> @@ -0,0 +1,705 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Guid/SmBios.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/PrintLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Protocol/Smbios.h>
>> +
>> +#define TYPE16_ADDITIONAL_STRINGS        \
>> +  "\0" /* no string*/
>> +
>> +#define TYPE17_ADDITIONAL_STRINGS        \
>> +  "Device Locator not set \0"  \
>> +  "Bank Locator not set \0"    \
>> +  "Manufacturer not set \0"    \
>> +  "Serial Number not set \0"   \
>> +  "Asset Tag not set \0"       \
>> +  "Part Number not set \0"     \
>> +
>> +#define TYPE19_ADDITIONAL_STRINGS        \
>> +  "\0" /* no string */
>> +
>> +//
>> +// Type definition and contents of the default SMBIOS table.
>> +// This table covers only the minimum structures required by
>> +// the SMBIOS specification (section 6.2, version 3.0)
>> +//
>> +#pragma pack(1)
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE16 Base;
>> +  CHAR8               Strings[sizeof (TYPE16_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE16;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE17 Base;
>> +  CHAR8               Strings[sizeof (TYPE17_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE17;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE19 Base;
>> +  CHAR8               Strings[sizeof (TYPE19_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE19;
>> +
>> +#pragma pack()
>> +// Type 16 Physical Memory Array
>> +STATIC ARM_TYPE16 mArmDefaultType16 = {
>> +  {
>> +    {                                        // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PHYSICAL_MEMORY_ARRAY, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE16),          // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    MemoryArrayLocationSystemBoard,   // on motherboard
>> +    MemoryArrayUseSystemMemory,       // system RAM
>> +    MemoryErrorCorrectionMultiBitEcc, // ECC RAM
>> +    0x80000000,
>> +    0xFFFE,   // No error information structure
>> +    0x10,
>> +    0x40000000000ULL,
>> +  },
>> +  TYPE16_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 17 Memory Device
>> +STATIC ARM_TYPE17 mArmDefaultType17 = {
>> +  {
>> +    { // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_MEMORY_DEVICE,
>> +      sizeof (SMBIOS_TABLE_TYPE17),
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    0xFFFF,                         // array to which this module belongs
>> +    0xFFFE,                         // no errors
>> +    72,                             // single DIMM with ECC
>> +    64,                             // data width of this device (64-bits)
>> +    0,                              // no module installed
>> +    0x09,                           // DIMM
>> +    1,                              // part of a set
>> +    1,                              // device locator
>> +    2,                              // bank locator
>> +    MemoryTypeDdr4,                 // DDR4
>> +    {},                             // type detail
>> +    0,                              // ? MHz
>> +    3,                              // manufacturer
>> +    4,                              // serial
>> +    5,                              // asset tag
>> +    6,                              // part number
>> +    0,                              // rank
>> +  },
>> +  TYPE17_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 19 Memory Array Mapped Address
>> +STATIC ARM_TYPE19 mArmDefaultType19 = {
>> +  {
>> +    {  // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS,
>> +      sizeof (SMBIOS_TABLE_TYPE19),
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    0xFFFFFFFF, // invalid, look at extended addr field
>> +    0xFFFFFFFF,
>> +    0xFFFF,    // handle
>> +    1,
>> +    0x0,
>> +    0x0,
>> +  },
>> +  TYPE19_ADDITIONAL_STRINGS
>> +};
>> +
>> +typedef struct _JEDEC_MF_ID {
>> +  UINT8 VendorId;
>> +  CHAR8 *ManufacturerString;
>> +} JEDEC_MF_ID;
>> +
>> +JEDEC_MF_ID Bank0Table[] = {
>> +  { 0x01, "AMD" },
>> +  { 0x04, "Fujitsu" },
>> +  { 0x07, "Hitachi" },
>> +  { 0x89, "Intel" },
>> +  { 0x10, "NEC" },
>> +  { 0x97, "Texas Instrument" },
>> +  { 0x98, "Toshiba" },
>> +  { 0x1c, "Mitsubishi" },
>> +  { 0x1f, "Atmel" },
>> +  { 0x20, "STMicroelectronics" },
>> +  { 0xa4, "IBM" },
>> +  { 0x2c, "Micron Technology" },
>> +  { 0xad, "SK Hynix" },
>> +  { 0xb0, "Sharp" },
>> +  { 0xb3, "IDT" },
>> +  { 0x3e, "Oracle" },
>> +  { 0xbf, "SST" },
>> +  { 0x40, "ProMos/Mosel" },
>> +  { 0xc1, "Infineon" },
>> +  { 0xc2, "Macronix" },
>> +  { 0x45, "SanDisk" },
>> +  { 0xce, "Samsung" },
>> +  { 0xda, "Winbond" },
>> +  { 0xe0, "LG Semi" },
>> +  { 0x62, "Sanyo" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank1Table[] = {
>> +  { 0x98, "Kingston" },
>> +  { 0xba, "PNY" },
>> +  { 0x4f, "Transcend" },
>> +  { 0x7a, "Apacer" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank2Table[] = {
>> +  { 0x9e, "Corsair" },
>> +  { 0xfe, "Elpida" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank3Table[] = {
>> +  { 0x0b, "Nanya" },
>> +  { 0x94, "Mushkin" },
>> +  { 0x25, "Kingmax" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank4Table[] = {
>> +  { 0xb0, "OCZ" },
>> +  { 0xcb, "A-DATA" },
>> +  { 0xcd, "G Skill" },
>> +  { 0xef, "Team" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank5Table[] = {
>> +  { 0x02, "Patriot" },
>> +  { 0x9b, "Crucial" },
>> +  { 0x51, "Qimonda" },
>> +  { 0x57, "AENEON" },
>> +  { 0xf7, "Avant" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank6Table[] = {
>> +  { 0x34, "Super Talent" },
>> +  { 0xd3, "Silicon Power" },
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID Bank7Table[] = {
>> +  { 0xff, "Undefined" }
>> +};
>> +
>> +JEDEC_MF_ID *ManufacturerJedecIdBankTable[] = {
>> +  Bank0Table,
>> +  Bank1Table,
>> +  Bank2Table,
>> +  Bank3Table,
>> +  Bank4Table,
>> +  Bank5Table,
>> +  Bank6Table,
>> +  Bank7Table
>> +};
>> +
>> +STATIC
>> +UINTN
>> +GetStringPackSize (
>> +  CHAR8 *StringPack
>> +  )
>> +{
>> +  UINTN StrCount;
>> +  CHAR8 *StrStart;
>> +
>> +  if ((*StringPack == 0) && (*(StringPack + 1) == 0)) {
>> +    return 0;
>> +  }
>> +
>> +  // String section ends in double-null (0000h)
>> +  for (StrCount = 0, StrStart = StringPack;
>> +       ((*StrStart != 0) || (*(StrStart + 1) != 0)); StrStart++, StrCount++)
>> +  {
>> +  }
>> +
>> +  return StrCount + 2; // Included the double NULL
>> +}
>> +
>> +// Update String at String number to String Pack
>> +EFI_STATUS
>> +UpdateStringPack (
>> +  CHAR8 *StringPack,
>> +  CHAR8 *String,
>> +  UINTN StringNumber
>> +  )
>> +{
>> +  CHAR8 *StrStart;
>> +  UINTN StrIndex;
>> +  UINTN InputStrLen;
>> +  UINTN TargetStrLen;
>> +  UINTN BufferSize;
>> +  CHAR8 *Buffer;
>> +
>> +  StrStart = StringPack;
>> +  for (StrIndex = 1; StrIndex < StringNumber; StrStart++) {
>> +    // A string ends in 00h
>> +    if (*StrStart == 0) {
>> +      StrIndex++;
>> +    }
>> +    // String section ends in double-null (0000h)
>> +    if ((*StrStart == 0) && (*(StrStart + 1) == 0)) {
>> +      return EFI_NOT_FOUND;
>> +    }
>> +  }
>> +
>> +  if (*StrStart == 0) {
>> +    StrStart++;
>> +  }
>> +
>> +  InputStrLen = AsciiStrLen (String);
>> +  TargetStrLen = AsciiStrLen (StrStart);
>> +  BufferSize = GetStringPackSize (StrStart + TargetStrLen + 1);
>> +
>> +  // Replace the String if length matched
>> +  // OR this is the last string
>> +  if ((InputStrLen == TargetStrLen) || (BufferSize == 0)) {
>> +    CopyMem (StrStart, String, InputStrLen);
>> +  }
>> +  // Otherwise, buffer is needed to apply new string
>> +  else {
>> +    Buffer = AllocateZeroPool (BufferSize);
>> +    if (Buffer == NULL) {
>> +      return EFI_OUT_OF_RESOURCES;
>> +    }
>> +
>> +    CopyMem (Buffer, StrStart + TargetStrLen + 1, BufferSize);
>> +    CopyMem (StrStart, String, InputStrLen + 1);
>> +    CopyMem (StrStart + InputStrLen + 1, Buffer, BufferSize);
>> +
>> +    FreePool (Buffer);
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +UINT8
>> +GetMemoryType (
>> +  IN UINT8 *SpdData
>> +  )
>> +{
>> +  return (SpdData[2] == 0x08) ? 1 :    // DDR2
>> +         (SpdData[2] == 0x0B) ? 2 :    // DDR3
>> +         (SpdData[2] == 0x0C) ? 3 : 0; // DDR4
>> +}
>> +
>> +EFI_STATUS
>> +UpdateManufacturer (
>> +  IN VOID  *Table,
>> +  IN UINT8 *SpdData
>> +  )
>> +{
>> +  EFI_STATUS  Status = EFI_SUCCESS;
>> +  UINTN       i;
>> +  UINT8       Data8;
>> +  UINT8       MemType;
>> +  JEDEC_MF_ID *IdTblPtr = NULL;
>> +
>> +  MemType = GetMemoryType (SpdData);
>> +
>> +  switch (MemType) {
>> +  case 1:
>> +    for (i = 0; i < 8; i++) {      // DDR2
>> +      Data8 = SpdData[64 + i];
>> +      if (Data8 != 0x7f) {
>> +        break;
>> +      }
>> +    }
>> +    break;
>> +
>> +  case 2:                    // DDR3
>> +    i = SpdData[117] & 0x7f; // Remove parity bit
>> +    Data8 = SpdData[118];
>> +    break;
>> +
>> +  case 3:                    // DDR4
>> +    i = SpdData[320] & 0x7f; // Remove parity bit
>> +    Data8 = SpdData[321];
>> +    break;
>> +
>> +  default:
>> +    return EFI_UNSUPPORTED;  // Not supported
>> +  }
>> +
>> +  if (i > 7) {
>> +    i = 7;
>> +  }
>> +  IdTblPtr = ManufacturerJedecIdBankTable[i];
>> +
>> +  // Search in Manufacturer table
>> +  while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
>> +    IdTblPtr++;
>> +  }
>> +
>> +  if (IdTblPtr->VendorId != 0xff) {
>> +    Status = UpdateStringPack (
>> +               ((ARM_TYPE17 *)Table)->Strings,
>> +               IdTblPtr->ManufacturerString,
>> +               ((ARM_TYPE17 *)Table)->Base.Manufacturer
>> +               );
>> +  }
>> +
>> +  return Status;
>> +}
>> +
>> +EFI_STATUS
>> +UpdateSerialNumber (
>> +  IN VOID  *Table,
>> +  IN UINT8 *SpdData
>> +  )
>> +{
>> +  UINT8 MemType;
>> +  UINTN Offset;
>> +  CHAR8 Str[64];
>> +
>> +  MemType = GetMemoryType (SpdData);
>> +
>> +  switch (MemType) {
>> +  case 1:
>> +    Offset = 95;
>> +    break;
>> +
>> +  case 2:                          // DDR3
>> +    Offset = 122;
>> +    break;
>> +
>> +  case 3:                          // DDR4
>> +    Offset = 325;
>> +    break;
>> +
>> +  default:
>> +    return EFI_UNSUPPORTED;        // Not supported
>> +  }
>> +
>> +  AsciiSPrint (
>> +    Str,
>> +    sizeof (Str),
>> +    "%02X%02X%02X%02X",
>> +    SpdData[Offset],
>> +    SpdData[Offset + 1],
>> +    SpdData[Offset + 2],
>> +    SpdData[Offset + 3]
>> +    );
>> +
>> +  return UpdateStringPack (
>> +           ((ARM_TYPE17 *)Table)->Strings,
>> +           Str,
>> +           ((ARM_TYPE17 *)Table)->Base.SerialNumber
>> +           );
>> +}
>> +
>> +CHAR8
>> +Printable (
>> +  IN CHAR8 Character
>> +  )
>> +{
>> +  if((Character >= 0x20) && (Character <= 0x7E)) {
>> +    return Character;
>> +  }
>> +
>> +  return ' ';
>> +}
>> +
>> +EFI_STATUS
>> +UpdatePartNumber (
>> +  IN VOID  *Table,
>> +  IN UINT8 *SpdData
>> +  )
>> +{
>> +  UINT8 MemType;
>> +  UINTN Offset;
>> +  CHAR8 Str[64];
>> +
>> +  MemType = GetMemoryType (SpdData);
>> +
>> +  switch (MemType) {
>> +  case 1:
>> +    Offset = 73;
>> +    break;
>> +
>> +  case 2:                          // DDR3
>> +    Offset = 128;
>> +    break;
>> +
>> +  case 3:                          // DDR4
>> +    Offset = 329;
>> +    break;
>> +
>> +  default:
>> +    return EFI_UNSUPPORTED;        // Not supported
>> +  }
>> +
>> +  AsciiSPrint (
>> +    Str,
>> +    sizeof (Str),
>> +    "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
>> +    Printable (SpdData[Offset]),
>> +    Printable (SpdData[Offset + 1]),
>> +    Printable (SpdData[Offset + 2]),
>> +    Printable (SpdData[Offset + 3]),
>> +    Printable (SpdData[Offset + 4]),
>> +    Printable (SpdData[Offset + 5]),
>> +    Printable (SpdData[Offset + 6]),
>> +    Printable (SpdData[Offset + 7]),
>> +    Printable (SpdData[Offset + 8]),
>> +    Printable (SpdData[Offset + 9]),
>> +    Printable (SpdData[Offset + 10]),
>> +    Printable (SpdData[Offset + 11]),
>> +    Printable (SpdData[Offset + 12]),
>> +    Printable (SpdData[Offset + 13]),
>> +    Printable (SpdData[Offset + 14]),
>> +    Printable (SpdData[Offset + 15]),
>> +    Printable (SpdData[Offset + 16]),
>> +    Printable (SpdData[Offset + 17])
>> +    );
>> +
>> +  return UpdateStringPack (
>> +           ((ARM_TYPE17 *)Table)->Strings,
>> +           Str,
>> +           ((ARM_TYPE17 *)Table)->Base.PartNumber
>> +           );
>> +}
>> +
>> +/**
>> +   Install SMBIOS Type 16 17 and 19 table
>> +
>> +   @param  Smbios               SMBIOS protocol.
>> +**/
>> +EFI_STATUS
>> +InstallMemStructures (
>> +  IN EFI_SMBIOS_PROTOCOL *Smbios
>> +  )
>> +{
>> +  EFI_STATUS         Status = EFI_SUCCESS;
>> +  EFI_SMBIOS_HANDLE  SmbiosHandle;
>> +  EFI_SMBIOS_HANDLE  Type16Handle;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +  PLATFORM_DIMM      *Dimm;
>> +  CHAR8              *Table;
>> +  VOID               *Hob;
>> +  UINTN              Index;
>> +  UINTN              SlotIndex;
>> +  UINTN              MemRegionIndex;
>> +  UINT64             MemorySize = 0;
>> +  CHAR8              Str[64];
>> +
>> +  ASSERT (Smbios != NULL);
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  ASSERT (Hob != NULL);
>> +  if (Hob == NULL) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  Table = AllocateZeroPool (sizeof (ARM_TYPE17));
>> +  if (Table == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  for ( Index = 0; Index < GetNumberOfSupportedSockets (); Index++ ) {
>> +    // Copy template to Type 16
>> +    CopyMem (Table, (VOID *)&mArmDefaultType16, sizeof (ARM_TYPE16));
>> +
>> +    ((ARM_TYPE16 *)Table)->Base.MaximumCapacity = 0x80000000;
>> +    ((ARM_TYPE16 *)Table)->Base.ExtendedMaximumCapacity = 0x40000000000ULL; /* 4TB per socket */
>> +    ((ARM_TYPE16 *)Table)->Base.MemoryErrorCorrection = MemoryErrorCorrectionMultiBitEcc;
>> +
>> +    // Install Type 16 and hold the handle so that the subsequence type17/19 could use
>> +    Type16Handle = ((ARM_TYPE16 *)Table)->Base.Hdr.Handle;
>> +    Status = Smbios->Add (
>> +                       Smbios,
>> +                       NULL,
>> +                       &Type16Handle,
>> +                       (EFI_SMBIOS_TABLE_HEADER *)Table
>> +                       );
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "%a: adding SMBIOS type 16 socket %d failed\n", __FUNCTION__, Index));
>> +      FreePool (Table);
>> +      // stop adding rather than continuing
>> +      return Status;
>> +    }
>> +
>> +    for (SlotIndex = 0; SlotIndex < PlatformHob->DimmList.BoardDimmSlots; SlotIndex++) {
>> +      // Copy Tempplate to Type 17
>> +      CopyMem (Table, (VOID *)&mArmDefaultType17, sizeof (ARM_TYPE17));
>> +
>> +      // Fill up type 17 table's content here
>> +      Dimm = &PlatformHob->DimmList.Dimm[SlotIndex];
>> +      if (Dimm->NodeId != Index) {
>> +        continue;
>> +      }
>> +
>> +      if (Dimm->Info.DimmStatus == DIMM_INSTALLED_OPERATIONAL) {
>> +
>> +        UpdateManufacturer ((VOID *)Table, Dimm->SpdData.Data);
>> +        UpdateSerialNumber ((VOID *)Table, Dimm->SpdData.Data);
>> +        UpdatePartNumber ((VOID *)Table, Dimm->SpdData.Data);
>> +
>> +        MemorySize = Dimm->Info.DimmSize * 1024;
>> +        if (MemorySize >= 0x7FFF) {
>> +          ((ARM_TYPE17 *)Table)->Base.Size = 0x7FFF;
>> +          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = MemorySize;
>> +        } else {
>> +          ((ARM_TYPE17 *)Table)->Base.Size = (UINT16)MemorySize;
>> +          ((ARM_TYPE17 *)Table)->Base.ExtendedSize = 0;
>> +        }
>> +
>> +        ((ARM_TYPE17 *)Table)->Base.MemoryType = 0x1A; /* DDR4 */
>> +        ((ARM_TYPE17 *)Table)->Base.Speed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
>> +        ((ARM_TYPE17 *)Table)->Base.ConfiguredMemoryClockSpeed = (UINT16)PlatformHob->DramInfo.MaxSpeed;
>> +        ((ARM_TYPE17 *)Table)->Base.Attributes = Dimm->Info.DimmNrRank & 0x0F;
>> +        ((ARM_TYPE17 *)Table)->Base.ConfiguredVoltage = 1200;
>> +        ((ARM_TYPE17 *)Table)->Base.MinimumVoltage = 1140;
>> +        ((ARM_TYPE17 *)Table)->Base.MaximumVoltage = 1260;
>> +        ((ARM_TYPE17 *)Table)->Base.DeviceSet = 0; // None
>> +
>> +        if (Dimm->Info.DimmType == UDIMM || Dimm->Info.DimmType == SODIMM) {
>> +          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Unbuffered = 1; /* BIT 14: unregistered */
>> +        } else if (Dimm->Info.DimmType == RDIMM
>> +                   || Dimm->Info.DimmType == LRDIMM
>> +                   || Dimm->Info.DimmType == RSODIMM)
>> +        {
>> +          ((ARM_TYPE17 *)Table)->Base.TypeDetail.Registered = 1; /* BIT 13: registered */
>> +        }
>> +        /* FIXME: Determine if need to set technology to NVDIMM-* when supported */
>> +        ((ARM_TYPE17 *)Table)->Base.MemoryTechnology = 0x3; // DRAM
>> +      }
>> +      AsciiSPrint (Str, sizeof (Str), "Socket %d DIMM %d", Index, SlotIndex);
>> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.DeviceLocator);
>> +      AsciiSPrint (Str, sizeof (Str), "Bank %d", SlotIndex);
>> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.BankLocator);
>> +      AsciiSPrint (Str, sizeof (Str), "Array %d Asset Tag %d", Index, SlotIndex);
>> +      UpdateStringPack (((ARM_TYPE17 *)Table)->Strings, Str, ((ARM_TYPE17 *)Table)->Base.AssetTag);
>> +
>> +      // Update Type 16 handle
>> +      ((ARM_TYPE17 *)Table)->Base.MemoryArrayHandle = Type16Handle;
>> +
>> +      // Install structure
>> +      SmbiosHandle = ((ARM_TYPE17 *)Table)->Base.Hdr.Handle;
>> +      Status = Smbios->Add (
>> +                         Smbios,
>> +                         NULL,
>> +                         &SmbiosHandle,
>> +                         (EFI_SMBIOS_TABLE_HEADER *)Table
>> +                         );
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((
>> +          DEBUG_ERROR,
>> +          "%a: adding SMBIOS type 17 Socket %d Slot %d failed\n",
>> +          __FUNCTION__,
>> +          Index,
>> +          SlotIndex
>> +          ));
>> +        FreePool (Table);
>> +        // stop adding rather than continuing
>> +        return Status;
>> +      }
>> +    }
>> +
>> +    for (MemRegionIndex = 0; MemRegionIndex < PlatformHob->DramInfo.NumRegion; MemRegionIndex++) {
>> +      // Copy Tempplate to Type 19
>> +      CopyMem (Table, (VOID *)&mArmDefaultType19, sizeof (ARM_TYPE19));
>> +
>> +      if (PlatformHob->DramInfo.NvdRegion[MemRegionIndex] > 0
>> +          || PlatformHob->DramInfo.Socket[MemRegionIndex] != Index)
>> +      {
>> +        continue;
>> +      }
>> +
>> +      ((ARM_TYPE19 *)Table)->Base.StartingAddress = 0xFFFFFFFF;
>> +      ((ARM_TYPE19 *)Table)->Base.EndingAddress = 0xFFFFFFFF;
>> +      ((ARM_TYPE19 *)Table)->Base.ExtendedStartingAddress = PlatformHob->DramInfo.Base[MemRegionIndex];
>> +      ((ARM_TYPE19 *)Table)->Base.ExtendedEndingAddress = PlatformHob->DramInfo.Base[MemRegionIndex] +
>> +                                                          PlatformHob->DramInfo.Size[MemRegionIndex] - 1;
>> +
>> +      if (MemorySize != 0) {
>> +        ((ARM_TYPE19 *)Table)->Base.PartitionWidth = (PlatformHob->DramInfo.Size[MemRegionIndex] - 1) / MemorySize + 1;
>> +      }
>> +
>> +      // Update Type 16 handle
>> +      ((ARM_TYPE19 *)Table)->Base.MemoryArrayHandle = Type16Handle;
>> +
>> +      // Install structure
>> +      SmbiosHandle = ((ARM_TYPE19 *)Table)->Base.Hdr.Handle;
>> +      Status = Smbios->Add (
>> +                         Smbios,
>> +                         NULL,
>> +                         &SmbiosHandle,
>> +                         (EFI_SMBIOS_TABLE_HEADER *)Table
>> +                         );
>> +      if (EFI_ERROR (Status)) {
>> +        DEBUG ((
>> +          DEBUG_ERROR,
>> +          "%a: adding SMBIOS type 19 Socket %d MemRegion %d failed\n",
>> +          __FUNCTION__,
>> +          Index,
>> +          MemRegionIndex
>> +          ));
>> +        FreePool (Table);
>> +        // stop adding rather than continuing
>> +        return Status;
>> +      }
>> +    }
>> +  }
>> +
>> +  FreePool (Table);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +SmbiosMemInfoDxeEntry (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS          Status;
>> +  EFI_SMBIOS_PROTOCOL *Smbios;
>> +
>> +  //
>> +  // Find the SMBIOS protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiSmbiosProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&Smbios
>> +                  );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Unable to locate SMBIOS Protocol"));
>> +    ASSERT_EFI_ERROR (Status);
>> +    return Status;
>> +  }
>> +
>> +  Status = InstallMemStructures (Smbios);
>> +  DEBUG ((DEBUG_ERROR, "SmbiosMemInfoDxe install: %r\n", Status));
>> +
>> +  return Status;
>> +}
>> diff --git a/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
>> new file mode 100644
>> index 000000000000..086fdd9749fb
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/SmbiosPlatformDxe/SmbiosPlatformDxe.c
>> @@ -0,0 +1,1049 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Guid/SmBios.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <PlatformInfoHob.h>
>> +#include <Protocol/Smbios.h>
>> +
>> +// Type0 Data
>> +#define VENDOR_TEMPLATE       "Ampere(R)\0"
>> +#define BIOS_VERSION_TEMPLATE "TianoCore EDKII\0"
>> +#define RELEASE_DATE_TEMPLATE "MM/DD/YYYY\0"
>> +
>> +#define TYPE0_ADDITIONAL_STRINGS                    \
>> +  VENDOR_TEMPLATE       /* Vendor */         \
>> +  BIOS_VERSION_TEMPLATE /* BiosVersion */    \
>> +  RELEASE_DATE_TEMPLATE /* BiosReleaseDate */
>> +
>> +// Type1 Data
>> +#define MANUFACTURER_TEMPLATE "Ampere(R)\0"
>> +#define PRODUCT_NAME_TEMPLATE "Mt. Jade\0"
>> +#define SYS_VERSION_TEMPLATE  "PR010\0"
>> +#define SERIAL_TEMPLATE       "123456789ABCDEFF123456789ABCDEFF\0"
>> +#define SKU_TEMPLATE          "FEDCBA9876543211FEDCBA9876543211\0"
>> +#define FAMILY_TEMPLATE       "ARMv8\0"
>> +
>> +#define TYPE1_ADDITIONAL_STRINGS                  \
>> +  MANUFACTURER_TEMPLATE /* Manufacturer */  \
>> +  PRODUCT_NAME_TEMPLATE /* Product Name */  \
>> +  SYS_VERSION_TEMPLATE  /* Version */       \
>> +  SERIAL_TEMPLATE       /* Serial Number */ \
>> +  SKU_TEMPLATE          /* SKU Number */    \
>> +  FAMILY_TEMPLATE       /* Family */
>> +
>> +#define TYPE2_ADDITIONAL_STRINGS                   \
>> +  MANUFACTURER_TEMPLATE /* Manufacturer */   \
>> +  PRODUCT_NAME_TEMPLATE /* Product Name */   \
>> +  "EVT2\0"              /* Version */        \
>> +  "Serial Not Set\0"    /* Serial */         \
>> +  "Base of Chassis\0"   /* board location */ \
>> +  "FF\0"                /* Version */        \
>> +  "FF\0"                /* Version */
>> +
>> +#define CHASSIS_VERSION_TEMPLATE    "None               \0"
>> +#define CHASSIS_SERIAL_TEMPLATE     "Serial Not Set     \0"
>> +#define CHASSIS_ASSET_TAG_TEMPLATE  "Asset Tag Not Set  \0"
>> +
>> +#define TYPE3_ADDITIONAL_STRINGS                 \
>> +  MANUFACTURER_TEMPLATE      /* Manufacturer */ \
>> +  CHASSIS_VERSION_TEMPLATE   /* Version */      \
>> +  CHASSIS_SERIAL_TEMPLATE    /* Serial  */      \
>> +  CHASSIS_ASSET_TAG_TEMPLATE /* Asset Tag */    \
>> +  SKU_TEMPLATE               /* SKU Number */
>> +
>> +#define TYPE8_ADDITIONAL_STRINGS      \
>> +  "VGA1 - Rear VGA Connector\0"       \
>> +  "DB-15 Male (VGA)         \0"
>> +
>> +#define TYPE9_ADDITIONAL_STRINGS       \
>> +  "Socket 0 Riser 1 x32 - Slot 1\0"
>> +
>> +#define TYPE11_ADDITIONAL_STRINGS       \
>> +  "www.amperecomputing.com\0"
>> +
>> +#define TYPE13_ADDITIONAL_STRINGS       \
>> +  "en|US|iso8859-1\0"
>> +
>> +#define TYPE41_ADDITIONAL_STRINGS       \
>> +  "Onboard VGA\0"
>> +
>> +//
>> +// Type definition and contents of the default SMBIOS table.
>> +// This table covers only the minimum structures required by
>> +// the SMBIOS specification (section 6.2, version 3.0)
>> +//
>> +#pragma pack(1)
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE0 Base;
>> +  CHAR8              Strings[sizeof (TYPE0_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE0;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE1 Base;
>> +  CHAR8              Strings[sizeof (TYPE1_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE1;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE2 Base;
>> +  CHAR8              Strings[sizeof (TYPE2_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE2;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE3 Base;
>> +  CHAR8              Strings[sizeof (TYPE3_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE3;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE8 Base;
>> +  CHAR8              Strings[sizeof (TYPE8_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE8;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE9 Base;
>> +  CHAR8              Strings[sizeof (TYPE9_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE9;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE11 Base;
>> +  CHAR8               Strings[sizeof (TYPE11_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE11;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE13 Base;
>> +  CHAR8               Strings[sizeof (TYPE13_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE13;
>> +
>> +typedef struct {
>> +  SMBIOS_TABLE_TYPE41 Base;
>> +  CHAR8               Strings[sizeof (TYPE41_ADDITIONAL_STRINGS)];
>> +} ARM_TYPE41;
>> +
>> +#pragma pack()
>> +
>> +//-------------------------------------
>> +//        SMBIOS Platform Common
>> +//-------------------------------------
>> +enum {
>> +  ADDITIONAL_STR_INDEX_1 = 1,
>> +  ADDITIONAL_STR_INDEX_2,
>> +  ADDITIONAL_STR_INDEX_3,
>> +  ADDITIONAL_STR_INDEX_4,
>> +  ADDITIONAL_STR_INDEX_5,
>> +  ADDITIONAL_STR_INDEX_6,
>> +  ADDITIONAL_STR_INDEX_MAX
>> +};
>> +
>> +
>> +// Type 0 BIOS information
>> +STATIC ARM_TYPE0 mArmDefaultType0 = {
>> +  {
>> +    {                                   // Header
>> +      EFI_SMBIOS_TYPE_BIOS_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE0),      // UINT8 Length, The length of the structure's string-set is not included.
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +
>> +    ADDITIONAL_STR_INDEX_1,     // SMBIOS_TABLE_STRING       Vendor
>> +    ADDITIONAL_STR_INDEX_2,     // SMBIOS_TABLE_STRING       BiosVersion
>> +    0,                          // UINT16                    BiosSegment
>> +    ADDITIONAL_STR_INDEX_3,     // SMBIOS_TABLE_STRING       BiosReleaseDate
>> +    0,                          // UINT8                     BiosSize
>> +
>> +    // MISC_BIOS_CHARACTERISTICS BiosCharacteristics
>> +    {
>> +      0,0,0,0,0,0,
>> +      1, // PCI supported
>> +      0,
>> +      1, // PNP supported
>> +      0,
>> +      1, // BIOS upgradable
>> +      0, 0, 0,
>> +      0, // Boot from CD
>> +      1, // selectable boot
>> +    },
>> +
>> +    // BIOSCharacteristicsExtensionBytes[2]
>> +    {
>> +      0,
>> +      0,
>> +    },
>> +
>> +    0,     // UINT8                     SystemBiosMajorRelease
>> +    0,     // UINT8                     SystemBiosMinorRelease
>> +
>> +    // If the system does not have field upgradeable embedded controller
>> +    // firmware, the value is 0FFh
>> +    0xFF,  // UINT8                     EmbeddedControllerFirmwareMajorRelease
>> +    0xFF   // UINT8                     EmbeddedControllerFirmwareMinorRelease
>> +  },
>> +
>> +  // Text strings (unformatted area)
>> +  TYPE0_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 1 System information
>> +STATIC ARM_TYPE1 mArmDefaultType1 = {
>> +  {
>> +    { // Header
>> +      EFI_SMBIOS_TYPE_SYSTEM_INFORMATION,
>> +      sizeof (SMBIOS_TABLE_TYPE1),
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +
>> +    ADDITIONAL_STR_INDEX_1,                                                     // Manufacturer
>> +    ADDITIONAL_STR_INDEX_2,                                                     // Product Name
>> +    ADDITIONAL_STR_INDEX_3,                                                     // Version
>> +    ADDITIONAL_STR_INDEX_4,                                                     // Serial Number
>> +    { 0x12345678, 0x9ABC, 0xDEFF, { 0x12,0x34,0x56,0x78,0x9A,0xBC,0xDE,0xFF }}, // UUID
>> +    SystemWakeupTypePowerSwitch,                                                // Wakeup type
>> +    ADDITIONAL_STR_INDEX_5,                                                     // SKU Number
>> +    ADDITIONAL_STR_INDEX_6,                                                     // Family
>> +  },
>> +
>> +  // Text strings (unformatted)
>> +  TYPE1_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 2 Baseboard
>> +STATIC ARM_TYPE2 mArmDefaultType2 = {
>> +  {
>> +    {                                        // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_BASEBOARD_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE2),           // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1, // Manufacturer
>> +    ADDITIONAL_STR_INDEX_2, // Product Name
>> +    ADDITIONAL_STR_INDEX_3, // Version
>> +    ADDITIONAL_STR_INDEX_4, // Serial
>> +    0,                      // Asset tag
>> +    {1},                    // motherboard, not replaceable
>> +    ADDITIONAL_STR_INDEX_5, // location of board
>> +    0xFFFF,                 // chassis handle
>> +    BaseBoardTypeMotherBoard,
>> +    0,
>> +    {0},
>> +  },
>> +  TYPE2_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 3 Enclosure
>> +STATIC CONST ARM_TYPE3 mArmDefaultType3 = {
>> +  {
>> +    {                                   // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_ENCLOSURE, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE3),      // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,          // Manufacturer
>> +    MiscChassisTypeRackMountChassis, // Rack-mounted chassis
>> +    ADDITIONAL_STR_INDEX_2,          // version
>> +    ADDITIONAL_STR_INDEX_3,          // serial
>> +    ADDITIONAL_STR_INDEX_4,          // asset tag
>> +    ChassisStateUnknown,             // boot chassis state
>> +    ChassisStateSafe,                // power supply state
>> +    ChassisStateSafe,                // thermal state
>> +    ChassisSecurityStatusNone,       // security state
>> +    {0,0,0,0},                       // OEM defined
>> +    1,                               // 1U height
>> +    2,                               // number of power cords
>> +    0,                               // no contained elements
>> +    3,                               // ContainedElementRecordLength;
>> +  },
>> +  TYPE3_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8Vga = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
>> +    PortConnectorTypeDB15Female,  // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
>> +    PortTypeOther,                // ExternalConnectorType;
>> +    PortTypeVideoPort,            // PortType;
>> +  },
>> +  "VGA1 - Rear VGA Connector\0" \
>> +  "DB-15 Male (VGA)\0"
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8USBFront = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
>> +    PortConnectorTypeUsb,         // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
>> +    PortTypeOther,                // ExternalConnectorType;
>> +    PortTypeUsb,                  // PortType;
>> +  },
>> +  "Front Panel USB 3.0\0"  \
>> +  "USB\0"
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8USBRear = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
>> +    PortConnectorTypeUsb,         // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
>> +    PortTypeOther,                // ExternalConnectorType;
>> +    PortTypeUsb,                  // PortType;
>> +  },
>> +  "Rear Panel USB 3.0\0"   \
>> +  "USB\0"
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8NetRJ45 = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
>> +    PortConnectorTypeRJ45,        // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
>> +    PortConnectorTypeRJ45,        // ExternalConnectorType;
>> +    PortTypeNetworkPort,          // PortType;
>> +  },
>> +  "RJ1 - BMC RJ45 Port\0" \
>> +  "RJ45 Connector\0"
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8NetOcp = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,       // InternalReferenceDesignator String
>> +    PortTypeOther,                // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,       // ExternalReferenceDesignator String
>> +    PortTypeOther,                // ExternalConnectorType;
>> +    PortTypeNetworkPort,          // PortType;
>> +  },
>> +  "OCP1 - OCP NIC 3.0 Connector\0"  \
>> +  "OCP NIC 3.0\0"
>> +};
>> +
>> +// Type 8 Port Connector Information
>> +STATIC CONST ARM_TYPE8 mArmDefaultType8Uart = {
>> +  {
>> +    {                                             // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_PORT_CONNECTOR_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE8),                // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,        // InternalReferenceDesignator String
>> +    PortTypeOther,                 // InternalConnectorType;
>> +    ADDITIONAL_STR_INDEX_2,        // ExternalReferenceDesignator String
>> +    PortConnectorTypeDB9Female,    // ExternalConnectorType;
>> +    PortTypeSerial16550Compatible, // PortType;
>> +  },
>> +  "UART1 - BMC UART5 Connector\0"  \
>> +  "DB-9 female\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot1 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth16X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    0,
>> +    0,
>> +    0,
>> +  },
>> +  "S0 Riser 1 x32 - Slot 1\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot2 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    4,
>> +    0,
>> +    0,
>> +  },
>> +  "S0 Riser x32 - Slot 2\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk0RiserX32Slot3 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    5,
>> +    0,
>> +    0,
>> +  },
>> +  "S0 Riser x32 - Slot 3\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot1 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    7,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 Riser x24 - Slot 1\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot2 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    8,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 Riser x24 - Slot 2\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX24Slot3 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    9,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 Riser x24 - Slot 3\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1RiserX8Slot1 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth8X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    8,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 Riser x8 - Slot 1\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk0OcpNic = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth16X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    1,
>> +    0,
>> +    0,
>> +  },
>> +  "S0 OCP NIC 3.0\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot1 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth4X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    5,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 NVMe M.2 - Slot 1\0"
>> +};
>> +
>> +// Type 9 System Slots
>> +STATIC ARM_TYPE9 mArmDefaultType9Sk1NvmeM2Slot2 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_SYSTEM_SLOTS, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE9),  // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1,
>> +    SlotTypePciExpressGen3,
>> +    SlotDataBusWidth4X,
>> +    SlotUsageAvailable,
>> +    SlotLengthLong,
>> +    0,
>> +    {0, 0, 1}, // Provides 3.3 Volts
>> +    {1},       // PME
>> +    5,
>> +    0,
>> +    0,
>> +  },
>> +  "S1 NVMe M.2 - Slot 2\0"
>> +};
>> +
>> +// Type 11 OEM Strings
>> +STATIC ARM_TYPE11 mArmDefaultType11 = {
>> +  {
>> +    {                               // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_OEM_STRINGS,  // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE11), // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    ADDITIONAL_STR_INDEX_1
>> +  },
>> +  TYPE11_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 13 BIOS Language Information
>> +STATIC ARM_TYPE13 mArmDefaultType13 = {
>> +  {
>> +    {                                            // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_BIOS_LANGUAGE_INFORMATION, // UINT8 Type
>> +      sizeof (SMBIOS_TABLE_TYPE13),              // UINT8 Length
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    1,
>> +    0,
>> +    { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
>> +    1,
>> +  },
>> +  TYPE13_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 24 Hardware Security
>> +STATIC SMBIOS_TABLE_TYPE24 mArmDefaultType24 = {
>> +  {                                    // SMBIOS_STRUCTURE Hdr
>> +    EFI_SMBIOS_TYPE_HARDWARE_SECURITY, // UINT8 Type
>> +    sizeof (SMBIOS_TABLE_TYPE24),      // UINT8 Length
>> +    SMBIOS_HANDLE_PI_RESERVED,
>> +  },
>> +  0
>> +};
>> +
>> +// Type 32 System Boot Information
>> +STATIC SMBIOS_TABLE_TYPE32 mArmDefaultType32 = {
>> +  {                                          // SMBIOS_STRUCTURE Hdr
>> +    EFI_SMBIOS_TYPE_SYSTEM_BOOT_INFORMATION, // UINT8 Type
>> +    sizeof (SMBIOS_TABLE_TYPE32),            // UINT8 Length
>> +    SMBIOS_HANDLE_PI_RESERVED,
>> +  },
>> +  {0, 0, 0, 0, 0, 0},
>> +  0
>> +};
>> +
>> +// Type 38 IPMI Device Information
>> +STATIC SMBIOS_TABLE_TYPE38 mArmDefaultType38 = {
>> +  {                                          // SMBIOS_STRUCTURE Hdr
>> +    EFI_SMBIOS_TYPE_IPMI_DEVICE_INFORMATION, // UINT8 Type
>> +    sizeof (SMBIOS_TABLE_TYPE38),            // UINT8 Length
>> +    SMBIOS_HANDLE_PI_RESERVED,
>> +  },
>> +  IPMIDeviceInfoInterfaceTypeSSIF,
>> +  0x20,
>> +  0x20,
>> +  0xFF,
>> +  0x20
>> +};
>> +
>> +// Type 41 Onboard Devices Extended Information
>> +STATIC ARM_TYPE41 mArmDefaultType41 = {
>> +  {
>> +    { // SMBIOS_STRUCTURE Hdr
>> +      EFI_SMBIOS_TYPE_ONBOARD_DEVICES_EXTENDED_INFORMATION,
>> +      sizeof (SMBIOS_TABLE_TYPE41),
>> +      SMBIOS_HANDLE_PI_RESERVED,
>> +    },
>> +    1,
>> +    0x83,  // OnBoardDeviceExtendedTypeVideo, Enabled
>> +    1,
>> +    4,
>> +    2,
>> +    0,
>> +  },
>> +  TYPE41_ADDITIONAL_STRINGS
>> +};
>> +
>> +// Type 42 System Boot Information
>> +STATIC SMBIOS_TABLE_TYPE42 mArmDefaultType42 = {
>> +  { // SMBIOS_STRUCTURE Hdr
>> +    EFI_SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE,
>> +    sizeof (SMBIOS_TABLE_TYPE42),
>> +    SMBIOS_HANDLE_PI_RESERVED,
>> +  },
>> +  MCHostInterfaceTypeOemDefined,
>> +  4,
>> +  {0xFF, 0, 0, 0}
>> +};
>> +
>> +STATIC CONST VOID *DefaultCommonTables[] =
>> +{
>> +  &mArmDefaultType0,
>> +  &mArmDefaultType1,
>> +  &mArmDefaultType2,
>> +  &mArmDefaultType8Vga,
>> +  &mArmDefaultType8USBFront,
>> +  &mArmDefaultType8USBRear,
>> +  &mArmDefaultType8NetRJ45,
>> +  &mArmDefaultType8NetOcp,
>> +  &mArmDefaultType8Uart,
>> +  &mArmDefaultType9Sk0RiserX32Slot1,
>> +  &mArmDefaultType9Sk0RiserX32Slot2,
>> +  &mArmDefaultType9Sk0RiserX32Slot3,
>> +  &mArmDefaultType9Sk1RiserX24Slot1,
>> +  &mArmDefaultType9Sk1RiserX24Slot2,
>> +  &mArmDefaultType9Sk1RiserX24Slot3,
>> +  &mArmDefaultType9Sk1RiserX8Slot1,
>> +  &mArmDefaultType9Sk0OcpNic,
>> +  &mArmDefaultType9Sk1NvmeM2Slot1,
>> +  &mArmDefaultType9Sk1NvmeM2Slot2,
>> +  &mArmDefaultType11,
>> +  &mArmDefaultType13,
>> +  &mArmDefaultType24,
>> +  &mArmDefaultType32,
>> +  &mArmDefaultType38,
>> +  &mArmDefaultType41,
>> +  &mArmDefaultType42,
>> +  NULL
>> +};
>> +
>> +typedef struct {
>> +  CHAR8 MonthNameStr[4]; // example "Jan", Compiler build date, month
>> +  CHAR8 DigitStr[3];     // example "01", Smbios date format, month
>> +} MonthStringDig;
>> +
>> +STATIC MonthStringDig MonthMatch[12] = {
>> +  { "Jan", "01" },
>> +  { "Feb", "02" },
>> +  { "Mar", "03" },
>> +  { "Apr", "04" },
>> +  { "May", "05" },
>> +  { "Jun", "06" },
>> +  { "Jul", "07" },
>> +  { "Aug", "08" },
>> +  { "Sep", "09" },
>> +  { "Oct", "10" },
>> +  { "Nov", "11" },
>> +  { "Dec", "12" }
>> +};
>> +
>> +STATIC
>> +VOID
>> +ConstructBuildDate (
>> +  OUT CHAR8 *DateBuf
>> +  )
>> +{
>> +  UINTN i;
>> +
>> +  // GCC __DATE__ format is "Feb  2 1996"
>> +  // If the day of the month is less than 10, it is padded with a space on the left
>> +  CHAR8 *BuildDate = __DATE__;
>> +
>> +  // SMBIOS spec date string: MM/DD/YYYY
>> +  CHAR8 SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE)] = { 0 };
>> +
>> +  SmbiosDateStr[sizeof (RELEASE_DATE_TEMPLATE) - 1] = '\0';
>> +
>> +  SmbiosDateStr[2] = '/';
>> +  SmbiosDateStr[5] = '/';
>> +
>> +  // Month
>> +  for (i = 0; i < sizeof (MonthMatch) / sizeof (MonthMatch[0]); i++) {
>> +    if (AsciiStrnCmp (&BuildDate[0], MonthMatch[i].MonthNameStr, AsciiStrLen (MonthMatch[i].MonthNameStr)) == 0) {
>> +      CopyMem (&SmbiosDateStr[0], MonthMatch[i].DigitStr, AsciiStrLen (MonthMatch[i].DigitStr));
>> +      break;
>> +    }
>> +  }
>> +
>> +  // Day
>> +  CopyMem (&SmbiosDateStr[3], &BuildDate[4], 2);
>> +  if (BuildDate[4] == ' ') {
>> +    // day is less then 10, SAPCE filed by compiler, SMBIOS requires 0
>> +    SmbiosDateStr[3] = '0';
>> +  }
>> +
>> +  // Year
>> +  CopyMem (&SmbiosDateStr[6], &BuildDate[7], 4);
>> +
>> +  CopyMem (DateBuf, SmbiosDateStr, AsciiStrLen (RELEASE_DATE_TEMPLATE));
>> +}
>> +
>> +STATIC
>> +UINT8
>> +GetBiosVerMajor (
>> +  VOID
>> +  )
>> +{
>> +  return (PcdGet8 (PcdSmbiosTables1MajorVersion));
>> +}
>> +
>> +STATIC
>> +UINT8
>> +GetBiosVerMinor (
>> +  VOID
>> +  )
>> +{
>> +  return (PcdGet8 (PcdSmbiosTables1MinorVersion));
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +UpdateSmbiosType0 (
>> +  PLATFORM_INFO_HOB  *PlatformHob
>> +  )
>> +{
>> +  EFI_STATUS                          Status        = EFI_SUCCESS;
>> +  MISC_BIOS_CHARACTERISTICS_EXTENSION *MiscExt      = NULL;
>> +  CHAR8                               *ReleaseDateBuf = NULL;
>> +  CHAR8                               *PcdReleaseDate = NULL;
>> +  CHAR8                               AsciiVersion[32];
>> +  UINTN                               Index;
>> +
>> +  //
>> +  //  Update Type0 information
>> +  //
>> +  ReleaseDateBuf = &mArmDefaultType0.Strings[0]
>> +                   + sizeof (VENDOR_TEMPLATE) - 1
>> +                   + sizeof (BIOS_VERSION_TEMPLATE) - 1;
>> +  PcdReleaseDate = (CHAR8 *)PcdGetPtr (PcdSmbiosTables0BiosReleaseDate);
>> +
>> +  if (AsciiStrnCmp (PcdReleaseDate, RELEASE_DATE_TEMPLATE, AsciiStrLen (RELEASE_DATE_TEMPLATE)) == 0) {
>> +    // If PCD is still template date MM/DD/YYYY, use compiler date
>> +    ConstructBuildDate (ReleaseDateBuf);
>> +  } else {
>> +    // PCD is updated somehow, use PCD date
>> +    CopyMem (ReleaseDateBuf, PcdReleaseDate, AsciiStrLen (PcdReleaseDate));
>> +  }
>> +
>> +  if (PcdGet32 (PcdFdSize) < SIZE_16MB) {
>> +    mArmDefaultType0.Base.BiosSize = (PcdGet32 (PcdFdSize) / SIZE_64KB) - 1;
>> +
>> +    mArmDefaultType0.Base.ExtendedBiosSize.Size = 0;
>> +    mArmDefaultType0.Base.ExtendedBiosSize.Unit = 0;
>> +  } else {
>> +    // TODO: Need to update Extended BIOS ROM Size
>> +    mArmDefaultType0.Base.BiosSize = 0xFF;
>> +
>> +    // As a reminder
>> +    ASSERT (FALSE);
>> +  }
>> +
>> +  // Type0 BIOS Characteristics Extension Byte 1
>> +  MiscExt = (MISC_BIOS_CHARACTERISTICS_EXTENSION *)&(mArmDefaultType0.Base.BIOSCharacteristicsExtensionBytes);
>> +
>> +  MiscExt->BiosReserved.AcpiIsSupported = 1;
>> +
>> +  // Type0 BIOS Characteristics Extension Byte 2
>> +  MiscExt->SystemReserved.BiosBootSpecIsSupported = 1;
>> +  MiscExt->SystemReserved.FunctionKeyNetworkBootIsSupported = 1;
>> +  MiscExt->SystemReserved.UefiSpecificationSupported = 1;
>> +
>> +  // Type0 BIOS Release
>> +  // TODO: to decide another way: If the system does not support the use of this
>> +  // field, the value is 0FFh
>> +  mArmDefaultType0.Base.SystemBiosMajorRelease = GetBiosVerMajor ();
>> +  mArmDefaultType0.Base.SystemBiosMinorRelease = GetBiosVerMinor ();
>> +
>> +  /* Update SMBIOS Type 0 EC Info */
>> +  CopyMem (
>> +    (VOID *)&AsciiVersion,
>> +    (VOID *)&PlatformHob->SmPmProVer,
>> +    sizeof (PlatformHob->SmPmProVer)
>> +    );
>> +  /* The AsciiVersion is formated as "major.minor" */
>> +  for (Index = 0; Index < (UINTN)AsciiStrLen (AsciiVersion); Index++) {
>> +    if (AsciiVersion[Index] == '.') {
>> +      AsciiVersion[Index] = '\0';
>> +      break;
>> +    }
>> +  }
>> +
>> +  mArmDefaultType0.Base.EmbeddedControllerFirmwareMajorRelease =
>> +    (UINT8)AsciiStrDecimalToUintn (AsciiVersion);
>> +  mArmDefaultType0.Base.EmbeddedControllerFirmwareMinorRelease =
>> +    (UINT8)AsciiStrDecimalToUintn (AsciiVersion + Index + 1);
>> +
>> +  return Status;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +InstallType3Structure (
>> +  IN EFI_SMBIOS_PROTOCOL *Smbios
>> +  )
>> +{
>> +  EFI_STATUS          Status = EFI_SUCCESS;
>> +  EFI_SMBIOS_HANDLE   SmbiosHandle;
>> +
>> +  ASSERT (Smbios != NULL);
>> +
>> +  SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*) &mArmDefaultType3)->Handle;
>> +  Status = Smbios->Add (
>> +                     Smbios,
>> +                     NULL,
>> +                     &SmbiosHandle,
>> +                     (EFI_SMBIOS_TABLE_HEADER *)&mArmDefaultType3
>> +                     );
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "adding SMBIOS type 3 failed\n"));
>> +    // stop adding rather than continuing
>> +    return Status;
>> +  }
>> +
>> +  // Save this handle to type 2 table
>> +  mArmDefaultType2.Base.ChassisHandle = SmbiosHandle;
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +   Install a whole table worth of structures
>> +
>> +   @param  Smbios               SMBIOS protocol.
>> +   @param  DefaultTables        A pointer to the default SMBIOS table structure.
>> +**/
>> +EFI_STATUS
>> +InstallStructures (
>> +  IN       EFI_SMBIOS_PROTOCOL *Smbios,
>> +  IN CONST VOID                *DefaultTables[]
>> +  )
>> +{
>> +  EFI_STATUS        Status = EFI_SUCCESS;
>> +  EFI_SMBIOS_HANDLE SmbiosHandle;
>> +  UINTN             TableIndex;
>> +
>> +  ASSERT (Smbios != NULL);
>> +
>> +  for (TableIndex = 0; DefaultTables[TableIndex] != NULL; TableIndex++) {
>> +    SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex])->Handle;
>> +    Status = Smbios->Add (
>> +                       Smbios,
>> +                       NULL,
>> +                       &SmbiosHandle,
>> +                       (EFI_SMBIOS_TABLE_HEADER *)DefaultTables[TableIndex]
>> +                       );
>> +    if (EFI_ERROR (Status)) {
>> +      DEBUG ((DEBUG_ERROR, "%a: adding %d failed\n", __FUNCTION__, TableIndex));
>> +
>> +      // stop adding rather than continuing
>> +      return Status;
>> +    }
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +VOID
>> +UpdateSmbiosInfo (
>> +  VOID
>> +  )
>> +{
>> +  VOID               *Hob;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  /* Get the Platform HOB */
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  ASSERT (Hob != NULL);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  //
>> +  //  Update Type0 information
>> +  //
>> +  UpdateSmbiosType0 (PlatformHob);
>> +
>> +}
>> +
>> +/**
>> +   Install all structures from the DefaultTables structure
>> +
>> +   @param  Smbios               SMBIOS protocol
>> +
>> +**/
>> +EFI_STATUS
>> +InstallAllStructures (
>> +  IN EFI_SMBIOS_PROTOCOL *Smbios
>> +  )
>> +{
>> +  EFI_STATUS Status = EFI_SUCCESS;
>> +
>> +  ASSERT (Smbios != NULL);
>> +
>> +  // Update SMBIOS Tables
>> +  UpdateSmbiosInfo ();
>> +
>> +  // Install Type 3 table
>> +  InstallType3Structure (Smbios);
>> +
>> +  // Install Tables
>> +  Status = InstallStructures (Smbios, DefaultCommonTables);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  return Status;
>> +}
>> +
>> +/**
>> +   Installs SMBIOS information for ARM platforms
>> +
>> +   @param ImageHandle     Module's image handle
>> +   @param SystemTable     Pointer of EFI_SYSTEM_TABLE
>> +
>> +   @retval EFI_SUCCESS    Smbios data successfully installed
>> +   @retval Other          Smbios data was not installed
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +SmbiosPlatformDxeEntry (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS          Status;
>> +  EFI_SMBIOS_PROTOCOL *Smbios;
>> +
>> +  //
>> +  // Find the SMBIOS protocol
>> +  //
>> +  Status = gBS->LocateProtocol (
>> +                  &gEfiSmbiosProtocolGuid,
>> +                  NULL,
>> +                  (VOID **)&Smbios
>> +                  );
>> +
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Status = InstallAllStructures (Smbios);
>> +  DEBUG ((DEBUG_ERROR, "SmbiosPlatform install - %r\n", Status));
>> +
>> +  return Status;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module
  2021-06-07 23:08   ` Leif Lindholm
@ 2021-06-15 16:51     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:51 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/8/21 06:08, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:13 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> Helps to show various system information like CPU info and Board Setting
>> values to UART console during boot process.
>>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc                |   1 +
>>   Platform/Ampere/JadePkg/Jade.fdf                                    |   2 +
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf |  41 ++++
>>   Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c   | 230 ++++++++++++++++++++
>>   4 files changed, 274 insertions(+)
>>
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> index 930bbb5d385b..2d380b21df24 100755
>> --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc
>> @@ -534,6 +534,7 @@ [Components.common]
>>     ArmPlatformPkg/PlatformPei/PlatformPeim.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/ATFHobPei/ATFHobPeim.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/MemoryInitPeim/MemoryInitPeim.inf
>> +  Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/MmCommunicationPei/MmCommunicationPei.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/FlashPei/FlashPei.inf
>>     ArmPkg/Drivers/CpuPei/CpuPei.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index 3d5d857178b3..8c09e2a49089 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -167,6 +167,8 @@ [FV.FVMAIN_COMPACT]
>>     #
>>     # Print platform information before passing control into the Driver Execution Environment (DXE) phase
>>     #
>> +  INF Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>> +
>>     INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
>>   
>>     FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>> new file mode 100755
>> index 000000000000..11414f72f369
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.inf
>> @@ -0,0 +1,41 @@
>> +## @file
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = DebugInfo
>> +  FILE_GUID                      = C0571D26-6176-11E9-8647-D663BD873D93
>> +  MODULE_TYPE                    = PEIM
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = DebugInfoPeiEntryPoint
>> +
>> +[Sources]
>> +  DebugInfoPei.c
>> +
>> +[Packages]
>> +  ArmPkg/ArmPkg.dec
>> +  ArmPlatformPkg/ArmPlatformPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  AmpereCpuLib
>> +  ArmLib
>> +  HobLib
>> +  NVParamLib
>> +  PeimEntryPoint
>> +  PrintLib
>> +  SerialPortLib
>> +
>> +[Guids]
>> +  gPlatformHobGuid
>> +
>> +[Depex]
>> +  TRUE
>> diff --git a/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
>> new file mode 100644
>> index 000000000000..d6775ffa4a79
>> --- /dev/null
>> +++ b/Silicon/Ampere/AmpereAltraPkg/Drivers/DebugInfoPei/DebugInfoPei.c
>> @@ -0,0 +1,230 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <PiPei.h>
>> +#include <Uefi.h>
>> +
>> +#include <Guid/PlatformInfoHobGuid.h>
>> +#include <Library/AmpereCpuLib.h>
>> +#include <Library/ArmLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/HobLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/NVParamLib.h>
>> +#include <Library/PeimEntryPoint.h>
>> +#include <Library/PeiServicesLib.h>
>> +#include <Library/PeiServicesTablePointerLib.h>
>> +#include <Library/PrintLib.h>
>> +#include <Library/SerialPortLib.h>
>> +#include <NVParamDef.h>
>> +#include <Pcie.h>
>> +#include <PlatformInfoHob.h>
>> +
>> +#define MAX_PRINT_LEN       512
>> +
>> +#define GB_SCALE_FACTOR     1073741824
>> +#define MB_SCALE_FACTOR     1048576
>> +#define KB_SCALE_FACTOR     1024
>> +#define MHZ_SCALE_FACTOR    1000000
>> +
>> +STATIC VOID
>> +SerialPrint (
>> +  IN CONST CHAR8 *FormatString,
>> +  ...
>> +  )
>> +{
>> +  CHAR8   Buf[MAX_PRINT_LEN];
>> +  VA_LIST Marker;
>> +  UINTN   NumberOfPrinted;
>> +
>> +  VA_START (Marker, FormatString);
>> +  NumberOfPrinted = AsciiVSPrint (Buf, sizeof (Buf), FormatString, Marker);
>> +  SerialPortWrite ((UINT8 *)Buf, NumberOfPrinted);
>> +  VA_END (Marker);
>> +}
> Why not use BaseDebugLibSerialPort?

Thanks Leif for catching that. Will replace it by DebugPrint in the v3.

Best regards,

Nhi

>
> /
>      Leif
>
>> +
>> +/**
>> +  Print any existence NVRAM.
>> +**/
>> +STATIC VOID
>> +PrintNVRAM (
>> +  VOID
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  NVPARAM    Idx;
>> +  UINT32     Val;
>> +  UINT16     ACLRd = NV_PERM_ALL;
>> +  BOOLEAN    Flag;
>> +
>> +  Flag = FALSE;
>> +  for (Idx = NV_PREBOOT_PARAM_START; Idx <= NV_PREBOOT_PARAM_MAX; Idx += NVPARAM_SIZE) {
>> +    Status = NVParamGet (Idx, ACLRd, &Val);
>> +    if (!EFI_ERROR (Status)) {
>> +      if (!Flag) {
>> +        SerialPrint ("Pre-boot Configuration Setting:\n");
>> +        Flag = TRUE;
>> +      }
>> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
>> +    }
>> +  }
>> +
>> +  Flag = FALSE;
>> +  for (Idx = NV_MANU_PARAM_START; Idx <= NV_MANU_PARAM_MAX; Idx += NVPARAM_SIZE) {
>> +    Status = NVParamGet (Idx, ACLRd, &Val);
>> +    if (!EFI_ERROR (Status)) {
>> +      if (!Flag) {
>> +        SerialPrint ("Manufacturer Configuration Setting:\n");
>> +        Flag = TRUE;
>> +      }
>> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
>> +    }
>> +  }
>> +
>> +  Flag = FALSE;
>> +  for (Idx = NV_USER_PARAM_START; Idx <= NV_USER_PARAM_MAX; Idx += NVPARAM_SIZE) {
>> +    Status = NVParamGet (Idx, ACLRd, &Val);
>> +    if (!EFI_ERROR (Status)) {
>> +      if (!Flag) {
>> +        SerialPrint ("User Configuration Setting:\n");
>> +        Flag = TRUE;
>> +      }
>> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
>> +    }
>> +  }
>> +
>> +  Flag = FALSE;
>> +  for (Idx = NV_BOARD_PARAM_START; Idx <= NV_BOARD_PARAM_MAX; Idx += NVPARAM_SIZE) {
>> +    Status = NVParamGet (Idx, ACLRd, &Val);
>> +    if (!EFI_ERROR (Status)) {
>> +      if (!Flag) {
>> +        SerialPrint ("Board Configuration Setting:\n");
>> +        Flag = TRUE;
>> +      }
>> +      SerialPrint ("    %04X: 0x%X (%d)\n", (UINT32)Idx, Val, Val);
>> +    }
>> +  }
>> +}
>> +
>> +STATIC
>> +CHAR8 *
>> +GetCCIXLinkSpeed (
>> +  IN UINTN Speed
>> +  )
>> +{
>> +  switch (Speed) {
>> +  case 1:
>> +    return "2.5 GT/s";
>> +
>> +  case 2:
>> +    return "5 GT/s";
>> +
>> +  case 3:
>> +    return "8 GT/s";
>> +
>> +  case 4:
>> +  case 6:
>> +    return "16 GT/s";
>> +
>> +  case 0xa:
>> +    return "20 GT/s";
>> +
>> +  case 0xf:
>> +    return "25 GT/s";
>> +  }
>> +
>> +  return "Unknown";
>> +}
>> +
>> +/**
>> +  Print system info
>> +**/
>> +STATIC VOID
>> +PrintSystemInfo (
>> +  VOID
>> +  )
>> +{
>> +  UINTN              Idx;
>> +  VOID               *Hob;
>> +  PLATFORM_INFO_HOB  *PlatformHob;
>> +
>> +  Hob = GetFirstGuidHob (&gPlatformHobGuid);
>> +  if (Hob == NULL) {
>> +    return;
>> +  }
>> +
>> +  PlatformHob = (PLATFORM_INFO_HOB *)GET_GUID_HOB_DATA (Hob);
>> +
>> +  SerialPrint ("SCP FW version    : %a\n", (const CHAR8 *)PlatformHob->SmPmProVer);
>> +  SerialPrint ("SCP FW build date : %a\n", (const CHAR8 *)PlatformHob->SmPmProBuild);
>> +
>> +  SerialPrint ("Failsafe status                 : %d\n", PlatformHob->FailSafeStatus);
>> +  SerialPrint ("Reset status                    : %d\n", PlatformHob->ResetStatus);
>> +  SerialPrint ("CPU info\n");
>> +  SerialPrint ("    CPU ID                      : %X\n", ArmReadMidr ());
>> +  SerialPrint ("    CPU Clock                   : %d MHz\n", PlatformHob->CpuClk / MHZ_SCALE_FACTOR);
>> +  SerialPrint ("    Number of active sockets    : %d\n", GetNumberOfActiveSockets ());
>> +  SerialPrint ("    Number of active cores      : %d\n", GetNumberOfActiveCores ());
>> +  if (IsSlaveSocketActive ()) {
>> +    SerialPrint (
>> +      "    Inter Socket Connection 0   : Width: x%d / Speed %a\n",
>> +      PlatformHob->Link2PWidth[0],
>> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[0])
>> +      );
>> +    SerialPrint (
>> +      "    Inter Socket Connection 1   : Width: x%d / Speed %a\n",
>> +      PlatformHob->Link2PWidth[1],
>> +      GetCCIXLinkSpeed (PlatformHob->Link2PSpeed[1])
>> +      );
>> +  }
>> +  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
>> +    SerialPrint ("    Socket[%d]: Core voltage     : %d\n", Idx, PlatformHob->CoreVoltage[Idx]);
>> +    SerialPrint ("    Socket[%d]: SCU ProductID    : %X\n", Idx, PlatformHob->ScuProductId[Idx]);
>> +    SerialPrint ("    Socket[%d]: Max cores        : %d\n", Idx, PlatformHob->MaxNumOfCore[Idx]);
>> +    SerialPrint ("    Socket[%d]: Warranty         : %d\n", Idx, PlatformHob->Warranty[Idx]);
>> +    SerialPrint ("    Socket[%d]: Subnuma          : %d\n", Idx, PlatformHob->SubNumaMode[Idx]);
>> +    SerialPrint ("    Socket[%d]: RC disable mask  : %X\n", Idx, PlatformHob->RcDisableMask[Idx]);
>> +    SerialPrint ("    Socket[%d]: AVS enabled      : %d\n", Idx, PlatformHob->AvsEnable[Idx]);
>> +    SerialPrint ("    Socket[%d]: AVS voltage      : %d\n", Idx, PlatformHob->AvsVoltageMV[Idx]);
>> +  }
>> +
>> +  SerialPrint ("SOC info\n");
>> +  SerialPrint ("    DDR Frequency               : %d MHz\n", PlatformHob->DramInfo.MaxSpeed);
>> +  for (Idx = 0; Idx < GetNumberOfActiveSockets (); Idx++) {
>> +    SerialPrint ("    Socket[%d]: Soc voltage      : %d\n", Idx, PlatformHob->SocVoltage[Idx]);
>> +    SerialPrint ("    Socket[%d]: DIMM1 voltage    : %d\n", Idx, PlatformHob->Dimm1Voltage[Idx]);
>> +    SerialPrint ("    Socket[%d]: DIMM2 voltage    : %d\n", Idx, PlatformHob->Dimm2Voltage[Idx]);
>> +  }
>> +
>> +  SerialPrint ("    PCP Clock                   : %d MHz\n", PlatformHob->PcpClk / MHZ_SCALE_FACTOR);
>> +  SerialPrint ("    SOC Clock                   : %d MHz\n", PlatformHob->SocClk / MHZ_SCALE_FACTOR);
>> +  SerialPrint ("    SYS Clock                   : %d MHz\n", PlatformHob->SysClk / MHZ_SCALE_FACTOR);
>> +  SerialPrint ("    AHB Clock                   : %d MHz\n", PlatformHob->AhbClk / MHZ_SCALE_FACTOR);
>> +}
>> +
>> +/**
>> +  Entry point function for the PEIM
>> +
>> +  @param FileHandle      Handle of the file being invoked.
>> +  @param PeiServices     Describes the list of possible PEI Services.
>> +
>> +  @return EFI_SUCCESS    If we installed our PPI
>> +
>> +**/
>> +EFI_STATUS
>> +EFIAPI
>> +DebugInfoPeiEntryPoint (
>> +  IN       EFI_PEI_FILE_HANDLE FileHandle,
>> +  IN CONST EFI_PEI_SERVICES    **PeiServices
>> +  )
>> +{
>> +  PrintSystemInfo ();
>> +  PrintNVRAM ();
>> +
>> +  return EFI_SUCCESS;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared
  2021-06-07 23:46   ` Leif Lindholm
@ 2021-06-15 16:52     ` Nhi Pham
  0 siblings, 0 replies; 87+ messages in thread
From: Nhi Pham @ 2021-06-15 16:52 UTC (permalink / raw)
  To: Leif Lindholm
  Cc: devel, Vu Nguyen, Thang Nguyen, Chuong Tran, Phong Vo,
	Michael D Kinney, Ard Biesheuvel, Nate DeSimone

On 6/8/21 06:46, Leif Lindholm wrote:
> On Wed, May 26, 2021 at 17:07:21 +0700, Nhi Pham wrote:
>> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>>
>> Due to recent changes in EDK2, system without a valid boot options list
>> in NVRAM will enter Platform Recovery mode. As ReadyToBoot event is not
>> triggered in this mode, services like ACPI and PCIe won't be able to do
>> some finalization settings and cause OS fails to boot.
>> This change is to prevent the issue by recovery boot options list each
>> time NVRAM is cleared.
> Urgh.
> Ultimately this is a bug in EDK2. And it should be fixed in edk2:
> https://bugzilla.tianocore.org/show_bug.cgi?id=2831
>
> But could you let me know which specific edk2 change broke this for
> you, since it is not obvious to me?

Thanks Leif for the info.

The issue happened since below change  037d86dd7a (20/06/06 14:49) 
ArmPkg/PlatformBootManagerLib: don't connect all devices on each boot 
<Ard Biesheuvel>

 From that commit, System with a NVRAM cleared might try to boot with 
default boot option in Platform Recovery mode. As ReadyToBoot event is 
not triggered in this mode, services like ACPI and PCIe can't complete 
theirs finalizing configurations and cause the OS fails to boot. This 
patch is to prevent the system from entering Platform Recovery mode by 
recovering boot options list each time NVRAM cleared.

Best regards,

Nhi

>
> /
>      Leif
>
>> Cc: Thang Nguyen <thang@os.amperecomputing.com>
>> Cc: Chuong Tran <chuong@os.amperecomputing.com>
>> Cc: Phong Vo <phong@os.amperecomputing.com>
>> Cc: Leif Lindholm <leif@nuviainc.com>
>> Cc: Michael D Kinney <michael.d.kinney@intel.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>>
>> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
>> ---
>>   Platform/Ampere/JadePkg/Jade.dsc                                                  |  5 ++
>>   Platform/Ampere/JadePkg/Jade.fdf                                                  |  5 ++
>>   Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf | 39 +++++++++++++
>>   Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c   | 58 ++++++++++++++++++++
>>   4 files changed, 107 insertions(+)
>>
>> diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
>> index 9d787113e3b5..023f2e898d7f 100755
>> --- a/Platform/Ampere/JadePkg/Jade.dsc
>> +++ b/Platform/Ampere/JadePkg/Jade.dsc
>> @@ -185,3 +185,8 @@ [Components.common]
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/RasConfigDxe/RasConfigDxe.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>>     Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>> +
>> +  #
>> +  # Misc
>> +  #
>> +  Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>> diff --git a/Platform/Ampere/JadePkg/Jade.fdf b/Platform/Ampere/JadePkg/Jade.fdf
>> index b0c2894d00f8..edbead046572 100755
>> --- a/Platform/Ampere/JadePkg/Jade.fdf
>> +++ b/Platform/Ampere/JadePkg/Jade.fdf
>> @@ -361,4 +361,9 @@ [FV.FvMain]
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/WatchdogConfigDxe/WatchdogConfigDxe.inf
>>     INF Silicon/Ampere/AmpereAltraPkg/Drivers/PcieDeviceConfigDxe/PcieDeviceConfigDxe.inf
>>   
>> +  #
>> +  # Misc
>> +  #
>> +  INF Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>> +
>>   !include Platform/Ampere/AmperePlatformPkg/FvRules.fdf.inc
>> diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>> new file mode 100644
>> index 000000000000..624332339beb
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.inf
>> @@ -0,0 +1,39 @@
>> +#
>> +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +#
>> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x0001001B
>> +  BASE_NAME                      = BootOptionsRecoveryDxe
>> +  FILE_GUID                      = FDCDDC91-4F9E-400C-9BB4-1FE4BE9565B3
>> +  MODULE_TYPE                    = DXE_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = BootOptionsRecoveryDxeEntry
>> +
>> +[Sources]
>> +  BootOptionsRecoveryDxe.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec
>> +
>> +[LibraryClasses]
>> +  DebugLib
>> +  PcdLib
>> +  PrintLib
>> +  UefiBootManagerLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +
>> +[Guids]
>> +  gEfiEndOfDxeEventGroupGuid
>> +
>> +[Pcd]
>> +  gAmpereTokenSpaceGuid.PcdNvramErased
>> +
>> +[Depex]
>> +  gEfiFaultTolerantWriteProtocolGuid
>> diff --git a/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
>> new file mode 100644
>> index 000000000000..cd9637ec704e
>> --- /dev/null
>> +++ b/Platform/Ampere/JadePkg/Drivers/BootOptionsRecoveryDxe/BootOptionsRecoveryDxe.c
>> @@ -0,0 +1,58 @@
>> +/** @file
>> +
>> +  Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
>> +
>> +  SPDX-License-Identifier: BSD-2-Clause-Patent
>> +
>> +**/
>> +
>> +#include <Uefi.h>
>> +
>> +#include <Library/DebugLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootManagerLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +
>> +VOID
>> +EFIAPI
>> +RecoveryCallback (
>> +  IN EFI_EVENT Event,
>> +  IN VOID      *Context
>> +  )
>> +{
>> +  DEBUG ((DEBUG_INFO, "%a: Do recover boot options\n", __FUNCTION__));
>> +
>> +  EfiBootManagerConnectAll ();
>> +  EfiBootManagerRefreshAllBootOption ();
>> +
>> +  gBS->CloseEvent (Event);
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +BootOptionsRecoveryDxeEntry (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  EFI_STATUS Status;
>> +  EFI_EVENT  EndOfDxeEvent;
>> +
>> +  DEBUG ((DEBUG_INFO, "%a: NVRAM Clear is %d\n", PcdGetBool (PcdNvramErased), __FUNCTION__));
>> +
>> +  if (PcdGetBool (PcdNvramErased)) {
>> +    DEBUG ((DEBUG_INFO, "%a: Register event to recover boot options\n", __FUNCTION__));
>> +    Status = gBS->CreateEventEx (
>> +                    EVT_NOTIFY_SIGNAL,
>> +                    TPL_CALLBACK,
>> +                    RecoveryCallback,
>> +                    NULL,
>> +                    &gEfiEndOfDxeEventGroupGuid,
>> +                    &EndOfDxeEvent
>> +                    );
>> +    ASSERT_EFI_ERROR (Status);
>> +  }
>> +
>> +  return Status;
>> +}
>> -- 
>> 2.17.1
>>

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

* Re: [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver
  2021-06-15 15:54     ` Nhi Pham
@ 2021-06-16 14:20       ` Ard Biesheuvel
  0 siblings, 0 replies; 87+ messages in thread
From: Ard Biesheuvel @ 2021-06-16 14:20 UTC (permalink / raw)
  To: Nhi Pham
  Cc: Leif Lindholm, edk2-devel-groups-io, Vu Nguyen, Thang Nguyen,
	Chuong Tran, Phong Vo, Michael D Kinney, Ard Biesheuvel,
	Nate DeSimone

On Tue, 15 Jun 2021 at 17:54, Nhi Pham <nhi@os.amperecomputing.com> wrote:
>
> On 6/9/21 12:29, Ard Biesheuvel wrote:
> > On Wed, 26 May 2021 at 12:12, Nhi Pham <nhi@os.amperecomputing.com> wrote:
> >> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
> >>
> >> The roles of this driver:
> >> * Consume PcieCoreLib to initialize all enable PCIe controllers.
> >> * Produce neccessary protocols like RootBridgeIo an ResourceAllocation
> >>    which will be used later by PciBus.
> >>
> >> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> >> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> >> Cc: Phong Vo <phong@os.amperecomputing.com>
> >> Cc: Leif Lindholm <leif@nuviainc.com>
> >> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> >> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> >> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> >>
> >> Signed-off-by: Vu Nguyen <vunguyen@os.amperecomputing.com>
> > Why do you need a re-implementation of PciHostBridgeDxe for any of
> > this? There is very little h/w specific code there, and it is all
> > customizable using PciHostBridgeLib and PciSegmentLib (among others)
> >
> > There are a couple of examples of this in edk2-platforms - please take
> > a look at those, and if that does not give you enough wiggle room,
> > let's see if we can accommodate your needs in PciHostBridgeDxe itself.
> >
> Hi Leif, Ard,
>
> Thanks for your comments. The current implementation which has little
> deltas comparing with the standard one has been well-tested. It's a good
> idea that we need to re-implement it based on Ard's suggestion, but it
> will take time and we need to make sure that it is well-tested
> internally before getting it out.

That is reasonable.

> So, we want to keep this current
> implementation but we will start looking at working the
> re-implementation in the future.
>

I would prefer to wait for this to happen, rather than merge 4000+
lines of code which are almost identical to the original, without any
agreement on when it can be removed again.

Thanks,
Ard.

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

end of thread, other threads:[~2021-06-16 14:20 UTC | newest]

Thread overview: 87+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-05-26 10:06 [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. Jade platform Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 01/32] Ampere: Initial support for Ampere Altra processor and " Nhi Pham
2021-06-04 23:04   ` Leif Lindholm
2021-06-09  4:50     ` Nhi Pham
2021-06-09 12:40       ` Leif Lindholm
2021-06-15 16:46     ` Nhi Pham
2021-05-26 10:06 ` [PATCH 1/1] UsbCdcNetDxe: Remove reading connection status in SNP GetStatus Nhi Pham
2021-05-26 10:23   ` [edk2-devel] " Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 02/32] AmpereAltraPkg: Add MmCommunication modules Nhi Pham
2021-06-04 23:05   ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 03/32] AmperePlatformPkg: Implement FailSafe library Nhi Pham
2021-06-04 23:07   ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 04/32] AmperePlatformPkg: Add FailSafe and WDT support Nhi Pham
2021-06-04 23:12   ` Leif Lindholm
2021-06-15 16:47     ` Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 05/32] AmpereAltraPkg: Add DwI2cLib library Nhi Pham
2021-06-04 23:21   ` Leif Lindholm
2021-06-15 16:47     ` Nhi Pham
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 06/32] AmpereAltraPkg: Add DwGpioLib library Nhi Pham
2021-06-04 23:22   ` Leif Lindholm
2021-05-26 10:06 ` [edk2-platforms][PATCH v2 07/32] JadePkg: Implement RealTimeClockLib for PCF85063 Nhi Pham
2021-06-04 23:26   ` Leif Lindholm
2021-06-15 16:48     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 08/32] AmpereAltraPkg: Add BootProgress support Nhi Pham
2021-06-04 23:27   ` Leif Lindholm
2021-06-15 16:48     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 09/32] AmpereAltraPkg: Support non-volatile variables Nhi Pham
2021-06-04 23:36   ` Leif Lindholm
2021-06-15 16:48     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 10/32] AmpereSiliconPkg: Add PlatformManagerUiLib library instance Nhi Pham
2021-06-04 23:37   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Nhi Pham
2021-06-04 23:44   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Nhi Pham
2021-06-04 23:47   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 13/32] AmpereAltraPkg, JadePkg: Add ACPI support Nhi Pham
2021-06-04 23:50   ` Leif Lindholm
2021-06-15 16:49     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 14/32] AmpereAltraPkg: Add PcieCoreLib library instance Nhi Pham
2021-06-05  0:05   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 15/32] JadePkg: Add PcieBoardLib " Nhi Pham
2021-06-07 22:45   ` Leif Lindholm
2021-06-15 16:50     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 16/32] AmpereAltraPkg: Add PciHostBridge driver Nhi Pham
2021-06-08 22:26   ` Leif Lindholm
2021-06-09  5:29   ` Ard Biesheuvel
2021-06-15 15:54     ` Nhi Pham
2021-06-16 14:20       ` Ard Biesheuvel
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 17/32] JadePkg: Enable PCIe-related libraries and device drivers Nhi Pham
2021-06-07 22:51   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 18/32] JadePkg: Add ASpeed GOP driver Nhi Pham
2021-06-07 22:51   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 19/32] AmpereAltraPkg: Add Random Number Generator Support Nhi Pham
2021-06-08 11:13   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 20/32] JadePkg: Add SMBIOS tables support Nhi Pham
2021-06-07 23:00   ` Leif Lindholm
2021-06-15 16:51     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 21/32] AmpereAltraPkg: Add DebugInfoPei module Nhi Pham
2021-06-07 23:08   ` Leif Lindholm
2021-06-15 16:51     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 22/32] AmpereAltraPkg: Add platform info screen Nhi Pham
2021-06-07 23:10   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 23/32] AmpereAltraPkg: Add configuration screen for memory Nhi Pham
2021-06-07 23:14   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 24/32] AmpereAltraPkg: Add configuration screen for CPU Nhi Pham
2021-06-07 23:15   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 25/32] AmpereAltraPkg: Add configuration screen for ACPI Nhi Pham
2021-06-07 23:20   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 26/32] AmpereAltraPkg: Add configuration screen for RAS Nhi Pham
2021-06-07 23:22   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 27/32] AmpereAltraPkg: Add configuration screen for Watchdog timer Nhi Pham
2021-06-07 23:24   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 28/32] AmpereAltraPkg: Add configuration screen for Pcie Devices Nhi Pham
2021-06-07 23:34   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 29/32] JadePkg: Recover boot options when NVRAM cleared Nhi Pham
2021-06-07 23:46   ` Leif Lindholm
2021-06-15 16:52     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 30/32] AmpereSiliconPkg: Implement PlatformBootManagerLib for LinuxBoot Nhi Pham
2021-06-07 23:50   ` Leif Lindholm
2021-06-09 15:21     ` Nhi Pham
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 31/32] Platform/Ampere: Introduce the LinuxBootPkg Nhi Pham
2021-06-07 23:51   ` Leif Lindholm
2021-05-26 10:07 ` [edk2-platforms][PATCH v2 32/32] AmpereAltraPkg,JadePkg: Support LinuxBoot DSC/FDF build for Jade platform Nhi Pham
2021-06-07 23:58   ` Leif Lindholm
2021-06-09 15:20     ` Nhi Pham
2021-05-27 12:56 ` [edk2-platforms][PATCH v2 00/32] Add new Ampere Mt. " Leif Lindholm
2021-06-04 13:54 ` Leif Lindholm

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