QuarkSocPkg: Add new package for Quark SoC X1000
authorMichael Kinney <michael.d.kinney@intel.com>
Tue, 15 Dec 2015 19:22:23 +0000 (19:22 +0000)
committermdkinney <mdkinney@Edk2>
Tue, 15 Dec 2015 19:22:23 +0000 (19:22 +0000)
Changes for V4
==============
1) Remove Unicode character from C source file
2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode
   from QuarkPlatformPkg commit to QuarkSocPkg commit

Changes for V2
==============
1) Sync with new APIs in SmmCpuFeaturesLib class
2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg
3) Remove PCI serial driver from QuarkSocPkg
4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg
5) Convert all UNI files to utf-8
6) Replace tabs with spaces and remove trailing spaces
7) Add License.txt

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
Acked-by: Jordan Justen <jordan.l.justen@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524

176 files changed:
QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf [new file with mode: 0644]
QuarkSocPkg/Contributions.txt [new file with mode: 0644]
QuarkSocPkg/License.txt [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.uni [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/BaseAccess.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/QNCAccessLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeAccess.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCAccessLib/RuntimeQNCAccessLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/QNCSmmLib/QNCSmmLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/ResetSystemLib/ResetSystemLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmbusLib/SmbusLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Library/SmmCpuFeaturesLib/SmmCpuFeaturesLib.uni [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInit.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/MemoryInitPei.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/core_types.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/gen5_iosf_sb_definitions.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/general_definitions.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/hte.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/io.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/lprint.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/meminit_utils.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/memory_options.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/mrc.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/platform.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/MemoryInit/Pei/prememinit.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/DxeQNCSmbus.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/LegacyRegion.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInit.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCInitDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCRootPorts.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbus.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/QNCInit/Dxe/QNCSmbusExec.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/S3Support/Dxe/QncS3Support.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccess.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmAccessDxe/SmmAccessDriver.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDriver.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Dxe/SmmControlDxe/SmmControlDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmGpi.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmHelpers.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmPeriodicTimer.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmQncn.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSw.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNC/QNCSmmSx.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmm.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmCore.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmDispatcher.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmHelpers.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCSmmRegisters.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/DxeSmm/QncSmmDispatcher/QNCxSmmHelpers.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmAccessPei/SmmAccessPei.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Smm/Pei/SmmControlPei/SmmControlPei.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/Common/SpiCommon.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiRuntime.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/PchSpiSmm.inf [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/RuntimeDxe/PchSpi.h [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.c [new file with mode: 0644]
QuarkSocPkg/QuarkNorthCluster/Spi/Smm/PchSpi.h [new file with mode: 0644]
QuarkSocPkg/QuarkSocPkg.dec [new file with mode: 0644]
QuarkSocPkg/QuarkSocPkg.dsc [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/CEATA.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/I2cRegs.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/Ioh.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/IohAccess.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/IohCommonDefinitions.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/Library/I2cLib.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/Library/IohLib.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/MMC.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/SDCard.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Include/SDHostIo.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohBds.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohData.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInit.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/IohInit/Dxe/IohInitDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/I2cLib/I2cLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/IohLib/CommonHeader.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Library/IohLib/IohLib.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/ComponentName.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDController.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDControllerDxe/SDControllerDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATA.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/CEATABlockIo.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/ComponentName.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDBlockIo.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDevice.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/SDMediaDeviceDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Common/Pei/UsbPei.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/ComponentName.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Descriptor.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/Ohci.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDebug.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciDxe.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciReg.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciSched.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/OhciUrb.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Dxe/UsbHcMem.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/Descriptor.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhcPeim.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciPei.inf [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciReg.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciSched.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/OhciUrb.h [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.c [new file with mode: 0644]
QuarkSocPkg/QuarkSouthCluster/Usb/Ohci/Pei/UsbHcMem.h [new file with mode: 0644]

diff --git a/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf b/QuarkPlatformPkg/Library/PlatformPcieHelperLib/PlatformPcieHelperLib.inf
new file mode 100644 (file)
index 0000000..89747d4
--- /dev/null
@@ -0,0 +1,47 @@
+## @file\r
+# Library producing Pci Express Helper routines.\r
+#\r
+# Copyright (c) 2013 Intel Corporation.\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = PlatformPcieHelperLib\r
+  FILE_GUID                      = C153F460-5D8A-4d44-83BB-A8AF5CEF132C\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = PlatformPcieHelperLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32\r
+#\r
+\r
+[Sources]\r
+  PlatformPcieHelperLib.c\r
+  SocUnit.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  QuarkSocPkg/QuarkSocPkg.dec\r
+  QuarkPlatformPkg/QuarkPlatformPkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  PcdLib\r
+  IoLib\r
+  DebugLib\r
+  TimerLib\r
+  QNCAccessLib\r
+  IntelQNCLib\r
diff --git a/QuarkSocPkg/Contributions.txt b/QuarkSocPkg/Contributions.txt
new file mode 100644 (file)
index 0000000..f87cbd7
--- /dev/null
@@ -0,0 +1,218 @@
+\r
+======================\r
+= Code Contributions =\r
+======================\r
+\r
+To make a contribution to a TianoCore project, follow these steps.\r
+1. Create a change description in the format specified below to\r
+   use in the source control commit log.\r
+2. Your commit message must include your "Signed-off-by" signature,\r
+   and "Contributed-under" message.\r
+3. Your "Contributed-under" message explicitly states that the\r
+   contribution is made under the terms of the specified\r
+   contribution agreement.  Your "Contributed-under" message\r
+   must include the name of contribution agreement and version.\r
+   For example: Contributed-under: TianoCore Contribution Agreement 1.0\r
+   The "TianoCore Contribution Agreement" is included below in\r
+   this document.\r
+4. Submit your code to the TianoCore project using the process\r
+   that the project documents on its web page.  If the process is\r
+   not documented, then submit the code on development email list\r
+   for the project.\r
+5. It is preferred that contributions are submitted using the same\r
+   copyright license as the base project. When that is not possible,\r
+   then contributions using the following licenses can be accepted:\r
+   * BSD (2-clause): http://opensource.org/licenses/BSD-2-Clause\r
+   * BSD (3-clause): http://opensource.org/licenses/BSD-3-Clause\r
+   * MIT: http://opensource.org/licenses/MIT\r
+   * Python-2.0: http://opensource.org/licenses/Python-2.0\r
+   * Zlib: http://opensource.org/licenses/Zlib\r
+\r
+   Contributions of code put into the public domain can also be\r
+   accepted.\r
+\r
+   Contributions using other licenses might be accepted, but further\r
+   review will be required.\r
+\r
+=====================================================\r
+= Change Description / Commit Message / Patch Email =\r
+=====================================================\r
+\r
+Your change description should use the standard format for a\r
+commit message, and must include your "Signed-off-by" signature\r
+and the "Contributed-under" message.\r
+\r
+== Sample Change Description / Commit Message =\r
+\r
+=== Start of sample patch email message ===\r
+\r
+From: Contributor Name <contributor@example.com>\r
+Subject: [PATCH] CodeModule: Brief-single-line-summary\r
+\r
+Full-commit-message\r
+\r
+Contributed-under: TianoCore Contribution Agreement 1.0\r
+Signed-off-by: Contributor Name <contributor@example.com>\r
+---\r
+\r
+An extra message for the patch email which will not be considered part\r
+of the commit message can be added here.\r
+\r
+Patch content inline or attached\r
+\r
+=== End of sample patch email message ===\r
+\r
+=== Notes for sample patch email ===\r
+\r
+* The first line of commit message is taken from the email's subject\r
+  line following [PATCH]. The remaining portion of the commit message\r
+  is the email's content until the '---' line.\r
+* git format-patch is one way to create this format\r
+\r
+=== Definitions for sample patch email ===\r
+\r
+* "CodeModule" is a short idenfier for the affected code.  For\r
+  example MdePkg, or MdeModulePkg UsbBusDxe.\r
+* "Brief-single-line-summary" is a short summary of the change.\r
+* The entire first line should be less than ~70 characters.\r
+* "Full-commit-message" a verbose multiple line comment describing\r
+  the change.  Each line should be less than ~70 characters.\r
+* "Contributed-under" explicitely states that the contribution is\r
+  made under the terms of the contribtion agreement.  This\r
+  agreement is included below in this document.\r
+* "Signed-off-by" is the contributor's signature identifying them\r
+  by their real/legal name and their email address.\r
+\r
+========================================\r
+= TianoCore Contribution Agreement 1.0 =\r
+========================================\r
+\r
+INTEL CORPORATION ("INTEL") MAKES AVAILABLE SOFTWARE, DOCUMENTATION,\r
+INFORMATION AND/OR OTHER MATERIALS FOR USE IN THE TIANOCORE OPEN SOURCE\r
+PROJECT (COLLECTIVELY "CONTENT"). USE OF THE CONTENT IS GOVERNED BY THE\r
+TERMS AND CONDITIONS OF THIS AGREEMENT BETWEEN YOU AND INTEL AND/OR THE\r
+TERMS AND CONDITIONS OF LICENSE AGREEMENTS OR NOTICES INDICATED OR\r
+REFERENCED BELOW. BY USING THE CONTENT, YOU AGREE THAT YOUR USE OF THE\r
+CONTENT IS GOVERNED BY THIS AGREEMENT AND/OR THE TERMS AND CONDITIONS\r
+OF ANY APPLICABLE LICENSE AGREEMENTS OR NOTICES INDICATED OR REFERENCED\r
+BELOW. IF YOU DO NOT AGREE TO THE TERMS AND CONDITIONS OF THIS\r
+AGREEMENT AND THE TERMS AND CONDITIONS OF ANY APPLICABLE LICENSE\r
+AGREEMENTS OR NOTICES INDICATED OR REFERENCED BELOW, THEN YOU MAY NOT\r
+USE THE CONTENT.\r
+\r
+Unless otherwise indicated, all Content made available on the TianoCore\r
+site is provided to you under the terms and conditions of the BSD\r
+License ("BSD"). A copy of the BSD License is available at\r
+http://opensource.org/licenses/bsd-license.php\r
+or when applicable, in the associated License.txt file.\r
+\r
+Certain other content may be made available under other licenses as\r
+indicated in or with such Content. (For example, in a License.txt file.)\r
+\r
+You accept and agree to the following terms and conditions for Your\r
+present and future Contributions submitted to TianoCore site. Except\r
+for the license granted to Intel hereunder, You reserve all right,\r
+title, and interest in and to Your Contributions.\r
+\r
+== SECTION 1: Definitions ==\r
+* "You" or "Contributor" shall mean the copyright owner or legal\r
+  entity authorized by the copyright owner that is making a\r
+  Contribution hereunder. All other entities that control, are\r
+  controlled by, or are under common control with that entity are\r
+  considered to be a single Contributor. For the purposes of this\r
+  definition, "control" means (i) the power, direct or indirect, to\r
+  cause the direction or management of such entity, whether by\r
+  contract or otherwise, or (ii) ownership of fifty percent (50%)\r
+  or more of the outstanding shares, or (iii) beneficial ownership\r
+  of such entity.\r
+* "Contribution" shall mean any original work of authorship,\r
+  including any modifications or additions to an existing work,\r
+  that is intentionally submitted by You to the TinaoCore site for\r
+  inclusion in, or documentation of, any of the Content. For the\r
+  purposes of this definition, "submitted" means any form of\r
+  electronic, verbal, or written communication sent to the\r
+  TianoCore site or its representatives, including but not limited\r
+  to communication on electronic mailing lists, source code\r
+  control systems, and issue tracking systems that are managed by,\r
+  or on behalf of, the TianoCore site for the purpose of\r
+  discussing and improving the Content, but excluding\r
+  communication that is conspicuously marked or otherwise\r
+  designated in writing by You as "Not a Contribution."\r
+\r
+== SECTION 2: License for Contributions ==\r
+* Contributor hereby agrees that redistribution and use of the\r
+  Contribution in source and binary forms, with or without\r
+  modification, are permitted provided that the following\r
+  conditions are met:\r
+** Redistributions of source code must retain the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer.\r
+** Redistributions in binary form must reproduce the Contributor's\r
+   copyright notice, this list of conditions and the following\r
+   disclaimer in the documentation and/or other materials provided\r
+   with the distribution.\r
+* Disclaimer. None of the names of Contributor, Intel, or the names\r
+  of their respective contributors may be used to endorse or\r
+  promote products derived from this software without specific\r
+  prior written permission.\r
+* Contributor grants a license (with the right to sublicense) under\r
+  claims of Contributor's patents that Contributor can license that\r
+  are infringed by the Contribution (as delivered by Contributor) to\r
+  make, use, distribute, sell, offer for sale, and import the\r
+  Contribution and derivative works thereof solely to the minimum\r
+  extent necessary for licensee to exercise the granted copyright\r
+  license; this patent license applies solely to those portions of\r
+  the Contribution that are unmodified. No hardware per se is\r
+  licensed.\r
+* EXCEPT AS EXPRESSLY SET FORTH IN SECTION 3 BELOW, THE\r
+  CONTRIBUTION IS PROVIDED BY THE CONTRIBUTOR "AS IS" AND ANY\r
+  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\r
+  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\r
+  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+  CONTRIBUTOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\r
+  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
+  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\r
+  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THE\r
+  CONTRIBUTION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\r
+  DAMAGE.\r
+\r
+== SECTION 3: Representations ==\r
+* You represent that You are legally entitled to grant the above\r
+  license. If your employer(s) has rights to intellectual property\r
+  that You create that includes Your Contributions, You represent\r
+  that You have received permission to make Contributions on behalf\r
+  of that employer, that Your employer has waived such rights for\r
+  Your Contributions.\r
+* You represent that each of Your Contributions is Your original\r
+  creation (see Section 4 for submissions on behalf of others).\r
+  You represent that Your Contribution submissions include complete\r
+  details of any third-party license or other restriction\r
+  (including, but not limited to, related patents and trademarks)\r
+  of which You are personally aware and which are associated with\r
+  any part of Your Contributions.\r
+\r
+== SECTION 4: Third Party Contributions ==\r
+* Should You wish to submit work that is not Your original creation,\r
+  You may submit it to TianoCore site separately from any\r
+  Contribution, identifying the complete details of its source\r
+  and of any license or other restriction (including, but not\r
+  limited to, related patents, trademarks, and license agreements)\r
+  of which You are personally aware, and conspicuously marking the\r
+  work as "Submitted on behalf of a third-party: [named here]".\r
+\r
+== SECTION 5: Miscellaneous ==\r
+* Applicable Laws. Any claims arising under or relating to this\r
+  Agreement shall be governed by the internal substantive laws of\r
+  the State of Delaware or federal courts located in Delaware,\r
+  without regard to principles of conflict of laws.\r
+* Language. This Agreement is in the English language only, which\r
+  language shall be controlling in all respects, and all versions\r
+  of this Agreement in any other language shall be for accommodation\r
+  only and shall not be binding. All communications and notices made\r
+  or given pursuant to this Agreement, and all documentation and\r
+  support to be provided, unless otherwise noted, shall be in the\r
+  English language.\r
+\r
diff --git a/QuarkSocPkg/License.txt b/QuarkSocPkg/License.txt
new file mode 100644 (file)
index 0000000..be68999
--- /dev/null
@@ -0,0 +1,25 @@
+Copyright (c) 2012, Intel Corporation. All rights reserved.\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions\r
+are met:\r
+\r
+* Redistributions of source code must retain the above copyright\r
+  notice, this list of conditions and the following disclaimer.\r
+* Redistributions in binary form must reproduce the above copyright\r
+  notice, this list of conditions and the following disclaimer in\r
+  the documentation and/or other materials provided with the\r
+  distribution.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r
+COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGE.\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h b/QuarkSocPkg/QuarkNorthCluster/Include/DdrMemoryController.h
new file mode 100644 (file)
index 0000000..de777c5
--- /dev/null
@@ -0,0 +1,257 @@
+/** @file\r
+Memory controller configuration.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#ifndef __DDR_MEMORY_CONTROLLER_H__\r
+#define __DDR_MEMORY_CONTROLLER_H__\r
+\r
+//\r
+// DDR timing data definitions.\r
+// These are used to create bitmaps of valid timing configurations.\r
+//\r
+\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_FREQUENCY_UNKNOWN    0xFF\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_REFRESH_RATE_UNKNOWN 0xFF\r
+\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_20    0x01\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_25    0x00\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_30    0x02\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TCL_ALL   0x03\r
+\r
+\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_02   0x02\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_03   0x01\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_04   0x00\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRCD_ALL  0x03\r
+\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_02    0x02\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_03    0x01\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_04    0x00\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRP_ALL   0x03\r
+\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_05   0x05\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_06   0x04\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_07   0x03\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_08   0x02\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_09   0x01\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_10   0x00\r
+#define DUAL_CHANNEL_DDR_TIMING_DATA_TRAS_ALL  0x07\r
+\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_REGISTERED    0x01\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_UNREGISTERED  0x02\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_BUFFERED      0x04\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_UNBUFFERED    0x08\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_SDR           0x10\r
+#define DUAL_CHANNEL_DDR_DATA_TYPE_DDR           0x20\r
+\r
+\r
+//\r
+// Maximum number of SDRAM channels supported by the memory controller\r
+//\r
+#define MAX_CHANNELS 1\r
+\r
+//\r
+// Maximum number of DIMM sockets supported by the memory controller\r
+//\r
+#define MAX_SOCKETS 1\r
+\r
+//\r
+// Maximum number of sides supported per DIMM\r
+//\r
+#define   MAX_SIDES                         2\r
+\r
+//\r
+// Maximum number of "Socket Sets", where a "Socket Set is a set of matching\r
+// DIMM's from the various channels\r
+//\r
+#define   MAX_SOCKET_SETS                   2\r
+\r
+//\r
+// Maximum number of rows supported by the memory controller\r
+//\r
+#define MAX_ROWS (MAX_SIDES * MAX_SOCKETS)\r
+\r
+//\r
+// Maximum number of memory ranges supported by the memory controller\r
+//\r
+#define MAX_RANGES (MAX_ROWS + 5)\r
+\r
+//\r
+// Maximum Number of Log entries\r
+//\r
+#define   MEMORY_LOG_MAX_INDEX          16\r
+\r
+\r
+typedef struct _MEMORY_LOG_ENTRY {\r
+  EFI_STATUS_CODE_VALUE                     Event;\r
+  EFI_STATUS_CODE_TYPE                      Severity;\r
+  UINT8                                     Data;\r
+} MEMORY_LOG_ENTRY;\r
+\r
+typedef struct _MEMORY_LOG {\r
+  UINT8                                     Index;\r
+  MEMORY_LOG_ENTRY                      Entry[MEMORY_LOG_MAX_INDEX];\r
+} MEMORY_LOG;\r
+\r
+\r
+\r
+//\r
+// Defined ECC types\r
+//\r
+#define DUAL_CHANNEL_DDR_ECC_TYPE_NONE             0x01   // No error checking\r
+#define DUAL_CHANNEL_DDR_ECC_TYPE_EC               0x02   // Error checking only\r
+#define DUAL_CHANNEL_DDR_ECC_TYPE_SECC             0x04   // Software Scrubbing ECC\r
+#define DUAL_CHANNEL_DDR_ECC_TYPE_HECC             0x08   // Hardware Scrubbing ECC\r
+#define DUAL_CHANNEL_DDR_ECC_TYPE_CKECC            0x10   // Chip Kill ECC\r
+\r
+//\r
+// Row configuration status values\r
+//\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_SUCCESS        0x00  // No error\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNKNOWN        0x01  // Pattern mismatch, no memory\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_UNSUPPORTED    0x02  // Memory type not supported\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_ADDRESS_ERROR  0x03  // Row/Col/Bnk mismatch\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_ECC_ERROR      0x04  // Received ECC error\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_NOT_PRESENT    0x05  // Row is not present\r
+#define DUAL_CHANNEL_DDR_ROW_CONFIG_DISABLED       0x06  // Row is disabled\r
+\r
+\r
+//\r
+// Memory range types\r
+//\r
+typedef enum {\r
+  DualChannelDdrMainMemory,\r
+  DualChannelDdrSmramCacheable,\r
+  DualChannelDdrSmramNonCacheable,\r
+  DualChannelDdrGraphicsMemoryCacheable,\r
+  DualChannelDdrGraphicsMemoryNonCacheable,\r
+  DualChannelDdrReservedMemory,\r
+  DualChannelDdrMaxMemoryRangeType\r
+} DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE;\r
+\r
+//\r
+// Memory map range information\r
+//\r
+typedef struct {\r
+  EFI_PHYSICAL_ADDRESS                          PhysicalAddress;\r
+  EFI_PHYSICAL_ADDRESS                          CpuAddress;\r
+  EFI_PHYSICAL_ADDRESS                          RangeLength;\r
+  DUAL_CHANNEL_DDR_MEMORY_RANGE_TYPE                 Type;\r
+} DUAL_CHANNEL_DDR_MEMORY_MAP_RANGE;\r
+typedef struct {\r
+    unsigned    dramType        :1;                 /**< Type: 0 = RESERVED; 1 = DDR2 */\r
+    unsigned    dramWidth       :1;                 /**< Width: 0 = x8; 1 = x16 */\r
+    unsigned    dramDensity     :2;                 /**< Density: 00b = 2Gb; 01b = 1Gb; 10b = 512Mb; 11b = 256Mb */\r
+    unsigned    dramSpeed       :1;                 /**< Speed Grade: 0 = RESERVED; 1 = 800MT/s;*/\r
+    unsigned    dramTimings     :3;                 /**< Timings: 4-4-4, 5-5-5, 6-6-6 */\r
+    unsigned    dramRanks       :1;                 /**< Ranks: 0 = Single Rank; 1 = Dual Rank */\r
+} DramGeometry;                                     /**< DRAM Geometry Descriptor */\r
+\r
+typedef union _RegDRP {\r
+    UINT32    raw;\r
+    struct {\r
+        unsigned rank0Enabled       :1;     /**< Rank 0 Enable */\r
+        unsigned rank0DevWidth      :2;     /**< DRAM Device Width (x8,x16) */\r
+        unsigned rank0DevDensity    :2;     /**< DRAM Device Density (256Mb,512Mb,1Gb,2Gb) */\r
+        unsigned reserved2          :1;\r
+        unsigned rank1Enabled       :1;     /**< Rank 1 Enable */\r
+        unsigned reserved3          :5;\r
+        unsigned dramType           :1;     /**< DRAM Type (0=DDR2) */\r
+        unsigned reserved4          :5;\r
+        unsigned reserved5          :14;\r
+      } field;\r
+} RegDRP;                                   /**< DRAM Rank Population and Interface Register */\r
+\r
+\r
+typedef union {\r
+    UINT32    raw;\r
+    struct {\r
+        unsigned dramFrequency      :3;     /**< DRAM Frequency (000=RESERVED,010=667,011=800) */\r
+        unsigned tRP                :2;     /**< Precharge to Activate Delay (3,4,5,6) */\r
+        unsigned reserved1          :1;\r
+        unsigned tRCD               :2;     /**< Activate to CAS Delay (3,4,5,6) */\r
+        unsigned reserved2          :1;\r
+        unsigned tCL                :2;     /**< CAS Latency (3,4,5,6) */\r
+        unsigned reserved3          :21;\r
+      } field;\r
+} RegDTR0;                                  /**< DRAM Timing Register 0 */\r
+\r
+typedef union {\r
+    UINT32    raw;\r
+    struct {\r
+        unsigned tWRRD_dly          :2;     /**< Additional Write to Read Delay (0,1,2,3) */\r
+        unsigned reserved1          :1;\r
+        unsigned tRDWR_dly          :2;     /**< Additional Read to Write Delay (0,1,2,3) */\r
+        unsigned reserved2          :1;\r
+        unsigned tRDRD_dr_dly       :1;     /**< Additional Read to Read Delay (1,2) */\r
+        unsigned reserved3          :1;\r
+        unsigned tRD_dly            :3;     /**< Additional Read Data Sampling Delay (0-7) */\r
+        unsigned reserved4          :1;\r
+        unsigned tRCVEN_halfclk_dly :4;     /**< Additional RCVEN Half Clock Delay Control */\r
+        unsigned reserved5          :1;\r
+        unsigned readDqDelay        :2;     /**< Read DQ Delay */\r
+        unsigned reserved6          :13;\r
+      } field;\r
+} RegDTR1;                                  /**< DRAM Timing Register 1 */\r
+\r
+typedef union {\r
+    UINT32    raw;\r
+    struct {\r
+        unsigned ckStaticDisable    :1;     /**< CK/CK# Static Disable */\r
+        unsigned reserved1          :3;\r
+        unsigned ckeStaticDisable   :2;     /**< CKE Static Disable */\r
+        unsigned reserved2          :8;\r
+        unsigned refreshPeriod      :2;     /**< Refresh Period (disabled,128clks,3.9us,7.8us) */\r
+        unsigned refreshQueueDepth  :2;     /**< Refresh Queue Depth (1,2,4,8) */\r
+        unsigned reserved5          :13;\r
+        unsigned initComplete       :1;     /**< Initialization Complete */\r
+      } field;\r
+} RegDCO;\r
+\r
+//\r
+// MRC Data Structure\r
+//\r
+typedef struct {\r
+    RegDRP          drp;\r
+    RegDTR0         dtr0;\r
+    RegDTR1         dtr1;\r
+    RegDCO          dco;\r
+    UINT32          reg0104;\r
+    UINT32          reg0120;\r
+    UINT32          reg0121;\r
+    UINT32          reg0123;\r
+    UINT32          reg0111;\r
+    UINT32          reg0130;\r
+    UINT8           refreshPeriod;      /**< Placeholder for the chosen refresh\r
+                                         *   period.  This value will NOT be\r
+                                         *   programmed into DCO until all\r
+                                         *   initialization is done.\r
+                                         */\r
+    UINT8           ddr2Odt;            /**< 0 = Disabled, 1 = 75 ohm, 2 = 150ohm, 3 = 50ohm */\r
+    UINT8           sku;                /**< Detected QuarkNcSocId SKU */\r
+    UINT8           capabilities;       /**< Capabilities Available on this part */\r
+    UINT8           state;              /**< NORMAL_BOOT, S3_RESUME */\r
+    UINT32          memSize;            /**< Memory size */\r
+    UINT16          pmBase;             /**< PM Base */\r
+    UINT16          mrcVersion;         /**< MRC Version */\r
+    UINT32          hecbase;            /**< HECBASE shifted left 16 bits */\r
+    DramGeometry    geometry;          /**< DRAM Geometry */\r
+} MRC_DATA_STRUCTURE;             /**< QuarkNcSocId Memory Parameters for MRC */\r
+\r
+typedef struct _EFI_MEMINIT_CONFIG_DATA {\r
+  MRC_DATA_STRUCTURE                        MrcData;\r
+} EFI_MEMINIT_CONFIG_DATA;\r
+\r
+\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h b/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCBase.h
new file mode 100644 (file)
index 0000000..92ad948
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+Public include file for the QNC Base\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_BASE_H__\r
+#define __INTEL_QNC_BASE_H__\r
+\r
+#include <IntelQNCRegs.h>\r
+#include <IntelQNCConfig.h>\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h b/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCConfig.h
new file mode 100644 (file)
index 0000000..7736012
--- /dev/null
@@ -0,0 +1,106 @@
+/** @file\r
+Some configuration of QNC Package\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_CONFIG_H__\r
+#define __INTEL_QNC_CONFIG_H__\r
+\r
+//\r
+// QNC Fixed configurations.\r
+//\r
+\r
+//\r
+// Memory arbiter fixed config values.\r
+//\r
+#define QNC_FIXED_CONFIG_ASTATUS  ((UINT32) (\\r
+          (ASTATUS_PRI_NORMAL << ASTATUS0_DEFAULT_BP) | \\r
+          (ASTATUS_PRI_NORMAL << ASTATUS1_DEFAULT_BP) | \\r
+          (ASTATUS_PRI_URGENT << ASTATUS0_RASISED_BP) | \\r
+          (ASTATUS_PRI_URGENT << ASTATUS1_RASISED_BP) \\r
+          ))\r
+\r
+//\r
+// Memory Manager fixed config values.\r
+//\r
+#define V_DRAM_NON_HOST_RQ_LIMIT                    2\r
+\r
+//\r
+// RMU Thermal config fixed config values for TS in Vref Mode.\r
+//\r
+#define V_TSCGF1_CONFIG_ISNSCURRENTSEL_VREF_MODE    0x04\r
+#define V_TSCGF2_CONFIG2_ISPARECTRL_VREF_MODE       0x01\r
+#define V_TSCGF1_CONFIG_IBGEN_VREF_MODE             1\r
+#define V_TSCGF2_CONFIG_IDSCONTROL_VREF_MODE        0x011b\r
+#define V_TSCGF2_CONFIG2_ICALCOARSETUNE_VREF_MODE   0x34\r
+\r
+//\r
+// RMU Thermal config fixed config values for TS in Ratiometric mode.\r
+//\r
+#define V_TSCGF1_CONFIG_ISNSCURRENTSEL_RATIO_MODE   0x04\r
+#define V_TSCGF1_CONFIG_ISNSCHOPSEL_RATIO_MODE      0x02\r
+#define V_TSCGF1_CONFIG_ISNSINTERNALVREFEN_RATIO_MODE 1\r
+#define V_TSCGF2_CONFIG_IDSCONTROL_RATIO_MODE       0x011f\r
+#define V_TSCGF2_CONFIG_IDSTIMING_RATIO_MODE        0x0001\r
+#define V_TSCGF2_CONFIG2_ICALCONFIGSEL_RATIO_MODE   0x01\r
+#define V_TSCGF2_CONFIG2_ISPARECTRL_RATIO_MODE      0x00\r
+#define V_TSCGF1_CONFIG_IBGEN_RATIO_MODE            0\r
+#define V_TSCGF1_CONFIG_IBGCHOPEN_RATIO_MODE        0\r
+#define V_TSCGF3_CONFIG_ITSGAMMACOEFF_RATIO_MODE    0xC8\r
+#define V_TSCGF2_CONFIG2_ICALCOARSETUNE_RATIO_MODE  0x17\r
+\r
+//\r
+// iCLK fixed config values.\r
+//\r
+#define V_MUXTOP_FLEX2                              3\r
+#define V_MUXTOP_FLEX1                              1\r
+\r
+//\r
+// PCIe Root Port fixed config values.\r
+//\r
+#define V_PCIE_ROOT_PORT_SBIC_VALUE                 (B_QNC_PCIE_IOSFSBCTL_SBIC_IDLE_NEVER)\r
+\r
+//\r
+// QNC structures for configuration.\r
+//\r
+\r
+typedef union {\r
+  struct {\r
+    UINT32  PortErrorMask               :8;\r
+    UINT32  SlotImplemented             :1;\r
+    UINT32  Reserved1                   :1;\r
+    UINT32  AspmEnable                  :1;\r
+    UINT32  AspmAutoEnable              :1;\r
+    UINT32  AspmL0sEnable               :2;\r
+    UINT32  AspmL1Enable                :1;\r
+    UINT32  PmeInterruptEnable          :1;\r
+    UINT32  PhysicalSlotNumber          :13;\r
+    UINT32  Reserved2                   :1;\r
+    UINT32  PmSciEnable                 :1;\r
+    UINT32  HotplugSciEnable            :1;\r
+  } Bits;\r
+  UINT32 Uint32;\r
+} PCIEXP_ROOT_PORT_CONFIGURATION;\r
+\r
+typedef union {\r
+  UINT32 Uint32;\r
+  struct {\r
+    UINT32 Pcie_0     :1;   // 0: Disabled; 1: Enabled*\r
+    UINT32 Pcie_1     :1;   // 0: Disabled; 1: Enabled*\r
+    UINT32 Smbus      :1;   // 0: Disabled; 1: Enabled*\r
+    UINT32 Rsvd       :29;  // 0\r
+  } Bits;\r
+} QNC_DEVICE_ENABLES;\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h b/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCDxe.h
new file mode 100644 (file)
index 0000000..c266595
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+Public include file for the QNC Dxe\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_DXE_H__\r
+#define __INTEL_QNC_DXE_H__\r
+\r
+#include <IntelQNCRegs.h>\r
+#include <IntelQNCConfig.h>\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h b/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCPeim.h
new file mode 100644 (file)
index 0000000..5b27b1d
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+Public include file for the QNC Pei\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_PEIM_H__\r
+#define __INTEL_QNC_PEIM_H__\r
+\r
+#include <IntelQNCRegs.h>\r
+#include <IntelQNCConfig.h>\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h b/QuarkSocPkg/QuarkNorthCluster/Include/IntelQNCRegs.h
new file mode 100644 (file)
index 0000000..63dd04c
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file\r
+Registers definition for Intel QuarkNcSocId.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_REGS_H__\r
+#define __INTEL_QNC_REGS_H__\r
+\r
+#include <QNCAccess.h>\r
+\r
+//\r
+// PCI HostBridge Segment number\r
+//\r
+#define QNC_PCI_HOST_BRIDGE_SEGMENT_NUMBER    0\r
+\r
+//\r
+// PCI RootBridge resource allocation's attribute\r
+//\r
+#define QNC_PCI_ROOT_BRIDGE_RESOURCE_ALLOCATION_ATTRIBUTE \\r
+  EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM\r
+\r
+//\r
+// PCI HostBridge resource appeture\r
+//\r
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSBASE     0x0\r
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_BUSLIMIT    0xff\r
+#define QNC_PCI_HOST_BRIDGE_RESOURCE_APPETURE_TSEG_SIZE   0x10000000\r
+\r
+//\r
+// PCI RootBridge configure port\r
+//\r
+#define QNC_PCI_ROOT_BRIDGE_CONFIGURATION_ADDRESS_PORT  0xCF8\r
+#define QNC_PCI_ROOT_BRIDGE_CONFIGURATION_DATA_PORT     0xCFC\r
+\r
+//\r
+// PCI Rootbridge's support feature\r
+//\r
+#define QNC_PCI_ROOT_BRIDGE_SUPPORTED                   (EFI_PCI_ATTRIBUTE_IDE_PRIMARY_IO | \\r
+                                                         EFI_PCI_ATTRIBUTE_ISA_IO         | \\r
+                                                         EFI_PCI_ATTRIBUTE_VGA_PALETTE_IO | \\r
+                                                         EFI_PCI_ATTRIBUTE_VGA_MEMORY     | \\r
+                                                         EFI_PCI_ATTRIBUTE_VGA_IO)\r
+\r
+#endif // __INTEL_QNC_REGS_H__\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h b/QuarkSocPkg/QuarkNorthCluster/Include/Library/IntelQNCLib.h
new file mode 100644 (file)
index 0000000..7cda8b1
--- /dev/null
@@ -0,0 +1,290 @@
+/** @file\r
+Library that provides QNC specific library services in PEI phase\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __INTEL_QNC_LIB_H__\r
+#define __INTEL_QNC_LIB_H__\r
+\r
+/**\r
+  This function initializes the QNC register before MRC.\r
+  It sets RCBA, PMBASE, disable Watchdog timer and initialize QNC GPIO.\r
+  If the function cannot complete it'll ASSERT().\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiQNCPreMemInit (\r
+  VOID\r
+  );\r
+\r
+\r
+/**\r
+  Used to check SCH if it's S3 state.  Clear the register state after query.\r
+\r
+  @retval TRUE if it's S3 state.\r
+  @retval FALSE if it's not S3 state.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCCheckS3AndClearState (\r
+   VOID\r
+  );\r
+\r
+/**\r
+  Used to check SCH if system wakes up from power on reset. Clear the register state after query.\r
+\r
+  @retval TRUE  if system wakes up from power on reset\r
+  @retval FALSE if system does not wake up from power on reset\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCCheckPowerOnResetAndClearState (\r
+   VOID\r
+  );\r
+\r
+/**\r
+  This function is used to clear SMI and wake status.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCClearSmiAndWake (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Used to initialize the QNC register after MRC.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiQNCPostMemInit (\r
+  VOID\r
+  );\r
+\r
+/** Send DRAM Ready opcode.\r
+\r
+  @param[in]       OpcodeParam  Parameter to DRAM ready opcode.\r
+\r
+  @retval          VOID\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCSendOpcodeDramReady (\r
+  IN UINT32   OpcodeParam\r
+  );\r
+\r
+/**\r
+\r
+  Relocate RMU Main binary to memory after MRC to improve performance.\r
+\r
+  @param[in]  DestBaseAddress  - Specify the new memory address for the RMU Main binary.\r
+  @param[in]  SrcBaseAddress   - Specify the current memory address for the RMU Main binary.\r
+  @param[in]  Size             - Specify size of the RMU Main binary.\r
+\r
+  @retval     VOID\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RmuMainRelocation (\r
+  IN CONST UINT32   DestBaseAddress,\r
+  IN CONST UINT32   SrcBaseAddress,\r
+  IN CONST UINTN    Size\r
+  );\r
+\r
+/**\r
+  Get the total memory size\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+QNCGetTotalMemorysize (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get the memory range of TSEG.\r
+  The TSEG's memory is below TOLM.\r
+\r
+  @param[out] BaseAddress The base address of TSEG's memory range\r
+  @param[out] MemorySize  The size of TSEG's memory range\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCGetTSEGMemoryRange (\r
+  OUT UINT64  *BaseAddress,\r
+  OUT UINT64  *MemorySize\r
+  );\r
+\r
+/**\r
+  Updates the PAM registers in the MCH for the requested range and mode.\r
+\r
+  @param   Start        The start address of the memory region\r
+  @param   Length       The length, in bytes, of the memory region\r
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable read for legacy memory section.\r
+                        If NULL, then read attribute will not be touched by this call.\r
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable write for legacy memory section.\r
+                        If NULL, then write attribute will not be touched by this call.\r
+  @param   Granularity  A pointer to granularity, in bytes, that the PAM registers support\r
+\r
+  @retval  RETURN_SUCCESS            The PAM registers in the MCH were updated\r
+  @retval  RETURN_INVALID_PARAMETER  The memory range is not valid in legacy region.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+QNCLegacyRegionManipulation (\r
+  IN  UINT32                  Start,\r
+  IN  UINT32                  Length,\r
+  IN  BOOLEAN                 *ReadEnable,\r
+  IN  BOOLEAN                 *WriteEnable,\r
+  OUT UINT32                  *Granularity\r
+  );\r
+\r
+/**\r
+  Do early init of pci express rootports on Soc.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+PciExpressEarlyInit (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Complete initialization of all the pci express rootports on Soc.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PciExpressInit (\r
+  );\r
+\r
+/**\r
+  Determine if QNC is supported.\r
+\r
+  @retval FALSE  QNC is not supported.\r
+  @retval TRUE   QNC is supported.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsQncSupported (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Get the DeviceId of the SoC\r
+\r
+  @retval PCI DeviceId of the SoC\r
+**/\r
+UINT16\r
+EFIAPI\r
+QncGetSocDeviceId (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Enable SMI detection of legacy flash access violations.\r
+**/\r
+VOID\r
+EFIAPI\r
+QncEnableLegacyFlashAccessViolationSmi (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Setup RMU Thermal sensor registers for Vref mode.\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorSetVRefMode (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Setup RMU Thermal sensor registers for Ratiometric mode.\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorSetRatiometricMode (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Setup RMU Thermal sensor trip point values.\r
+\r
+  @param[in]  CatastrophicTripOnDegreesCelsius  - Catastrophic set trip point threshold.\r
+  @param[in]  HotTripOnDegreesCelsius           - Hot set trip point threshold.\r
+  @param[in]  HotTripOffDegreesCelsius          - Hot clear trip point threshold.\r
+\r
+  @retval     VOID\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+QNCThermalSensorSetTripValues (\r
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius,\r
+  IN  CONST UINTN             HotTripOnDegreesCelsius,\r
+  IN  CONST UINTN             HotTripOffDegreesCelsius\r
+  );\r
+\r
+/**\r
+  Enable RMU Thermal sensor with a Catastrophic Trip point.\r
+\r
+  @retval  EFI_SUCCESS            Trip points setup.\r
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+QNCThermalSensorEnableWithCatastrophicTrip (\r
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius\r
+  );\r
+\r
+/**\r
+  Lock all RMU Thermal sensor control & trip point registers.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorLockAllRegisters (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  Set chipset policy for double bit ECC error.\r
+\r
+  @param[in]       PolicyValue  Policy to config on double bit ECC error.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCPolicyDblEccBitErr (\r
+  IN  CONST UINT32                        PolicyValue\r
+  );\r
+\r
+/**\r
+  Determine if running on secure Quark hardware Sku.\r
+\r
+  @retval FALSE  Base Quark Sku or unprovisioned Secure Sku running.\r
+  @retval TRUE   Provisioned SecureSku hardware running.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QncIsSecureProvisionedSku (\r
+  VOID\r
+  );\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h b/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCAccessLib.h
new file mode 100644 (file)
index 0000000..4496167
--- /dev/null
@@ -0,0 +1,167 @@
+/** @file\r
+Library functions for Setting QNC internal network port\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __QNC_ACCESS_LIB_H__\r
+#define __QNC_ACCESS_LIB_H__\r
+\r
+#include <IntelQNCRegs.h>\r
+\r
+#define MESSAGE_READ_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_OPCODE_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define MESSAGE_WRITE_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_OPCODE_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define ALT_MESSAGE_READ_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_ALT_OPCODE_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define ALT_MESSAGE_WRITE_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_ALT_OPCODE_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define MESSAGE_IO_READ_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_OPCODE_IO_READ << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define MESSAGE_IO_WRITE_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_OPCODE_IO_WRITE << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+#define MESSAGE_SHADOW_DW(Port, Reg)  \\r
+        (UINT32)((QUARK_DRAM_BASE_ADDR_READY << QNC_MCR_OP_OFFSET) | ((Port << QNC_MCR_PORT_OFFSET) & 0xFF0000) | ((Reg << QNC_MCR_REG_OFFSET) & 0xFF00) | 0xF0)\r
+\r
+\r
+/**\r
+  Read required data from QNC internal message network\r
+**/\r
+UINT32\r
+EFIAPI\r
+QNCPortRead(\r
+  UINT8 Port,\r
+  UINT32 RegAddress\r
+  );\r
+\r
+/**\r
+  Write prepared data into QNC internal message network.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCPortWrite (\r
+  UINT8 Port,\r
+  UINT32 RegAddress,\r
+  UINT32 WriteValue\r
+  );\r
+\r
+/**\r
+  Read required data from QNC internal message network\r
+**/\r
+UINT32\r
+EFIAPI\r
+QNCAltPortRead(\r
+  UINT8 Port,\r
+  UINT32 RegAddress\r
+  );\r
+\r
+/**\r
+  Write prepared data into QNC internal message network.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCAltPortWrite (\r
+  UINT8 Port,\r
+  UINT32 RegAddress,\r
+  UINT32 WriteValue\r
+  );\r
+\r
+/**\r
+  Read required data from QNC internal message network\r
+**/\r
+UINT32\r
+EFIAPI\r
+QNCPortIORead(\r
+  UINT8 Port,\r
+  UINT32 RegAddress\r
+  );\r
+\r
+/**\r
+  Write prepared data into QNC internal message network.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCPortIOWrite (\r
+  UINT8 Port,\r
+  UINT32 RegAddress,\r
+  UINT32 WriteValue\r
+  );\r
+\r
+/**\r
+  This is for the special consideration for QNC MMIO write, as required by FWG,\r
+  a reading must be performed after MMIO writing to ensure the expected write\r
+  is processed and data is flushed into chipset\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+QNCMmIoWrite (\r
+  UINT32             MmIoAddress,\r
+  QNC_MEM_IO_WIDTH    Width,\r
+  UINT32             DataNumber,\r
+  VOID               *pData\r
+  );\r
+\r
+UINT32\r
+EFIAPI\r
+QncHsmmcRead (\r
+  VOID\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+QncHsmmcWrite (\r
+  UINT32 WriteValue\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+QncImrWrite (\r
+  UINT32 ImrBaseOffset,\r
+  UINT32 ImrLow,\r
+  UINT32 ImrHigh,\r
+  UINT32 ImrReadMask,\r
+  UINT32 ImrWriteMask\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+QncIClkAndThenOr (\r
+  UINT32 RegAddress,\r
+  UINT32 AndValue,\r
+  UINT32 OrValue\r
+  );\r
+\r
+VOID\r
+EFIAPI\r
+QncIClkOr (\r
+  UINT32 RegAddress,\r
+  UINT32 OrValue\r
+  );\r
+\r
+UINTN\r
+EFIAPI\r
+QncGetPciExpressBaseAddress (\r
+  VOID\r
+  );\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h b/QuarkSocPkg/QuarkNorthCluster/Include/Library/QNCSmmLib.h
new file mode 100644 (file)
index 0000000..731aebc
--- /dev/null
@@ -0,0 +1,63 @@
+/** @file\r
+QNC Smm Library Services header file.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __QNC_SMM_LIB_H__\r
+#define __QNC_SMM_LIB_H__\r
+\r
+/**\r
+  This routine is the chipset code that accepts a request to "open" a region of SMRAM.\r
+  The region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.\r
+  The use of "open" means that the memory is visible from all boot-service\r
+  and SMM agents.\r
+\r
+  @retval FALSE  Cannot open a locked SMRAM region\r
+  @retval TRUE   Success to open SMRAM region.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCOpenSmramRegion (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This routine is the chipset code that accepts a request to "close" a region of SMRAM.\r
+  The region could be legacy AB or TSEG near top of physical memory.\r
+  The use of "close" means that the memory is only visible from SMM agents,\r
+  not from BS or RT code.\r
+\r
+  @retval FALSE  Cannot open a locked SMRAM region\r
+  @retval TRUE   Success to open SMRAM region.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCCloseSmramRegion (\r
+  VOID\r
+  );\r
+\r
+/**\r
+  This routine is the chipset code that accepts a request to "lock" SMRAM.\r
+  The region could be legacy AB or TSEG near top of physical memory.\r
+  The use of "lock" means that the memory can no longer be opened\r
+  to BS state.\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCLockSmramRegion (\r
+  VOID\r
+  );\r
+\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h b/QuarkSocPkg/QuarkNorthCluster/Include/Ppi/QNCMemoryInit.h
new file mode 100644 (file)
index 0000000..2d99bff
--- /dev/null
@@ -0,0 +1,42 @@
+/** @file\r
+Memory Initialization PPI used in EFI PEI interface\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __QNC_MEMORY_INIT_H__\r
+#define __QNC_MEMORY_INIT_H__\r
+\r
+#include "mrc.h"\r
+\r
+#define PEI_QNC_MEMORY_INIT_PPI_GUID \\r
+  {0x21ff1fee, 0xd33a, 0x4fce, {0xa6, 0x5e, 0x95, 0x5e, 0xa3, 0xc4, 0x1f, 0x40}}\r
+\r
+\r
+\r
+\r
+//\r
+// PPI Function Declarations\r
+//\r
+typedef\r
+VOID\r
+(EFIAPI *PEI_QNC_MEMORY_INIT) (\r
+  IN OUT    MRCParams_t     *MRCDATA\r
+  );\r
+\r
+typedef struct _PEI_QNC_MEMORY_INIT_PPI {\r
+  PEI_QNC_MEMORY_INIT     MrcStart;\r
+}PEI_QNC_MEMORY_INIT_PPI;\r
+\r
+extern EFI_GUID gQNCMemoryInitPpiGuid;\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h b/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PchInfo.h
new file mode 100644 (file)
index 0000000..26c78ef
--- /dev/null
@@ -0,0 +1,54 @@
+/** @file\r
+This file defines the QNC Info Protocol.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+#ifndef _PCH_INFO_H_\r
+#define _PCH_INFO_H_\r
+\r
+//\r
+// Extern the GUID for protocol users.\r
+//\r
+extern EFI_GUID                       gEfiQncInfoProtocolGuid;\r
+\r
+//\r
+// Forward reference for ANSI C compatibility\r
+//\r
+typedef struct _EFI_QNC_INFO_PROTOCOL EFI_QNC_INFO_PROTOCOL;\r
+\r
+//\r
+// Protocol revision number\r
+// Any backwards compatible changes to this protocol will result in an update in the revision number\r
+// Major changes will require publication of a new protocol\r
+//\r
+// Revision 1:  Original version\r
+// Revision 2:   Add RCVersion item to EFI_QNC_INFO_PROTOCOL\r
+//\r
+#define QNC_INFO_PROTOCOL_REVISION_1  1\r
+#define QNC_INFO_PROTOCOL_REVISION_2  2\r
+\r
+//\r
+// RCVersion[7:0] is the release number.\r
+//\r
+#define QNC_RC_VERSION                0x01020000\r
+\r
+//\r
+// Protocol definition\r
+//\r
+struct _EFI_QNC_INFO_PROTOCOL {\r
+  UINT8   Revision;\r
+  UINT8   BusNumber;\r
+  UINT32  RCVersion;\r
+};\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h b/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/PlatformPolicy.h
new file mode 100644 (file)
index 0000000..e080bcc
--- /dev/null
@@ -0,0 +1,37 @@
+/** @file\r
+Protocol used for Platform Policy definition.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+\r
+#ifndef _PLATFORM_POLICY_H_\r
+#define _PLATFORM_POLICY_H_\r
+\r
+typedef struct _EFI_PLATFORM_POLICY_PROTOCOL EFI_PLATFORM_POLICY_PROTOCOL;\r
+\r
+#define EFI_PLATFORM_POLICY_PROTOCOL_GUID \\r
+  { \\r
+    0x2977064f, 0xab96, 0x4fa9, { 0x85, 0x45, 0xf9, 0xc4, 0x02, 0x51, 0xe0, 0x7f } \\r
+  }\r
+\r
+//\r
+// Protocol to describe various platform information. Add to this as needed.\r
+//\r
+struct _EFI_PLATFORM_POLICY_PROTOCOL {\r
+  UINT8 NumRsvdSmbusAddresses;\r
+  UINT8 *RsvdSmbusAddresses;\r
+};\r
+\r
+extern EFI_GUID gEfiPlatformPolicyProtocolGuid;\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h b/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/QncS3Support.h
new file mode 100644 (file)
index 0000000..9d39932
--- /dev/null
@@ -0,0 +1,90 @@
+/** @file\r
+This file defines the QNC S3 support Protocol.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+#ifndef _QNC_S3_SUPPORT_PROTOCOL_H_\r
+#define _QNC_S3_SUPPORT_PROTOCOL_H_\r
+\r
+//\r
+// Extern the GUID for protocol users.\r
+//\r
+extern EFI_GUID                             gEfiQncS3SupportProtocolGuid;\r
+\r
+//\r
+// Forward reference for ANSI C compatibility\r
+//\r
+typedef struct _EFI_QNC_S3_SUPPORT_PROTOCOL EFI_QNC_S3_SUPPORT_PROTOCOL;\r
+\r
+typedef enum {\r
+  QncS3ItemTypeInitPcieRootPortDownstream,\r
+  QncS3ItemTypeMax\r
+} EFI_QNC_S3_DISPATCH_ITEM_TYPE;\r
+\r
+//\r
+// It's better not to use pointer here because the size of pointer in DXE is 8, but it's 4 in PEI\r
+// plug 4 to ParameterSize in PEIM if you really need it\r
+//\r
+typedef struct {\r
+  UINT32                        Reserved;\r
+} EFI_QNC_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM;\r
+\r
+typedef union {\r
+  EFI_QNC_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM   PcieRootPortData;\r
+} EFI_DISPATCH_CONTEXT_UNION;\r
+\r
+typedef struct {\r
+  EFI_QNC_S3_DISPATCH_ITEM_TYPE Type;\r
+  VOID                          *Parameter;\r
+} EFI_QNC_S3_DISPATCH_ITEM;\r
+\r
+//\r
+// Member functions\r
+//\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_QNC_S3_SUPPORT_SET_S3_DISPATCH_ITEM) (\r
+  IN     EFI_QNC_S3_SUPPORT_PROTOCOL   * This,\r
+  IN     EFI_QNC_S3_DISPATCH_ITEM      * DispatchItem,\r
+  OUT    VOID                         **S3DispatchEntryPoint,\r
+  OUT    VOID                         **Context\r
+  );\r
+\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Set an item to be dispatched at S3 resume time. At the same time, the entry point\r
+  of the QNC S3 support image is returned to be used in subsequent boot script save\r
+  call\r
+\r
+Arguments:\r
+\r
+  This                    - Pointer to the protocol instance.\r
+  DispatchItem            - The item to be dispatched.\r
+  S3DispatchEntryPoint    - The entry point of the QNC S3 support image.\r
+\r
+Returns:\r
+\r
+  EFI_STATUS\r
+\r
+--*/\r
+\r
+//\r
+// Protocol definition\r
+//\r
+struct _EFI_QNC_S3_SUPPORT_PROTOCOL {\r
+  EFI_QNC_S3_SUPPORT_SET_S3_DISPATCH_ITEM SetDispatchItem;\r
+};\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h b/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/SmmIchnDispatch2.h
new file mode 100644 (file)
index 0000000..e3f7291
--- /dev/null
@@ -0,0 +1,121 @@
+/** @file\r
+Intel-only SMM Child Dispatcher Protocol.\r
+\r
+This protocol provides a parent dispatch service for a collection of\r
+chipset-specific SMI source.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+\r
+#ifndef __SMM_ICHN_DISPATCH2_H__\r
+#define __SMM_ICHN_DISPATCH2_H__\r
+\r
+//\r
+// Share some common definitions with Framework SMM\r
+//\r
+#include <Protocol/SmmIchnDispatch.h>\r
+\r
+#include <PiSmm.h>\r
+\r
+//\r
+// Global ID for the ICH SMI Protocol\r
+//\r
+#define EFI_SMM_ICHN_DISPATCH2_PROTOCOL_GUID \\r
+  { \\r
+    0xadf3a128, 0x416d, 0x4060, {0x8d, 0xdf, 0x30, 0xa1, 0xd7, 0xaa, 0xb6, 0x99 } \\r
+  }\r
+\r
+typedef struct _EFI_SMM_ICHN_DISPATCH2_PROTOCOL EFI_SMM_ICHN_DISPATCH2_PROTOCOL;\r
+\r
+typedef struct {\r
+  EFI_SMM_ICHN_SMI_TYPE Type;\r
+} EFI_SMM_ICHN_REGISTER_CONTEXT;\r
+\r
+//\r
+// Member functions\r
+//\r
+/**\r
+  Register a child SMI source dispatch function with a parent SMM driver\r
+\r
+  @param  This                  Protocol instance pointer.\r
+  @param  DispatchFunction      Pointer to dispatch function to be invoked for\r
+                                this SMI source\r
+  @param  RegisterContext       Pointer to the dispatch function's context.\r
+                                The caller fills this context in before calling\r
+                                the register function to indicate to the register\r
+                                function the ICHN SMI source for which the dispatch\r
+                                function should be invoked.\r
+  @param  DispatchHandle        Handle generated by the dispatcher to track the\r
+                                function instance.\r
+\r
+  @retval EFI_SUCCESS           The dispatch function has been successfully\r
+                                registered and the SMI source has been enabled.\r
+  @retval EFI_DEVICE_ERROR      The driver was unable to enable the SMI source.\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough memory (system or SMM) to manage this\r
+                                child.\r
+  @retval EFI_INVALID_PARAMETER RegisterContext is invalid. The ICHN input value\r
+                                is not within valid range.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SMM_ICHN_DISPATCH2_REGISTER) (\r
+  IN CONST EFI_SMM_ICHN_DISPATCH2_PROTOCOL   *This,\r
+  IN       EFI_SMM_HANDLER_ENTRY_POINT2      DispatchFunction,\r
+  IN OUT   EFI_SMM_ICHN_REGISTER_CONTEXT     *RegisterContext,\r
+     OUT   EFI_HANDLE                        *DispatchHandle\r
+  );\r
+\r
+/**\r
+  Unregister a child SMI source dispatch function with a parent SMM driver\r
+\r
+  @param  This                  Protocol instance pointer.\r
+  @param  DispatchHandle        Handle of dispatch function to deregister.\r
+\r
+  @retval EFI_SUCCESS           The dispatch function has been successfully\r
+                                unregistered and the SMI source has been disabled\r
+                                if there are no other registered child dispatch\r
+                                functions for this SMI source.\r
+  @retval EFI_INVALID_PARAMETER Handle is invalid.\r
+  @retval other\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SMM_ICHN_DISPATCH2_UNREGISTER) (\r
+  IN EFI_SMM_ICHN_DISPATCH2_PROTOCOL          *This,\r
+  IN EFI_HANDLE                               DispatchHandle\r
+  );\r
+\r
+//\r
+// Interface structure for the SMM Ich n specific SMI Dispatch Protocol\r
+//\r
+/**\r
+  @par Protocol Description:\r
+  Provides a parent dispatch service for ICH SMI sources.\r
+\r
+  @param Register\r
+  Installs a child service to be dispatched by this protocol.\r
+\r
+  @param UnRegister\r
+  Removes a child service dispatched by this protocol.\r
+\r
+**/\r
+struct _EFI_SMM_ICHN_DISPATCH2_PROTOCOL {\r
+  EFI_SMM_ICHN_DISPATCH2_REGISTER   Register;\r
+  EFI_SMM_ICHN_DISPATCH2_UNREGISTER UnRegister;\r
+};\r
+\r
+extern EFI_GUID gEfiSmmIchnDispatch2ProtocolGuid;\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h b/QuarkSocPkg/QuarkNorthCluster/Include/Protocol/Spi.h
new file mode 100644 (file)
index 0000000..137f9b3
--- /dev/null
@@ -0,0 +1,351 @@
+/** @file\r
+This file defines the EFI SPI Protocol which implements the\r
+Intel(R) ICH SPI Host Controller Compatibility Interface.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+#ifndef _SPI_H_\r
+#define _SPI_H_\r
+\r
+//\r
+// Define the SPI protocol GUID\r
+//\r
+// EDK and EDKII have different GUID formats\r
+//\r
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)\r
+#define EFI_SPI_PROTOCOL_GUID \\r
+  { \\r
+    0x1156efc6, 0xea32, 0x4396, 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \\r
+  }\r
+#define EFI_SMM_SPI_PROTOCOL_GUID \\r
+  { \\r
+    0xD9072C35, 0xEB8F, 0x43ad, 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \\r
+  }\r
+#else\r
+#define EFI_SPI_PROTOCOL_GUID \\r
+  { \\r
+    0x1156efc6, 0xea32, 0x4396, \\r
+    { \\r
+      0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \\r
+    } \\r
+  }\r
+#define EFI_SMM_SPI_PROTOCOL_GUID \\r
+  { \\r
+    0xD9072C35, 0xEB8F, 0x43ad, \\r
+    { \\r
+      0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \\r
+    } \\r
+  }\r
+#endif\r
+//\r
+// Extern the GUID for protocol users.\r
+//\r
+extern EFI_GUID                   gEfiSpiProtocolGuid;\r
+extern EFI_GUID                   gEfiSmmSpiProtocolGuid;\r
+\r
+//\r
+// Forward reference for ANSI C compatibility\r
+//\r
+typedef struct _EFI_SPI_PROTOCOL  EFI_SPI_PROTOCOL;\r
+\r
+//\r
+// SPI protocol data structures and definitions\r
+//\r
+//\r
+// Number of Prefix Opcodes allowed on the SPI interface\r
+//\r
+#define SPI_NUM_PREFIX_OPCODE 2\r
+\r
+//\r
+// Number of Opcodes in the Opcode Menu\r
+//\r
+#define SPI_NUM_OPCODE  8\r
+\r
+#ifdef SERVER_BIOS_FLAG\r
+//\r
+// SPI default opcode slots\r
+//\r
+#define SPI_OPCODE_JEDEC_ID_INDEX        0\r
+#endif // SERVER_BIOS_FLAG\r
+\r
+//\r
+// Opcode Type\r
+//    EnumSpiOpcodeCommand: Command without address\r
+//    EnumSpiOpcodeRead: Read with address\r
+//    EnumSpiOpcodeWrite: Write with address\r
+//\r
+typedef enum {\r
+  EnumSpiOpcodeReadNoAddr,\r
+  EnumSpiOpcodeWriteNoAddr,\r
+  EnumSpiOpcodeRead,\r
+  EnumSpiOpcodeWrite,\r
+  EnumSpiOpcodeMax\r
+} SPI_OPCODE_TYPE;\r
+\r
+typedef enum {\r
+  EnumSpiCycle20MHz,\r
+  EnumSpiCycle33MHz,\r
+  EnumSpiCycle66MHz,  // not supported by PCH\r
+  EnumSpiCycle50MHz,\r
+  EnumSpiCycleMax\r
+} SPI_CYCLE_FREQUENCY;\r
+\r
+typedef enum {\r
+  EnumSpiRegionAll,\r
+  EnumSpiRegionBios,\r
+  EnumSpiRegionMe,\r
+  EnumSpiRegionGbE,\r
+  EnumSpiRegionDescriptor,\r
+  EnumSpiRegionPlatformData,\r
+  EnumSpiRegionMax\r
+} SPI_REGION_TYPE;\r
+\r
+//\r
+// Hardware Sequencing required operations (as listed in CougarPoint EDS Table 5-55: "Hardware\r
+// Sequencing Commands and Opcode Requirements"\r
+//\r
+typedef enum {\r
+  EnumSpiOperationWriteStatus,\r
+  EnumSpiOperationProgramData_1_Byte,\r
+  EnumSpiOperationProgramData_64_Byte,\r
+  EnumSpiOperationReadData,\r
+  EnumSpiOperationWriteDisable,\r
+  EnumSpiOperationReadStatus,\r
+  EnumSpiOperationWriteEnable,\r
+  EnumSpiOperationFastRead,\r
+  EnumSpiOperationEnableWriteStatus,\r
+  EnumSpiOperationErase_256_Byte,\r
+  EnumSpiOperationErase_4K_Byte,\r
+  EnumSpiOperationErase_8K_Byte,\r
+  EnumSpiOperationErase_64K_Byte,\r
+  EnumSpiOperationFullChipErase,\r
+  EnumSpiOperationJedecId,\r
+  EnumSpiOperationDualOutputFastRead,\r
+  EnumSpiOperationDiscoveryParameters,\r
+  EnumSpiOperationOther,\r
+  EnumSpiOperationMax\r
+} SPI_OPERATION;\r
+\r
+//\r
+// Opcode menu entries\r
+//   Type            Operation Type (value to be programmed to the OPTYPE register)\r
+//   Code            The opcode (value to be programmed to the OPMENU register)\r
+//   Frequency       The expected frequency to be used (value to be programmed to the SSFC\r
+//                   Register)\r
+//   Operation       Which Hardware Sequencing required operation this opcode respoinds to.\r
+//                   The required operations are listed in EDS Table 5-55: "Hardware\r
+//                   Sequencing Commands and Opcode Requirements"\r
+//                   If the opcode does not corresponds to any operation listed, use\r
+//                   EnumSpiOperationOther\r
+//\r
+typedef struct _SPI_OPCODE_MENU_ENTRY {\r
+  SPI_OPCODE_TYPE     Type;\r
+  UINT8               Code;\r
+  SPI_CYCLE_FREQUENCY Frequency;\r
+  SPI_OPERATION       Operation;\r
+} SPI_OPCODE_MENU_ENTRY;\r
+\r
+//\r
+// Initialization data table loaded to the SPI host controller\r
+//    VendorId        Vendor ID of the SPI device\r
+//    DeviceId0       Device ID0 of the SPI device\r
+//    DeviceId1       Device ID1 of the SPI device\r
+//    PrefixOpcode    Prefix opcodes which are loaded into the SPI host controller\r
+//    OpcodeMenu      Opcodes which are loaded into the SPI host controller Opcode Menu\r
+//    BiosStartOffset The offset of the start of the BIOS image relative to the flash device.\r
+//                    Please note this is a Flash Linear Address, NOT a memory space address.\r
+//                    This value is platform specific and depends on the system flash map.\r
+//                    This value is only used on non Descriptor mode.\r
+//    BiosSize        The the BIOS Image size in flash. This value is platform specific\r
+//                    and depends on the system flash map. Please note BIOS Image size may\r
+//                    be smaller than BIOS Region size (in Descriptor Mode) or the flash size\r
+//                    (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be\r
+//                    placed at the top end of the BIOS Region (in Descriptor Mode) or the flash\r
+//                    (in Non Descriptor Mode)\r
+//\r
+typedef struct _SPI_INIT_TABLE {\r
+  UINT8                 VendorId;\r
+  UINT8                 DeviceId0;\r
+  UINT8                 DeviceId1;\r
+  UINT8                 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];\r
+  SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE];\r
+  UINTN                 BiosStartOffset;\r
+  UINTN                 BiosSize;\r
+} SPI_INIT_TABLE;\r
+\r
+//\r
+// Public Info struct to show current initialized state of the spi interface.\r
+// OpcodeIndex must be less then SPI_NUM_OPCODE for operation to be supported.\r
+//\r
+typedef struct _SPI_INIT_INFO {\r
+  SPI_INIT_TABLE        *InitTable;\r
+  UINT8                 JedecIdOpcodeIndex;\r
+  UINT8                 OtherOpcodeIndex;\r
+  UINT8                 WriteStatusOpcodeIndex;\r
+  UINT8                 ProgramOpcodeIndex;\r
+  UINT8                 ReadOpcodeIndex;\r
+  UINT8                 EraseOpcodeIndex;\r
+  UINT8                 ReadStatusOpcodeIndex;\r
+  UINT8                 FullChipEraseOpcodeIndex;\r
+} SPI_INIT_INFO;\r
+\r
+//\r
+// Protocol member functions\r
+//\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SPI_INIT) (\r
+  IN EFI_SPI_PROTOCOL     * This,\r
+  IN SPI_INIT_TABLE       * InitTable\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Initializes the host controller to execute SPI commands.\r
+\r
+Arguments:\r
+\r
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.\r
+  InitTable               Pointer to caller-allocated buffer containing the SPI\r
+                          interface initialization table.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Opcode initialization on the SPI host controller completed.\r
+  EFI_ACCESS_DENIED       The SPI configuration interface is locked.\r
+  EFI_OUT_OF_RESOURCES    Not enough resource available to initialize the device.\r
+  EFI_DEVICE_ERROR        Device error, operation failed.\r
+\r
+--*/\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SPI_LOCK) (\r
+  IN EFI_SPI_PROTOCOL     * This\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Lock the SPI Static Configuration Interface.\r
+  Once locked, the interface is no longer open for configuration changes.\r
+  The lock state automatically clears on next system reset.\r
+\r
+Arguments:\r
+\r
+  This      Pointer to the EFI_SPI_PROTOCOL instance.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Lock operation succeed.\r
+  EFI_DEVICE_ERROR        Device error, operation failed.\r
+  EFI_ACCESS_DENIED       The interface has already been locked.\r
+\r
+--*/\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SPI_EXECUTE) (\r
+  IN     EFI_SPI_PROTOCOL   * This,\r
+  IN     UINT8              OpcodeIndex,\r
+  IN     UINT8              PrefixOpcodeIndex,\r
+  IN     BOOLEAN            DataCycle,\r
+  IN     BOOLEAN            Atomic,\r
+  IN     BOOLEAN            ShiftOut,\r
+  IN     UINTN              Address,\r
+  IN     UINT32             DataByteCount,\r
+  IN OUT UINT8              *Buffer,\r
+  IN     SPI_REGION_TYPE    SpiRegionType\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Execute SPI commands from the host controller.\r
+\r
+Arguments:\r
+\r
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.\r
+  OpcodeIndex             Index of the command in the OpCode Menu.\r
+  PrefixOpcodeIndex       Index of the first command to run when in an atomic cycle sequence.\r
+  DataCycle               TRUE if the SPI cycle contains data\r
+  Atomic                  TRUE if the SPI cycle is atomic and interleave cycles are not allowed.\r
+  ShiftOut                If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.\r
+  Address                 In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform\r
+                          Region, this value specifies the offset from the Region Base; for BIOS Region,\r
+                          this value specifies the offset from the start of the BIOS Image. In Non\r
+                          Descriptor Mode, this value specifies the offset from the start of the BIOS Image.\r
+                          Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor\r
+                          Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is\r
+                          supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or\r
+                          the flash (in Non Descriptor Mode)\r
+  DataByteCount           Number of bytes in the data portion of the SPI cycle.\r
+  Buffer                  Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.\r
+  SpiRegionType           SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,\r
+                          EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in\r
+                          Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode\r
+                          and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative\r
+                          to base of the 1st flash device (i.e., it is a Flash Linear Address).\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Command succeed.\r
+  EFI_INVALID_PARAMETER   The parameters specified are not valid.\r
+  EFI_UNSUPPORTED         Command not supported.\r
+  EFI_DEVICE_ERROR        Device error, command aborts abnormally.\r
+\r
+--*/\r
+\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_SPI_INFO) (\r
+  IN EFI_SPI_PROTOCOL     *This,\r
+  OUT SPI_INIT_INFO      **InitInfoPtr\r
+  );\r
+/*++\r
+\r
+Routine Description:\r
+\r
+  Return info about SPI host controller, to help callers usage of Execute\r
+  service.\r
+\r
+  If 0xff is returned as an opcode index in init info struct\r
+  then device does not support the operation.\r
+\r
+Arguments:\r
+\r
+  This                    Pointer to the EFI_SPI_PROTOCOL instance.\r
+  InitInfoPtr             Pointer to init info written to this memory location.\r
+\r
+Returns:\r
+\r
+  EFI_SUCCESS             Information returned.\r
+  EFI_INVALID_PARAMETER   Invalid parameter.\r
+  EFI_NOT_READY           Required resources not setup.\r
+  Others                  Unexpected error happened.\r
+\r
+--*/\r
+\r
+//\r
+// Protocol definition\r
+//\r
+struct _EFI_SPI_PROTOCOL {\r
+  EFI_SPI_INIT    Init;\r
+  EFI_SPI_LOCK    Lock;\r
+  EFI_SPI_EXECUTE Execute;\r
+  EFI_SPI_INFO    Info;\r
+};\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h b/QuarkSocPkg/QuarkNorthCluster/Include/QNCAccess.h
new file mode 100644 (file)
index 0000000..b77d3c9
--- /dev/null
@@ -0,0 +1,183 @@
+/** @file\r
+Macros to simplify and abstract the interface to PCI configuration.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+\r
+**/\r
+\r
+#ifndef _QNC_ACCESS_H_\r
+#define _QNC_ACCESS_H_\r
+\r
+#include "QuarkNcSocId.h"\r
+#include "QNCCommonDefinitions.h"\r
+\r
+#define EFI_LPC_PCI_ADDRESS( Register ) \\r
+  EFI_PCI_ADDRESS(PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, Register)\r
+\r
+//\r
+// QNC Controller PCI access macros\r
+//\r
+#define QNC_RCRB_BASE (QNCMmio32 (PciDeviceMmBase (0, PCI_DEVICE_NUMBER_QNC_LPC, 0), R_QNC_LPC_RCBA) & B_QNC_LPC_RCBA_MASK)\r
+\r
+//\r
+// Device 0x1f, Function 0\r
+//\r
+\r
+#define LpcPciCfg32( Register ) \\r
+  QNCMmPci32(0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )\r
+\r
+#define LpcPciCfg32Or( Register, OrData ) \\r
+  QNCMmPci32Or( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )\r
+\r
+#define LpcPciCfg32And( Register, AndData ) \\r
+  QNCMmPci32And( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )\r
+\r
+#define LpcPciCfg32AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmPci32AndThenOr( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )\r
+\r
+#define LpcPciCfg16( Register ) \\r
+  QNCMmPci16( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )\r
+\r
+#define LpcPciCfg16Or( Register, OrData ) \\r
+  QNCMmPci16Or(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )\r
+\r
+#define LpcPciCfg16And( Register, AndData ) \\r
+  QNCMmPci16And( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )\r
+\r
+#define LpcPciCfg16AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmPci16AndThenOr( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )\r
+\r
+#define LpcPciCfg8( Register ) \\r
+  QNCMmPci8( 0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register )\r
+\r
+#define LpcPciCfg8Or( Register, OrData ) \\r
+  QNCMmPci8Or(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, OrData )\r
+\r
+#define LpcPciCfg8And( Register, AndData ) \\r
+  QNCMmPci8And(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData )\r
+\r
+#define LpcPciCfg8AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmPci8AndThenOr(  0,PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, 0, Register, AndData, OrData )\r
+\r
+//\r
+// Root Complex Register Block\r
+//\r
+\r
+#define MmRcrb32( Register ) \\r
+  QNCMmio32( QNC_RCRB_BASE, Register )\r
+\r
+#define MmRcrb32Or( Register, OrData ) \\r
+  QNCMmio32Or( QNC_RCRB_BASE, Register, OrData )\r
+\r
+#define MmRcrb32And( Register, AndData ) \\r
+  QNCMmio32And( QNC_RCRB_BASE, Register, AndData )\r
+\r
+#define MmRcrb32AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmio32AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )\r
+\r
+#define MmRcrb16( Register ) \\r
+  QNCMmio16( QNC_RCRB_BASE, Register )\r
+\r
+#define MmRcrb16Or( Register, OrData ) \\r
+  QNCMmio16Or( QNC_RCRB_BASE, Register, OrData )\r
+\r
+#define MmRcrb16And( Register, AndData ) \\r
+  QNCMmio16And( QNC_RCRB_BASE, Register, AndData )\r
+\r
+#define MmRcrb16AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmio16AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )\r
+\r
+#define MmRcrb8( Register ) \\r
+  QNCMmio8( QNC_RCRB_BASE, Register )\r
+\r
+#define MmRcrb8Or( Register, OrData ) \\r
+  QNCMmio8Or( QNC_RCRB_BASE, Register, OrData )\r
+\r
+#define MmRcrb8And( Register, AndData ) \\r
+  QNCMmio8And( QNC_RCRB_BASE, Register, AndData )\r
+\r
+#define MmRcrb8AndThenOr( Register, AndData, OrData ) \\r
+  QNCMmio8AndThenOr( QNC_RCRB_BASE, Register, AndData, OrData )\r
+\r
+//\r
+// Memory Controller PCI access macros\r
+//\r
+\r
+//\r
+// Device 0, Function 0\r
+//\r
+\r
+#define McD0PciCfg64(Register)                              QNCMmPci32           (0, MC_BUS, 0, 0, Register)\r
+#define McD0PciCfg64Or(Register, OrData)                    QNCMmPci32Or         (0, MC_BUS, 0, 0, Register, OrData)\r
+#define McD0PciCfg64And(Register, AndData)                  QNCMmPci32And        (0, MC_BUS, 0, 0, Register, AndData)\r
+#define McD0PciCfg64AndThenOr(Register, AndData, OrData)    QNCMmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)\r
+\r
+#define McD0PciCfg32(Register)                              QNCMmPci32           (0, MC_BUS, 0, 0, Register)\r
+#define McD0PciCfg32Or(Register, OrData)                    QNCMmPci32Or         (0, MC_BUS, 0, 0, Register, OrData)\r
+#define McD0PciCfg32And(Register, AndData)                  QNCMmPci32And        (0, MC_BUS, 0, 0, Register, AndData)\r
+#define McD0PciCfg32AndThenOr(Register, AndData, OrData)    QNCMmPci32AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)\r
+\r
+#define McD0PciCfg16(Register)                              QNCMmPci16           (0, MC_BUS, 0, 0, Register)\r
+#define McD0PciCfg16Or(Register, OrData)                    QNCMmPci16Or         (0, MC_BUS, 0, 0, Register, OrData)\r
+#define McD0PciCfg16And(Register, AndData)                  QNCMmPci16And        (0, MC_BUS, 0, 0, Register, AndData)\r
+#define McD0PciCfg16AndThenOr(Register, AndData, OrData)    QNCMmPci16AndThenOr  (0, MC_BUS, 0, 0, Register, AndData, OrData)\r
+\r
+#define McD0PciCfg8(Register)                               QNCMmPci8            (0, MC_BUS, 0, 0, Register)\r
+#define McD0PciCfg8Or(Register, OrData)                     QNCMmPci8Or          (0, MC_BUS, 0, 0, Register, OrData)\r
+#define McD0PciCfg8And(Register, AndData)                   QNCMmPci8And         (0, MC_BUS, 0, 0, Register, AndData)\r
+#define McD0PciCfg8AndThenOr( Register, AndData, OrData )   QNCMmPci8AndThenOr   (0, MC_BUS, 0, 0, Register, AndData, OrData)\r
+\r
+\r
+//\r
+// Memory Controller Hub Memory Mapped IO register access ???\r
+//\r
+#define MCH_REGION_BASE                     (McD0PciCfg64 (MC_MCHBAR_OFFSET) & ~BIT0)\r
+#define McMmioAddress(Register)             ((UINTN) MCH_REGION_BASE + (UINTN) (Register))\r
+\r
+#define McMmio32Ptr(Register)               ((volatile UINT32*) McMmioAddress (Register))\r
+#define McMmio64Ptr(Register)               ((volatile UINT64*) McMmioAddress (Register))\r
+\r
+#define McMmio64(Register)                            *McMmio64Ptr( Register )\r
+#define McMmio64Or(Register, OrData)                  (McMmio64 (Register) |= (UINT64)(OrData))\r
+#define McMmio64And(Register, AndData)                (McMmio64 (Register) &= (UINT64)(AndData))\r
+#define McMmio64AndThenOr(Register, AndData, OrData)  (McMmio64 ( Register ) = (McMmio64( Register ) & (UINT64)(AndData)) | (UINT64)(OrData))\r
+\r
+#define McMmio32(Register)                            *McMmio32Ptr (Register)\r
+#define McMmio32Or(Register, OrData)                  (McMmio32 (Register) |= (UINT32)(OrData))\r
+#define McMmio32And(Register, AndData)                (McMmio32 (Register) &= (UINT32)(AndData))\r
+#define McMmio32AndThenOr(Register, AndData, OrData)  (McMmio32 (Register) = (McMmio32 (Register) & (UINT32) (AndData)) | (UINT32) (OrData))\r
+\r
+#define McMmio16Ptr(Register)                         ((volatile UINT16*) McMmioAddress (Register))\r
+#define McMmio16(Register)                            *McMmio16Ptr (Register)\r
+#define McMmio16Or(Register, OrData)                  (McMmio16 (Register) |= (UINT16) (OrData))\r
+#define McMmio16And(Register, AndData)                (McMmio16 (Register) &= (UINT16) (AndData))\r
+#define McMmio16AndThenOr(Register, AndData, OrData)  (McMmio16 (Register) = (McMmio16 (Register) & (UINT16) (AndData)) | (UINT16) (OrData))\r
+\r
+#define McMmio8Ptr(Register)                          ((volatile UINT8 *)McMmioAddress (Register))\r
+#define McMmio8(Register)                             *McMmio8Ptr (Register)\r
+#define McMmio8Or(Register, OrData)                   (McMmio8 (Register) |= (UINT8) (OrData))\r
+#define McMmio8And(Register, AndData)                 (McMmio8 (Register) &= (UINT8) (AndData))\r
+#define McMmio8AndThenOr(Register, AndData, OrData)   (McMmio8 (Register) = (McMmio8 (Register) & (UINT8) (AndData)) | (UINT8) (OrData))\r
+\r
+//\r
+// QNC memory mapped related data structure deifinition\r
+//\r
+typedef enum {\r
+  QNCMmioWidthUint8  = 0,\r
+  QNCMmioWidthUint16 = 1,\r
+  QNCMmioWidthUint32 = 2,\r
+  QNCMmioWidthUint64 = 3,\r
+  QNCMmioWidthMaximum\r
+} QNC_MEM_IO_WIDTH;\r
+\r
+#endif\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h b/QuarkSocPkg/QuarkNorthCluster/Include/QNCCommonDefinitions.h
new file mode 100644 (file)
index 0000000..88d3d88
--- /dev/null
@@ -0,0 +1,356 @@
+/** @file\r
+This header file provides common definitions just for MCH using to avoid including extra module's file.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _QNC_COMMON_DEFINITIONS_H_\r
+#define _QNC_COMMON_DEFINITIONS_H_\r
+\r
+//\r
+// PCI CONFIGURATION MAP REGISTER OFFSETS\r
+//\r
+#ifndef PCI_VID\r
+#define PCI_VID             0x0000        // Vendor ID Register\r
+#define PCI_DID             0x0002        // Device ID Register\r
+#define PCI_CMD             0x0004        // PCI Command Register\r
+#define PCI_STS             0x0006        // PCI Status Register\r
+#define PCI_RID             0x0008        // Revision ID Register\r
+#define PCI_IFT             0x0009        // Interface Type\r
+#define PCI_SCC             0x000A        // Sub Class Code Register\r
+#define PCI_BCC             0x000B        // Base Class Code Register\r
+#define PCI_CLS             0x000C        // Cache Line Size\r
+#define PCI_PMLT            0x000D        // Primary Master Latency Timer\r
+#define PCI_HDR             0x000E        // Header Type Register\r
+#define PCI_BIST            0x000F        // Built in Self Test Register\r
+#define PCI_BAR0            0x0010        // Base Address Register 0\r
+#define PCI_BAR1            0x0014        // Base Address Register 1\r
+#define PCI_BAR2            0x0018        // Base Address Register 2\r
+#define PCI_PBUS            0x0018        // Primary Bus Number Register\r
+#define PCI_SBUS            0x0019        // Secondary Bus Number Register\r
+#define PCI_SUBUS           0x001A        // Subordinate Bus Number Register\r
+#define PCI_SMLT            0x001B        // Secondary Master Latency Timer\r
+#define PCI_BAR3            0x001C        // Base Address Register 3\r
+#define PCI_IOBASE          0x001C        // I/O base Register\r
+#define PCI_IOLIMIT         0x001D        // I/O Limit Register\r
+#define PCI_SECSTATUS       0x001E        // Secondary Status Register\r
+#define PCI_BAR4            0x0020        // Base Address Register 4\r
+#define PCI_MEMBASE         0x0020        // Memory Base Register\r
+#define PCI_MEMLIMIT        0x0022        // Memory Limit Register\r
+#define PCI_BAR5            0x0024        // Base Address Register 5\r
+#define PCI_PRE_MEMBASE     0x0024        // Prefetchable memory Base register\r
+#define PCI_PRE_MEMLIMIT    0x0026        // Prefetchable memory Limit register\r
+#define PCI_PRE_MEMBASE_U   0x0028        // Prefetchable memory base upper 32 bits\r
+#define PCI_PRE_MEMLIMIT_U  0x002C        // Prefetchable memory limit upper 32 bits\r
+#define PCI_SVID            0x002C        // Subsystem Vendor ID\r
+#define PCI_SID             0x002E        // Subsystem ID\r
+#define PCI_IOBASE_U        0x0030        // I/O base Upper Register\r
+#define PCI_IOLIMIT_U       0x0032        // I/O Limit Upper Register\r
+#define PCI_CAPP            0x0034        // Capabilities Pointer\r
+#define PCI_EROM            0x0038        // Expansion ROM Base Address\r
+#define PCI_INTLINE         0x003C        // Interrupt Line Register\r
+#define PCI_INTPIN          0x003D        // Interrupt Pin Register\r
+#define PCI_MAXGNT          0x003E        // Max Grant Register\r
+#define PCI_BRIDGE_CNTL     0x003E        // Bridge Control Register\r
+#define PCI_MAXLAT          0x003F        // Max Latency Register\r
+#endif\r
+//\r
+// Bit Difinitions\r
+//\r
+#ifndef BIT0\r
+#define BIT0                     0x0001\r
+#define BIT1                     0x0002\r
+#define BIT2                     0x0004\r
+#define BIT3                     0x0008\r
+#define BIT4                     0x0010\r
+#define BIT5                     0x0020\r
+#define BIT6                     0x0040\r
+#define BIT7                     0x0080\r
+#define BIT8                     0x0100\r
+#define BIT9                     0x0200\r
+#define BIT10                    0x0400\r
+#define BIT11                    0x0800\r
+#define BIT12                    0x1000\r
+#define BIT13                    0x2000\r
+#define BIT14                    0x4000\r
+#define BIT15                    0x8000\r
+#define BIT16                0x00010000\r
+#define BIT17                0x00020000\r
+#define BIT18                0x00040000\r
+#define BIT19                0x00080000\r
+#define BIT20                0x00100000\r
+#define BIT21                0x00200000\r
+#define BIT22                0x00400000\r
+#define BIT23                0x00800000\r
+#define BIT24                0x01000000\r
+#define BIT25                0x02000000\r
+#define BIT26                0x04000000\r
+#define BIT27                0x08000000\r
+#define BIT28                0x10000000\r
+#define BIT29                0x20000000\r
+#define BIT30                0x40000000\r
+#define BIT31                0x80000000\r
+#endif\r
+\r
+\r
+//\r
+//  Common Memory mapped Io access macros ------------------------------------------\r
+//\r
+#define QNCMmioAddress( BaseAddr, Register ) \\r
+    ( (UINTN)BaseAddr + \\r
+      (UINTN)(Register) \\r
+    )\r
+\r
+//\r
+// UINT64\r
+//\r
+#define QNCMmio64Ptr( BaseAddr, Register ) \\r
+    ( (volatile UINT64 *)QNCMmioAddress( BaseAddr, Register ) )\r
+\r
+#define QNCMmio64( BaseAddr, Register ) \\r
+    *QNCMmio64Ptr( BaseAddr, Register )\r
+\r
+#define QNCMmio64Or( BaseAddr, Register, OrData ) \\r
+    QNCMmio64( BaseAddr, Register ) = \\r
+      (UINT64) ( \\r
+        QNCMmio64( BaseAddr, Register ) | \\r
+        (UINT64)(OrData) \\r
+      )\r
+\r
+#define QNCMmio64And( BaseAddr, Register, AndData ) \\r
+    QNCMmio64( BaseAddr, Register ) = \\r
+      (UINT64) ( \\r
+        QNCMmio64( BaseAddr, Register ) & \\r
+        (UINT64)(AndData) \\r
+      )\r
+\r
+#define QNCMmio64AndThenOr( BaseAddr, Register, AndData, OrData ) \\r
+    QNCMmio64( BaseAddr, Register ) = \\r
+      (UINT64) ( \\r
+        ( QNCMmio64( BaseAddr, Register ) & \\r
+            (UINT64)(AndData) \\r
+        ) | \\r
+        (UINT64)(OrData) \\r
+      )\r
+\r
+//\r
+// UINT32\r
+//\r
+#define QNCMmio32Ptr( BaseAddr, Register ) \\r
+    ( (volatile UINT32 *)QNCMmioAddress( BaseAddr, Register ) )\r
+\r
+#define QNCMmio32( BaseAddr, Register ) \\r
+    *QNCMmio32Ptr( BaseAddr, Register )\r
+\r
+#define QNCMmio32Or( BaseAddr, Register, OrData ) \\r
+    QNCMmio32( BaseAddr, Register ) = \\r
+      (UINT32) ( \\r
+        QNCMmio32( BaseAddr, Register ) | \\r
+        (UINT32)(OrData) \\r
+      )\r
+\r
+#define QNCMmio32And( BaseAddr, Register, AndData ) \\r
+    QNCMmio32( BaseAddr, Register ) = \\r
+      (UINT32) ( \\r
+        QNCMmio32( BaseAddr, Register ) & \\r
+        (UINT32)(AndData) \\r
+      )\r
+\r
+#define QNCMmio32AndThenOr( BaseAddr, Register, AndData, OrData ) \\r
+    QNCMmio32( BaseAddr, Register ) = \\r
+      (UINT32) ( \\r
+        ( QNCMmio32( BaseAddr, Register ) & \\r
+            (UINT32)(AndData) \\r
+        ) | \\r
+        (UINT32)(OrData) \\r
+      )\r
+//\r
+// UINT16\r
+//\r
+\r
+#define QNCMmio16Ptr( BaseAddr, Register ) \\r
+    ( (volatile UINT16 *)QNCMmioAddress( BaseAddr, Register ) )\r
+\r
+#define QNCMmio16( BaseAddr, Register ) \\r
+    *QNCMmio16Ptr( BaseAddr, Register )\r
+\r
+#define QNCMmio16Or( BaseAddr, Register, OrData ) \\r
+    QNCMmio16( BaseAddr, Register ) = \\r
+      (UINT16) ( \\r
+        QNCMmio16( BaseAddr, Register ) | \\r
+        (UINT16)(OrData) \\r
+      )\r
+\r
+#define QNCMmio16And( BaseAddr, Register, AndData ) \\r
+    QNCMmio16( BaseAddr, Register ) = \\r
+      (UINT16) ( \\r
+        QNCMmio16( BaseAddr, Register ) & \\r
+        (UINT16)(AndData) \\r
+      )\r
+\r
+#define QNCMmio16AndThenOr( BaseAddr, Register, AndData, OrData ) \\r
+    QNCMmio16( BaseAddr, Register ) = \\r
+      (UINT16) ( \\r
+        ( QNCMmio16( BaseAddr, Register ) & \\r
+            (UINT16)(AndData) \\r
+        ) | \\r
+        (UINT16)(OrData) \\r
+      )\r
+//\r
+// UINT8\r
+//\r
+#define QNCMmio8Ptr( BaseAddr, Register ) \\r
+    ( (volatile UINT8 *)QNCMmioAddress( BaseAddr, Register ) )\r
+\r
+#define QNCMmio8( BaseAddr, Register ) \\r
+    *QNCMmio8Ptr( BaseAddr, Register )\r
+\r
+#define QNCMmio8Or( BaseAddr, Register, OrData ) \\r
+    QNCMmio8( BaseAddr, Register ) = \\r
+      (UINT8) ( \\r
+        QNCMmio8( BaseAddr, Register ) | \\r
+        (UINT8)(OrData) \\r
+      )\r
+\r
+#define QNCMmio8And( BaseAddr, Register, AndData ) \\r
+    QNCMmio8( BaseAddr, Register ) = \\r
+      (UINT8) ( \\r
+        QNCMmio8( BaseAddr, Register ) & \\r
+        (UINT8)(AndData) \\r
+      )\r
+\r
+#define QNCMmio8AndThenOr( BaseAddr, Register, AndData, OrData ) \\r
+    QNCMmio8( BaseAddr, Register ) = \\r
+      (UINT8) ( \\r
+        ( QNCMmio8( BaseAddr, Register ) & \\r
+            (UINT8)(AndData) \\r
+          ) | \\r
+        (UINT8)(OrData) \\r
+      )\r
+\r
+//\r
+//  Common Memory mapped Pci access macros ------------------------------------------\r
+//\r
+\r
+#define QNCMmPciAddress( Segment, Bus, Device, Function, Register ) \\r
+  ( (UINTN) QncGetPciExpressBaseAddress() + \\r
+    (UINTN)(Bus << 20) + \\r
+    (UINTN)(Device << 15) + \\r
+    (UINTN)(Function << 12) + \\r
+    (UINTN)(Register) \\r
+  )\r
+\r
+//\r
+// Macro to calculate the Pci device's base memory mapped address\r
+//\r
+#define PciDeviceMmBase( Bus, Device, Function) \\r
+    ( (UINTN) QncGetPciExpressBaseAddress () + \\r
+      (UINTN)(Bus << 20) + \\r
+      (UINTN)(Device << 15) + \\r
+      (UINTN)(Function << 12) \\r
+    )\r
+\r
+//\r
+// UINT32\r
+//\r
+#define QNCMmPci32Ptr( Segment, Bus, Device, Function, Register ) \\r
+  ( (volatile UINT32 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )\r
+\r
+#define QNCMmPci32( Segment, Bus, Device, Function, Register ) \\r
+  *QNCMmPci32Ptr( Segment, Bus, Device, Function, Register )\r
+\r
+#define QNCMmPci32Or( Segment, Bus, Device, Function, Register, OrData ) \\r
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT32) ( \\r
+      QNCMmPci32( Segment, Bus, Device, Function, Register ) | \\r
+      (UINT32)(OrData) \\r
+    )\r
+\r
+#define QNCMmPci32And( Segment, Bus, Device, Function, Register, AndData ) \\r
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT32) ( \\r
+      QNCMmPci32( Segment, Bus, Device, Function, Register ) & \\r
+      (UINT32)(AndData) \\r
+    )\r
+\r
+#define QNCMmPci32AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \\r
+  QNCMmPci32( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT32) ( \\r
+      ( QNCMmPci32( Segment, Bus, Device, Function, Register ) & \\r
+          (UINT32)(AndData) \\r
+      ) | \\r
+      (UINT32)(OrData) \\r
+    )\r
+//\r
+// UINT16\r
+//\r
+#define QNCMmPci16Ptr( Segment, Bus, Device, Function, Register ) \\r
+  ( (volatile UINT16 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )\r
+\r
+#define QNCMmPci16( Segment, Bus, Device, Function, Register ) \\r
+  *QNCMmPci16Ptr( Segment, Bus, Device, Function, Register )\r
+\r
+#define QNCMmPci16Or( Segment, Bus, Device, Function, Register, OrData ) \\r
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT16) ( \\r
+      QNCMmPci16( Segment, Bus, Device, Function, Register ) | \\r
+      (UINT16)(OrData) \\r
+    )\r
+\r
+#define QNCMmPci16And( Segment, Bus, Device, Function, Register, AndData ) \\r
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT16) ( \\r
+      QNCMmPci16( Segment, Bus, Device, Function, Register ) & \\r
+      (UINT16)(AndData) \\r
+    )\r
+\r
+#define QNCMmPci16AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \\r
+  QNCMmPci16( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT16) ( \\r
+      ( QNCMmPci16( Segment, Bus, Device, Function, Register ) & \\r
+          (UINT16)(AndData) \\r
+      ) | \\r
+      (UINT16)(OrData) \\r
+    )\r
+//\r
+// UINT8\r
+//\r
+#define QNCMmPci8Ptr( Segment, Bus, Device, Function, Register ) \\r
+  ( (volatile UINT8 *)QNCMmPciAddress( Segment, Bus, Device, Function, Register ) )\r
+\r
+#define QNCMmPci8( Segment, Bus, Device, Function, Register ) \\r
+  *QNCMmPci8Ptr( Segment, Bus, Device, Function, Register )\r
+\r
+#define QNCMmPci8Or( Segment, Bus, Device, Function, Register, OrData ) \\r
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT8) ( \\r
+      QNCMmPci8( Segment, Bus, Device, Function, Register ) | \\r
+      (UINT8)(OrData) \\r
+    )\r
+\r
+#define QNCMmPci8And( Segment, Bus, Device, Function, Register, AndData ) \\r
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT8) ( \\r
+      QNCMmPci8( Segment, Bus, Device, Function, Register ) & \\r
+      (UINT8)(AndData) \\r
+    )\r
+\r
+#define QNCMmPci8AndThenOr( Segment, Bus, Device, Function, Register, AndData, OrData ) \\r
+  QNCMmPci8( Segment, Bus, Device, Function, Register ) = \\r
+    (UINT8) ( \\r
+      ( QNCMmPci8( Segment, Bus, Device, Function, Register ) & \\r
+          (UINT8)(AndData) \\r
+        ) | \\r
+      (UINT8)(OrData) \\r
+    )\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h b/QuarkSocPkg/QuarkNorthCluster/Include/QuarkNcSocId.h
new file mode 100644 (file)
index 0000000..a9f3edd
--- /dev/null
@@ -0,0 +1,757 @@
+/** @file\r
+QuarkNcSocId Register Definitions\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+Definitions beginning with "R_" are registers\r
+Definitions beginning with "B_" are bits within registers\r
+Definitions beginning with "V_" are meaningful values of bits within the registers\r
+Definitions beginning with "S_" are register sizes\r
+Definitions beginning with "N_" are the bit position\r
+\r
+**/\r
+\r
+#ifndef _QUARK_NC_SOC_ID_H_\r
+#define _QUARK_NC_SOC_ID_H_\r
+\r
+//\r
+// QNC GMCH Equates\r
+//\r
+\r
+//\r
+// DEVICE 0 (Memroy Controller Hub)\r
+//\r
+#define MC_BUS                  PCI_BUS_NUMBER_QNC\r
+#define MC_DEV                  0x00\r
+#define MC_FUN                  0x00\r
+\r
+#define   QUARK_MC_VENDOR_ID      V_INTEL_VENDOR_ID\r
+#define   QUARK_MC_DEVICE_ID      0x0958\r
+#define   QUARK2_MC_DEVICE_ID     0x12C0\r
+#define   QNC_MC_REV_ID_A0      0x00\r
+\r
+\r
+//\r
+// MCR - B0:D0:F0:RD0h (WO)- Message control register\r
+// [31:24] Message opcode - D0 read; E0 write;\r
+// [23:16] Message port\r
+// [15:8 ] Message target register address\r
+// [ 7:4 ] Message write byte enable : F is enable\r
+// [ 3:0 ] Reserved\r
+//\r
+#define QNC_ACCESS_PORT_MCR              0xD0          // Message Control Register\r
+// Always Set to 0xF0\r
+\r
+//\r
+//MDR - B0:D0:F0:RD4h (RW)- Message data register\r
+//\r
+#define QNC_ACCESS_PORT_MDR              0xD4          // Message Data Register\r
+\r
+//\r
+//MEA - B0:D0:F0:RD8h (RW)- Message extended address register\r
+//\r
+#define QNC_ACCESS_PORT_MEA              0xD8          // Message Extended Address Register\r
+\r
+#define  QNC_MCR_OP_OFFSET           24           // Offset of the opcode field in MCR\r
+#define  QNC_MCR_PORT_OFFSET         16           // Offset of the port field in MCR\r
+#define  QNC_MCR_REG_OFFSET          8            // Offset of the register field in MCR\r
+\r
+//\r
+// Misc Useful Macros\r
+//\r
+\r
+#define LShift16(value) (value << 16)\r
+\r
+//\r
+// QNC Message OpCodes and Attributes\r
+//\r
+#define QUARK_OPCODE_READ              0x10         // Quark message bus "read" opcode\r
+#define QUARK_OPCODE_WRITE             0x11         // Quark message bus "write" opcode\r
+\r
+//\r
+// Alternative opcodes for the SCSS block\r
+//\r
+#define QUARK_ALT_OPCODE_READ          0x06         // Quark message bus "read" opcode\r
+#define QUARK_ALT_OPCODE_WRITE         0x07         // Quark message bus "write" opcode\r
+\r
+//\r
+// QNC Message OpCodes and Attributes for IO\r
+//\r
+#define QUARK_OPCODE_IO_READ           0x02         // Quark message bus "IO read" opcode\r
+#define QUARK_OPCODE_IO_WRITE          0x03         // Quark message bus "IO write" opcode\r
+\r
+\r
+#define QUARK_DRAM_BASE_ADDR_READY     0x78         // Quark message bus "RMU Main binary shadow" opcode\r
+\r
+#define QUARK_ECC_SCRUB_RESUME         0xC2         // Quark Remote Management Unit "scrub resume" opcode\r
+#define QUARK_ECC_SCRUB_PAUSE          0xC3         // Quark Remote Management Unit "scrub pause" opcode\r
+\r
+//\r
+// QNC Message Ports and Registers\r
+//\r
+// Start of SB Port IDs\r
+#define QUARK_NC_MEMORY_ARBITER_SB_PORT_ID    0x00\r
+#define QUARK_NC_MEMORY_CONTROLLER_SB_PORT_ID 0x01\r
+#define QUARK_NC_HOST_BRIDGE_SB_PORT_ID       0x03\r
+#define QUARK_NC_RMU_SB_PORT_ID               0x04\r
+#define QUARK_NC_MEMORY_MANAGER_SB_PORT_ID    0x05\r
+#define QUARK_SC_USB_AFE_SB_PORT_ID           0x14\r
+#define QUARK_SC_PCIE_AFE_SB_PORT_ID          0x16\r
+#define QUARK_SCSS_SOC_UNIT_SB_PORT_ID        0x31\r
+#define QUARK_SCSS_FUSE_SB_PORT_ID            0x33\r
+#define QUARK_ICLK_SB_PORT_ID                 0x32\r
+#define QUARK_SCSS_CRU_SB_PORT_ID             0x34\r
+\r
+//\r
+// Quark Memory Arbiter Registers.\r
+//\r
+#define   QUARK_NC_MEMORY_ARBITER_REG_ASTATUS     0x21        // Memory Arbiter PRI Status encodings register.\r
+#define   ASTATUS_PRI_CASUAL                    0x0         // Serviced only if convenient\r
+#define   ASTATUS_PRI_IMPENDING                 0x1         // Serviced if the DRAM is in Self-Refresh.\r
+#define   ASTATUS_PRI_NORMAL                    0x2         // Normal request servicing.\r
+#define   ASTATUS_PRI_URGENT                    0x3         // Urgent request servicing.\r
+#define   ASTATUS1_RASISED_BP                   (10)\r
+#define   ASTATUS1_RASISED_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)\r
+#define   ASTATUS0_RASISED_BP                   (8)\r
+#define   ASTATUS0_RASISED_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)\r
+#define   ASTATUS1_DEFAULT_BP                   (2)\r
+#define   ASTATUS1_DEFAULT_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)\r
+#define   ASTATUS0_DEFAULT_BP                   (0)\r
+#define   ASTATUS0_DEFAULT_BP_MASK              (0x03 << ASTATUS1_RASISED_BP)\r
+\r
+//\r
+// Quark Memory Controller Registers.\r
+//\r
+#define QUARK_NC_MEMORY_CONTROLLER_REG_DFUSESTAT  0x70        // Fuse status register.\r
+#define   B_DFUSESTAT_ECC_DIS                     (BIT0)    // Disable ECC.\r
+\r
+//\r
+// Quark Remote Management Unit Registers.\r
+//\r
+#define QNC_MSG_TMPM_REG_PMBA                   0x70        // Power Management I/O Base Address\r
+\r
+#define QUARK_NC_RMU_REG_CONFIG                   0x71        // Remote Management Unit configuration register.\r
+#define   TS_LOCK_AUX_TRIP_PT_REGS_ENABLE         (BIT6)\r
+#define   TS_LOCK_THRM_CTRL_REGS_ENABLE           (BIT5)\r
+\r
+#define QUARK_NC_RMU_REG_OPTIONS_1              0x72        // Remote Management Unit Options register 1.\r
+#define   OPTIONS_1_DMA_DISABLE                   (BIT0)\r
+\r
+#define QUARK_NC_RMU_REG_WDT_CONTROL              0x74        // Remote Management Unit Watchdog control register.\r
+#define   B_WDT_CONTROL_DBL_ECC_BIT_ERR_MASK      (BIT19 | BIT18)\r
+#define   B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP        18\r
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_NONE      (0x0 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)\r
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_CAT       (0x1 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)\r
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_WARM      (0x2 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)\r
+#define   V_WDT_CONTROL_DBL_ECC_BIT_ERR_SERR      (0x3 << B_WDT_CONTROL_DBL_ECC_BIT_ERR_BP)\r
+\r
+#define QUARK_NC_RMU_REG_TS_MODE                  0xB0        // Remote Management Unit Thermal sensor mode register.\r
+#define   TS_ENABLE                               (BIT15)\r
+#define QUARK_NC_RMU_REG_TS_TRIP                  0xB2        // Remote Management Unit Thermal sensor programmable trip point register.\r
+#define   TS_HOT_TRIP_CLEAR_THOLD_BP              24\r
+#define   TS_HOT_TRIP_CLEAR_THOLD_MASK            (0xFF << TS_HOT_TRIP_CLEAR_THOLD_BP)\r
+#define   TS_CAT_TRIP_CLEAR_THOLD_BP              16\r
+#define   TS_CAT_TRIP_CLEAR_THOLD_MASK            (0xFF << TS_CAT_TRIP_CLEAR_THOLD_BP)\r
+#define   TS_HOT_TRIP_SET_THOLD_BP                8\r
+#define   TS_HOT_TRIP_SET_THOLD_MASK              (0xFF << TS_HOT_TRIP_SET_THOLD_BP)\r
+#define   TS_CAT_TRIP_SET_THOLD_BP                0\r
+#define   TS_CAT_TRIP_SET_THOLD_MASK              (0xFF << TS_CAT_TRIP_SET_THOLD_BP)\r
+\r
+#define QUARK_NC_ECC_SCRUB_CONFIG_REG             0x50\r
+#define   SCRUB_CFG_INTERVAL_SHIFT              0x00\r
+#define   SCRUB_CFG_INTERVAL_MASK               0xFF\r
+#define   SCRUB_CFG_BLOCKSIZE_SHIFT             0x08\r
+#define   SCRUB_CFG_BLOCKSIZE_MASK              0x1F\r
+#define   SCRUB_CFG_ACTIVE                      (BIT13)\r
+#define   SCRUB_CFG_INVALID                     0x00000FFF\r
+\r
+#define QUARK_NC_ECC_SCRUB_START_MEM_REG          0x76\r
+#define QUARK_NC_ECC_SCRUB_END_MEM_REG            0x77\r
+#define QUARK_NC_ECC_SCRUB_NEXT_READ_REG          0x7C\r
+\r
+#define SCRUB_RESUME_MSG() ((UINT32)( \\r
+          (QUARK_ECC_SCRUB_RESUME << QNC_MCR_OP_OFFSET) | \\r
+          (QUARK_NC_RMU_SB_PORT_ID << QNC_MCR_PORT_OFFSET) | \\r
+          0xF0))\r
+\r
+#define SCRUB_PAUSE_MSG() ((UINT32)( \\r
+          (QUARK_ECC_SCRUB_PAUSE << QNC_MCR_OP_OFFSET) | \\r
+          (QUARK_NC_RMU_SB_PORT_ID << QNC_MCR_PORT_OFFSET) | \\r
+          0xF0))\r
+\r
+//\r
+// Quark Memory Manager Registers\r
+//\r
+#define QUARK_NC_MEMORY_MANAGER_ESRAMPGCTRL_BLOCK     0x82\r
+#define   BLOCK_ENABLE_PG                           (1 << 28)\r
+#define   BLOCK_DISABLE_PG                          (1 << 29)\r
+#define QUARK_NC_MEMORY_MANAGER_BIMRVCTL              0x19\r
+#define   EnableIMRInt                                BIT31\r
+#define QUARK_NC_MEMORY_MANAGER_BSMMVCTL              0x1C\r
+#define   EnableSMMInt                                BIT31\r
+#define QUARK_NC_MEMORY_MANAGER_BTHCTRL               0x20\r
+#define   DRAM_NON_HOST_RQ_LIMIT_BP                   0\r
+#define   DRAM_NON_HOST_RQ_LIMIT_MASK                 (0x3f << DRAM_NON_HOST_RQ_LIMIT_BP)\r
+\r
+#define QUARK_NC_TOTAL_IMR_SET                        0x8\r
+#define QUARK_NC_MEMORY_MANAGER_IMR0                  0x40\r
+#define QUARK_NC_MEMORY_MANAGER_IMR1                  0x44\r
+#define QUARK_NC_MEMORY_MANAGER_IMR2                  0x48\r
+#define QUARK_NC_MEMORY_MANAGER_IMR3                  0x4C\r
+#define QUARK_NC_MEMORY_MANAGER_IMR4                  0x50\r
+#define QUARK_NC_MEMORY_MANAGER_IMR5                  0x54\r
+#define QUARK_NC_MEMORY_MANAGER_IMR6                  0x58\r
+#define QUARK_NC_MEMORY_MANAGER_IMR7                  0x5C\r
+  #define QUARK_NC_MEMORY_MANAGER_IMRXL               0x00\r
+    #define IMR_LOCK                                BIT31\r
+    #define IMR_EN                                  BIT30\r
+    #define IMRL_MASK                               0x00FFFFFC\r
+    #define IMRL_RESET                              0x00000000\r
+  #define QUARK_NC_MEMORY_MANAGER_IMRXH               0x01\r
+    #define IMRH_MASK                               0x00FFFFFC\r
+    #define IMRH_RESET                              0x00000000\r
+  #define QUARK_NC_MEMORY_MANAGER_IMRXRM              0x02\r
+  #define QUARK_NC_MEMORY_MANAGER_IMRXWM              0x03\r
+    #define IMRX_ALL_ACCESS                         0xFFFFFFFF\r
+    #define CPU_SNOOP                               BIT30\r
+    #define RMU                                     BIT29\r
+    #define CPU0_NON_SMM                            BIT0\r
+\r
+//\r
+// Quark Host Bridge Registers\r
+//\r
+#define QNC_MSG_FSBIC_REG_HMISC                0x03       // Host Misellaneous Controls\r
+#define   SMI_EN                              (BIT19)     // SMI Global Enable (from Legacy Bridge)\r
+#define QNC_MSG_FSBIC_REG_HSMMC                0x04       // Host SMM Control\r
+#define   NON_HOST_SMM_WR_OPEN                (BIT18)     // SMM Writes OPEN\r
+#define   NON_HOST_SMM_RD_OPEN                (BIT17)     // SMM Writes OPEN\r
+#define   SMM_CODE_RD_OPEN                    (BIT16)     // SMM Code read OPEN\r
+#define   SMM_CTL_EN                          (BIT3)      // SMM enable\r
+#define   SMM_WRITE_OPEN                      (BIT2)      // SMM Writes OPEN\r
+#define   SMM_READ_OPEN                       (BIT1)      // SMM Reads OPEN\r
+#define   SMM_LOCKED                          (BIT0)      // SMM Locked\r
+#define   SMM_START_MASK                      0x0000FFF0\r
+#define   SMM_END_MASK                        0xFFF00000\r
+#define QUARK_NC_HOST_BRIDGE_HMBOUND_REG              0x08\r
+#define   HMBOUND_MASK                        0x0FFFFF000\r
+#define   HMBOUND_LOCK                        BIT0\r
+#define QUARK_NC_HOST_BRIDGE_HLEGACY_REG              0x0A\r
+#define   HLEGACY_SMI_PIN_VALUE               BIT12\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP            0x40\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE       0x41\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000        0x42\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000        0x44\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_A0000        0x46\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C0000         0x48\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C8000         0x4A\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D0000         0x4C\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D8000         0x4E\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E0000         0x50\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E8000         0x52\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F0000         0x54\r
+#define QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000         0x56\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSBASE  0x58\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_SMRR_PHYSMASK  0x59\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0      0x5A\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK0      0x5B\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE1      0x5C\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK1      0x5D\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE2      0x5E\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK2      0x5F\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE3      0x60\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK3      0x61\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE4      0x62\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK4      0x63\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE5      0x64\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK5      0x65\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE6      0x66\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK6      0x67\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE7      0x68\r
+#define QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSMASK7      0x69\r
+\r
+//\r
+// System On Chip Unit (SOCUnit) Registers.\r
+//\r
+#define QUARK_SCSS_SOC_UNIT_STPDDRCFG           0x00\r
+#define   B_STPDDRCFG_FORCE_RECOVERY              BIT0\r
+#define QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE    0x25\r
+#define   B_ROM_FUSE_IN_SECURE_SKU              BIT6\r
+\r
+#define QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG       0x31\r
+#define   B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK   (BIT5 | BIT4 | BIT3)\r
+#define   B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP     3\r
+#define   B_TSCGF1_CONFIG_ISNSCHOPSEL_MASK      (BIT12 | BIT11 | BIT10 | BIT9 | BIT8)\r
+#define   B_TSCGF1_CONFIG_ISNSCHOPSEL_BP        8\r
+#define   B_TSCGF1_CONFIG_IBGEN                 BIT17\r
+#define   B_TSCGF1_CONFIG_IBGEN_BP              17\r
+#define   B_TSCGF1_CONFIG_IBGCHOPEN             BIT18\r
+#define   B_TSCGF1_CONFIG_IBGCHOPEN_BP          18\r
+#define   B_TSCGF1_CONFIG_ISNSINTERNALVREFEN    BIT14\r
+#define   B_TSCGF1_CONFIG_ISNSINTERNALVREFEN_BP 14\r
+\r
+#define QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG       0x32\r
+#define   B_TSCGF2_CONFIG_IDSCONTROL_MASK       0x0000FFFF\r
+#define   B_TSCGF2_CONFIG_IDSCONTROL_BP         0\r
+#define   B_TSCGF2_CONFIG_IDSTIMING_MASK        0xFFFF0000\r
+#define   B_TSCGF2_CONFIG_IDSTIMING_BP          16\r
+\r
+#define QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2      0x33\r
+#define   B_TSCGF2_CONFIG2_ISPARECTRL_MASK      0xFF000000\r
+#define   B_TSCGF2_CONFIG2_ISPARECTRL_BP        24\r
+#define   B_TSCGF2_CONFIG2_ICALCONFIGSEL_MASK   (BIT9 | BIT8)\r
+#define   B_TSCGF2_CONFIG2_ICALCONFIGSEL_BP     8\r
+#define   B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK  0x000000FF\r
+#define   B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP    0\r
+\r
+#define QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG       0x34\r
+#define   B_TSCGF3_CONFIG_ITSRST                BIT0\r
+#define   B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP      11\r
+#define   B_TSCGF3_CONFIG_ITSGAMMACOEFF_MASK    (0xFFF << B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP)\r
+\r
+#define QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG     0x36\r
+#define   SOCCLKEN_CONFIG_PHY_I_SIDE_RST_L      BIT20\r
+#define   SOCCLKEN_CONFIG_PHY_I_CMNRESET_L      BIT19\r
+#define   SOCCLKEN_CONFIG_SBI_BB_RST_B          BIT18\r
+#define   SOCCLKEN_CONFIG_SBI_RST_100_CORE_B    BIT17\r
+#define   SOCCLKEN_CONFIG_BB_RST_B              BIT16\r
+\r
+#define QUARK_SCSS_SOC_UNIT_SOCCLKEN_CONFIG     0x36\r
+\r
+#define QUARK_SCSS_SOC_UNIT_CFG_STICKY_RW       0x51\r
+#define   B_CFG_STICKY_RW_SMM_VIOLATION         BIT0\r
+#define   B_CFG_STICKY_RW_HMB_VIOLATION         BIT1\r
+#define   B_CFG_STICKY_RW_IMR_VIOLATION         BIT2\r
+#define   B_CFG_STICKY_RW_DECC_VIOLATION        BIT3\r
+#define   B_CFG_STICKY_RW_WARM_RST              BIT4\r
+#define   B_CFG_STICKY_RW_FORCE_RECOVERY        BIT9\r
+#define   B_CFG_STICKY_RW_VIOLATION             (B_CFG_STICKY_RW_SMM_VIOLATION | B_CFG_STICKY_RW_HMB_VIOLATION | B_CFG_STICKY_RW_IMR_VIOLATION | B_CFG_STICKY_RW_DECC_VIOLATION)\r
+#define   B_CFG_STICKY_RW_ALL                   (B_CFG_STICKY_RW_VIOLATION | B_CFG_STICKY_RW_WARM_RST)\r
+\r
+//\r
+// iCLK Registers.\r
+//\r
+#define QUARK_ICLK_MUXTOP                       0x0140\r
+#define   B_MUXTOP_FLEX2_MASK                   (BIT25 | BIT24 | BIT23)\r
+#define   B_MUXTOP_FLEX2_BP                     23\r
+#define   B_MUXTOP_FLEX1_MASK                   (BIT22 | BIT21 | BIT20)\r
+#define   B_MUXTOP_FLEX1_BP                     20\r
+\r
+#define QUARK_ICLK_SSC1                         0x0314\r
+#define QUARK_ICLK_SSC2                         0x0414\r
+#define QUARK_ICLK_SSC3                         0x0514\r
+#define QUARK_ICLK_REF2_DBUFF0                  0x2000\r
+\r
+//\r
+// PCIe AFE Unit Registers (QUARK_SC_PCIE_AFE_SB_PORT_ID).\r
+//\r
+#define QUARK_PCIE_AFE_PCIE_RXPICTRL0_L0        0x2080\r
+#define QUARK_PCIE_AFE_PCIE_RXPICTRL0_L1        0x2180\r
+#define   OCFGPIMIXLOAD_1_0                   BIT6\r
+#define   OCFGPIMIXLOAD_1_0_MASK              0xFFFFFF3F\r
+\r
+//\r
+// QNC ICH Equates\r
+//\r
+#define V_INTEL_VENDOR_ID              0x8086\r
+\r
+#define PCI_BUS_NUMBER_QNC              0x00\r
+\r
+//\r
+// PCI to LPC Bridge Registers (D31:F0)\r
+//\r
+#define PCI_DEVICE_NUMBER_QNC_LPC       31\r
+#define PCI_FUNCTION_NUMBER_QNC_LPC     0\r
+\r
+#define R_QNC_LPC_VENDOR_ID             0x00\r
+#define   V_LPC_VENDOR_ID             V_INTEL_VENDOR_ID\r
+#define R_QNC_LPC_DEVICE_ID             0x02\r
+#define   QUARK_V_LPC_DEVICE_ID_0           0x095E\r
+#define R_QNC_LPC_REV_ID                0x08\r
+\r
+#define R_QNC_LPC_SMBUS_BASE            0x40 //~0x43\r
+#define   B_QNC_LPC_SMBUS_BASE_EN         (BIT31)\r
+#define   B_QNC_LPC_SMBUS_BASE_MASK       0x0000FFC0 //[15:6]\r
+//\r
+// SMBus register offsets from SMBA - "SMBA" (D31:F0:R40h)\r
+//        Suggested Value for SMBA = 0x1040\r
+//\r
+#define R_QNC_SMBUS_HCTL                0x00   // Host Control Register R/W\r
+#define   B_QNC_SMBUS_START               (BIT4)   // Start/Stop\r
+#define     V_QNC_SMBUS_HCTL_CMD_QUICK               0\r
+#define     V_QNC_SMBUS_HCTL_CMD_BYTE                1\r
+#define     V_QNC_SMBUS_HCTL_CMD_BYTE_DATA           2\r
+#define     V_QNC_SMBUS_HCTL_CMD_WORD_DATA           3\r
+#define     V_QNC_SMBUS_HCTL_CMD_PROCESS_CALL        4\r
+#define     V_QNC_SMBUS_HCTL_CMD_BLOCK               5\r
+\r
+#define R_QNC_SMBUS_HSTS                0x01   // Host Status Register R/W\r
+#define   B_QNC_SMBUS_BERR                (BIT2)   // BUS Error\r
+#define   B_QNC_SMBUS_DERR                (BIT1)   // Device Error\r
+#define   B_QNC_SMBUS_BYTE_DONE_STS       (BIT0)   // Completion Status\r
+#define   B_QNC_SMBUS_HSTS_ALL            0x07\r
+\r
+#define R_QNC_SMBUS_HCLK                0x02   // Host Clock Divider Register R/W\r
+#define     V_QNC_SMBUS_HCLK_100KHZ         0x0054\r
+\r
+#define R_QNC_SMBUS_TSA                 0x04   // Transmit Slave Address Register R/W\r
+#define     V_QNC_SMBUS_RW_SEL_READ         1\r
+#define     V_QNC_SMBUS_RW_SEL_WRITE        0\r
+\r
+#define R_QNC_SMBUS_HCMD                0x05   // Host Command Register R/W\r
+#define R_QNC_SMBUS_HD0                 0x06   // Data 0 Register R/W\r
+#define R_QNC_SMBUS_HD1                 0x07   // Data 1 Register R/W\r
+#define R_QNC_SMBUS_HBD                 0x20   // Host Block Data Register R/W [255:0] ~ 3Fh\r
+\r
+#define R_QNC_LPC_GBA_BASE              0x44\r
+#define   B_QNC_LPC_GPA_BASE_MASK         0x0000FFC0\r
+//\r
+// GPIO register offsets from GBA - "GPIO" (D31:F0:R44h)\r
+//        Suggested Value for GBA = 0x1080\r
+//\r
+#define R_QNC_GPIO_CGEN_CORE_WELL       0x00\r
+#define R_QNC_GPIO_CGIO_CORE_WELL       0x04\r
+#define R_QNC_GPIO_CGLVL_CORE_WELL      0x08\r
+#define R_QNC_GPIO_CGTPE_CORE_WELL      0x0C   // Core well GPIO Trigger Positive Edge Enable\r
+#define R_QNC_GPIO_CGTNE_CORE_WELL      0x10   // Core well GPIO Trigger Negative Edge Enable\r
+#define R_QNC_GPIO_CGGPE_CORE_WELL      0x14   // Core well GPIO GPE Enable\r
+#define R_QNC_GPIO_CGSMI_CORE_WELL      0x18   // Core well GPIO SMI Enable\r
+#define R_QNC_GPIO_CGTS_CORE_WELL       0x1C   // Core well GPIO Trigger Status\r
+#define R_QNC_GPIO_RGEN_RESUME_WELL     0x20\r
+#define R_QNC_GPIO_RGIO_RESUME_WELL     0x24\r
+#define R_QNC_GPIO_RGLVL_RESUME_WELL    0x28\r
+#define R_QNC_GPIO_RGTPE_RESUME_WELL    0x2C   // Resume well GPIO Trigger Positive Edge Enable\r
+#define R_QNC_GPIO_RGTNE_RESUME_WELL    0x30   // Resume well GPIO Trigger Negative Edge Enable\r
+#define R_QNC_GPIO_RGGPE_RESUME_WELL    0x34   // Resume well GPIO GPE Enable\r
+#define R_QNC_GPIO_RGSMI_RESUME_WELL    0x38   // Resume well GPIO SMI Enable\r
+#define R_QNC_GPIO_RGTS_RESUME_WELL     0x3C   // Resume well GPIO Trigger Status\r
+#define R_QNC_GPIO_CNMIEN_CORE_WELL     0x40   // Core well GPIO NMI Enable\r
+#define R_QNC_GPIO_RNMIEN_RESUME_WELL   0x44   // Resume well GPIO NMI Enable\r
+\r
+#define R_QNC_LPC_PM1BLK                0x48\r
+#define   B_QNC_LPC_PM1BLK_MASK           0x0000FFF0\r
+//\r
+// ACPI register offsets from PM1BLK - "ACPI PM1 Block" (D31:F0:R48h)\r
+//        Suggested Value for PM1BLK = 0x1000\r
+//\r
+#define R_QNC_PM1BLK_PM1S               0x00\r
+#define  S_QNC_PM1BLK_PM1S               2\r
+#define   B_QNC_PM1BLK_PM1S_ALL           (BIT15+BIT14+BIT10+BIT5+BIT0)\r
+#define   B_QNC_PM1BLK_PM1S_WAKE          (BIT15)\r
+#define   B_QNC_PM1BLK_PM1S_PCIEWSTS      (BIT14)\r
+#define   B_QNC_PM1BLK_PM1S_RTC           (BIT10)\r
+#define   B_QNC_PM1BLK_PM1S_GLOB          (BIT5)\r
+#define   B_QNC_PM1BLK_PM1S_TO            (BIT0)\r
+#define    N_QNC_PM1BLK_PM1S_RTC           10\r
+\r
+\r
+#define R_QNC_PM1BLK_PM1E               0x02\r
+#define  S_QNC_PM1BLK_PM1E               2\r
+#define   B_QNC_PM1BLK_PM1E_PWAKED        (BIT14)\r
+#define   B_QNC_PM1BLK_PM1E_RTC           (BIT10)\r
+#define   B_QNC_PM1BLK_PM1E_GLOB          (BIT5)\r
+#define    N_QNC_PM1BLK_PM1E_RTC           10\r
+\r
+#define R_QNC_PM1BLK_PM1C               0x04\r
+#define   B_QNC_PM1BLK_PM1C_SLPEN         (BIT13)\r
+#define   B_QNC_PM1BLK_PM1C_SLPTP         (BIT12+BIT11+BIT10)\r
+#define    V_S0                           0x00000000\r
+#define    V_S3                           0x00001400\r
+#define    V_S4                           0x00001800\r
+#define    V_S5                           0x00001C00\r
+#define   B_QNC_PM1BLK_PM1C_SCIEN         (BIT0)\r
+\r
+#define R_QNC_PM1BLK_PM1T               0x08\r
+\r
+#define R_QNC_LPC_GPE0BLK               0x4C\r
+#define   B_QNC_LPC_GPE0BLK_MASK          0x0000FFC0\r
+//        Suggested Value for GPE0BLK = 0x10C0\r
+//\r
+#define R_QNC_GPE0BLK_GPE0S             0x00          // General Purpose Event 0 Status\r
+#define  S_QNC_GPE0BLK_GPE0S             4\r
+#define   B_QNC_GPE0BLK_GPE0S_ALL         0x00003F800 // used to clear the status reg\r
+#define   B_QNC_GPE0BLK_GPE0S_PCIE        (BIT17)     // PCIE\r
+#define   B_QNC_GPE0BLK_GPE0S_GPIO        (BIT14)     // GPIO\r
+#define   B_QNC_GPE0BLK_GPE0S_EGPE        (BIT13)     // External GPE\r
+#define    N_QNC_GPE0BLK_GPE0S_THRM        12\r
+\r
+#define R_QNC_GPE0BLK_GPE0E             0x04          // General Purpose Event 0 Enable\r
+#define  S_QNC_GPE0BLK_GPE0E             4\r
+#define   B_QNC_GPE0BLK_GPE0E_PCIE        (BIT17)     // PCIE\r
+#define   B_QNC_GPE0BLK_GPE0E_GPIO        (BIT14)     // GPIO\r
+#define   B_QNC_GPE0BLK_GPE0E_EGPE        (BIT13)     // External GPE\r
+#define    N_QNC_GPE0BLK_GPE0E_THRM        12\r
+\r
+#define R_QNC_GPE0BLK_SMIE              0x10          // SMI_B Enable\r
+#define  S_QNC_GPE0BLK_SMIE              4\r
+#define   B_QNC_GPE0BLK_SMIE_ALL          0x0003871F\r
+#define   B_QNC_GPE0BLK_SMIE_APM          (BIT4)      // APM\r
+#define   B_QNC_GPE0BLK_SMIE_SLP          (BIT2)      // Sleep\r
+#define   B_QNC_GPE0BLK_SMIE_SWT          (BIT1)      // Software Timer\r
+#define    N_QNC_GPE0BLK_SMIE_GPIO         9\r
+#define    N_QNC_GPE0BLK_SMIE_ESMI         8\r
+#define    N_QNC_GPE0BLK_SMIE_APM          4\r
+#define    N_QNC_GPE0BLK_SMIE_SPI          3\r
+#define    N_QNC_GPE0BLK_SMIE_SLP          2\r
+#define    N_QNC_GPE0BLK_SMIE_SWT          1\r
+\r
+#define R_QNC_GPE0BLK_SMIS              0x14           // SMI Status Register.\r
+#define  S_QNC_GPE0BLK_SMIS              4\r
+#define   B_QNC_GPE0BLK_SMIS_ALL          0x0003871F\r
+#define   B_QNC_GPE0BLK_SMIS_EOS          (BIT31)      // End of SMI\r
+#define   B_QNC_GPE0BLK_SMIS_APM          (BIT4)       // APM\r
+#define   B_QNC_GPE0BLK_SMIS_SPI          (BIT3)       // SPI\r
+#define   B_QNC_GPE0BLK_SMIS_SLP          (BIT2)       // Sleep\r
+#define   B_QNC_GPE0BLK_SMIS_SWT          (BIT1)       // Software Timer\r
+#define   B_QNC_GPE0BLK_SMIS_BIOS         (BIT0)       // BIOS\r
+#define    N_QNC_GPE0BLK_SMIS_GPIO         9\r
+#define    N_QNC_GPE0BLK_SMIS_APM          4\r
+#define    N_QNC_GPE0BLK_SMIS_SPI          3\r
+#define    N_QNC_GPE0BLK_SMIS_SLP          2\r
+#define    N_QNC_GPE0BLK_SMIS_SWT          1\r
+\r
+#define R_QNC_GPE0BLK_PMCW              0x28            // Power Management Configuration Core Well\r
+#define   B_QNC_GPE0BLK_PMCW_PSE          (BIT31)       // Periodic SMI Enable\r
+\r
+#define R_QNC_GPE0BLK_PMSW              0x2C            // Power Management Configuration Suspend/Resume Well\r
+#define    B_QNC_GPE0BLK_PMSW_DRAM_INIT   (BIT0)        // Dram Initialization Sctrachpad\r
+\r
+#define R_QNC_LPC_ACTL                  0x58\r
+#define    V_QNC_LPC_ACTL_SCIS_IRQ9        0x00\r
+\r
+//\r
+// Number of PIRQs supported. PIRQA~PIRQH\r
+//\r
+#define QNC_NUMBER_PIRQS                8\r
+#define R_QNC_LPC_PIRQA_ROUT            0x60\r
+#define R_QNC_LPC_PIRQB_ROUT            0x61\r
+#define R_QNC_LPC_PIRQC_ROUT            0x62\r
+#define R_QNC_LPC_PIRQD_ROUT            0x63\r
+#define R_QNC_LPC_PIRQE_ROUT            0x64\r
+#define R_QNC_LPC_PIRQF_ROUT            0x65\r
+#define R_QNC_LPC_PIRQG_ROUT            0x66\r
+#define R_QNC_LPC_PIRQH_ROUT            0x67\r
+\r
+//\r
+// Bit values are the same for R_TNC_LPC_PIRQA_ROUT to\r
+//                             R_TNC_LPC_PIRQH_ROUT\r
+#define   B_QNC_LPC_PIRQX_ROUT            (BIT3+BIT2+BIT1+BIT0)\r
+\r
+#define R_QNC_LPC_WDTBA                 0x84\r
+// Watchdog Timer register offsets from WDTBASE (in R_QNC_LPC_WDTBA)------------BEGIN\r
+#define R_QNC_LPC_WDT_WDTCR             0x10\r
+#define R_QNC_LPC_WDT_WDTLR             0x18\r
+// Watchdog Timer register offsets from WDTBASE (in R_QNC_LPC_WDTBA)--------------END\r
+\r
+#define R_QNC_LPC_FWH_BIOS_DEC          0xD4\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_F8       (BIT31)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_F0       (BIT30)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_E8       (BIT29)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_E0       (BIT28)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_D8       (BIT27)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_D0       (BIT26)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_C8       (BIT25)\r
+#define   B_QNC_LPC_FWH_BIOS_DEC_C0       (BIT24)\r
+\r
+#define R_QNC_LPC_BIOS_CNTL             0xD8\r
+#define  S_QNC_LPC_BIOS_CNTL             4\r
+#define   B_QNC_LPC_BIOS_CNTL_PFE         (BIT8)\r
+#define   B_QNC_LPC_BIOS_CNTL_SMM_BWP     (BIT5)\r
+#define   B_QNC_LPC_BIOS_CNTL_BCD         (BIT2)\r
+#define   B_QNC_LPC_BIOS_CNTL_BLE         (BIT1)\r
+#define   B_QNC_LPC_BIOS_CNTL_BIOSWE      (BIT0)\r
+#define    N_QNC_LPC_BIOS_CNTL_BLE         1\r
+#define    N_QNC_LPC_BIOS_CNTL_BIOSWE      0\r
+\r
+#define R_QNC_LPC_RCBA                  0xF0\r
+#define   B_QNC_LPC_RCBA_MASK             0xFFFFC000\r
+#define   B_QNC_LPC_RCBA_EN               (BIT0)\r
+\r
+//---------------------------------------------------------------------------\r
+//  Fixed IO Decode on QuarkNcSocId\r
+//\r
+//  20h(2B) 24h(2B) 28h(2B) 2Ch(2B) 30h(2B) 34h(2B) 38h(2B) 3Ch(2B) : R/W 8259 master\r
+//  40h(3B): R/W 8254\r
+//  43h(1B): W   8254\r
+//  50h(3B): R/W 8254\r
+//  53h(1B): W   8254\r
+//  61h(1B): R/W NMI Controller\r
+//  63h(1B): R/W NMI Controller - can be disabled\r
+//  65h(1B): R/W NMI Controller - can be disabled\r
+//  67h(1B): R/W NMI Controller - can be disabled\r
+//  70h(1B): W   NMI & RTC\r
+//  71h(1B): R/W RTC\r
+//  72h(1B): R RTC; W NMI&RTC\r
+//  73h(1B): R/W RTC\r
+//  74h(1B): R RTC; W NMI&RTC\r
+//  75h(1B): R/W RTC\r
+//  76h(1B): R RTC; W NMI&RTC\r
+//  77h(1B): R/W RTC\r
+//  84h(3B): R/W Internal/LPC\r
+//  88h(1B): R/W Internal/LPC\r
+//  8Ch(3B): R/W Internal/LPC\r
+//  A0h(2B) A4h(2B) A8h(2B) ACh(2B) B0h(2B) B4h(2B) B8h(2B) BCh(2B): R/W 8259 slave\r
+//  B2h(1B) B3h(1B): R/W Power management\r
+//  3B0h-3BBh: R/W VGA\r
+//  3C0h-3DFh: R/W VGA\r
+//  CF8h(4B): R/W Internal\r
+//  CF9h(1B): R/W LPC\r
+//  CFCh(4B): R/W Internal\r
+//---------------------------------------------------------------------------\r
+\r
+#define R_APM_CNT                                       0xB2\r
+\r
+//\r
+// Reset Generator I/O Port\r
+//\r
+#define RST_CNT                                       0xCF9\r
+#define   B_RST_CNT_COLD_RST                            (BIT3)     // Cold reset\r
+#define   B_RST_CNT_WARM_RST                            (BIT1)     // Warm reset\r
+\r
+//\r
+// Processor interface registers (NMI)\r
+//\r
+\r
+#define  PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0                20\r
+#define  PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1                21\r
+#define  PCI_FUNCTION_NUMBER_QNC_IOSF2AHB                 0\r
+\r
+//\r
+// Pci Express Root Ports (D23:F0/F1)\r
+//\r
+#define PCI_DEVICE_NUMBER_PCIE_ROOTPORT                 23\r
+#define PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0             0\r
+#define PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1             1\r
+\r
+#define MAX_PCI_EXPRESS_ROOT_PORTS                      2\r
+\r
+#define R_QNC_PCIE_BNUM                             0x18\r
+#define R_QNC_PCIE_CAP_PTR                          0x34\r
+\r
+#define PCIE_CAPID                                  0x10  //PCIE Capability ID\r
+#define PCIE_CAP_EXT_HEARDER_OFFSET                 0x100 //PCIE Capability ID\r
+#define PCIE_DEV_CAP_OFFSET                         0x04 //PCIE Device Capability reg offset\r
+#define PCIE_LINK_CAP_OFFSET                        0x0C //PCIE Link Capability reg offset\r
+#define PCIE_LINK_CNT_OFFSET                        0x10 //PCIE Link control reg offset\r
+#define PCIE_LINK_STS_OFFSET                        0x12 //PCIE Link status reg offset\r
+#define PCIE_SLOT_CAP_OFFSET                        0x14 //PCIE Link Capability reg offset\r
+\r
+#define R_QNC_PCIE_XCAP                             0x42  //~ 43h\r
+#define   B_QNC_PCIE_XCAP_SI                          (BIT8)  //slot implemented\r
+#define R_QNC_PCIE_DCAP                             0x44  //~ 47h\r
+#define   B_QNC_PCIE_DCAP_E1AL                        (BIT11 | BIT10 | BIT9) // L1 Acceptable exit latency\r
+#define   B_QNC_PCIE_DCAP_E0AL                        (BIT8 | BIT7 | BIT6)   // L0 Acceptable exit latency\r
+#define R_QNC_PCIE_DCTL                             0x48  //~ 49h\r
+#define   B_QNC_PCIE_DCTL_URE                         (BIT3)  //Unsupported Request Reporting Enable\r
+#define   B_QNC_PCIE_DCTL_FEE                         (BIT2)  //Fatal error Reporting Enable\r
+#define   B_QNC_PCIE_DCTL_NFE                         (BIT1)  //Non Fatal error Reporting Enable\r
+#define   B_QNC_PCIE_DCTL_CEE                         (BIT0)  //Correctable error Reporting Enable\r
+#define R_QNC_PCIE_LCAP                             0x4C  //~ 4Fh\r
+#define   B_QNC_PCIE_LCAP_CPM                         (BIT18)  //clock power management supported\r
+#define   B_QNC_PCIE_LCAP_EL1_MASK                   (BIT17 | BIT16 | BIT15)  //L1 Exit latency mask\r
+#define   B_QNC_PCIE_LCAP_EL0_MASK                   (BIT14 | BIT13 | BIT12)  //L0 Exit latency mask\r
+#define   B_QNC_PCIE_LCAP_APMS_MASK                   (BIT11 | BIT10)  //Active state link PM support mask\r
+#define   V_QNC_PCIE_LCAP_APMS_OFFSET                 10  //Active state link PM support mask\r
+#define R_QNC_PCIE_LCTL                             0x50  //~ 51h\r
+#define   B_QNC_PCIE_LCTL_CCC                         (BIT6)  // Clock clock configuration\r
+#define   B_QNC_PCIE_LCTL_RL                          (BIT5)  // Retrain link\r
+#define R_QNC_PCIE_LSTS                             0x52  //~ 53h\r
+#define   B_QNC_PCIE_LSTS_SCC                         (BIT12) //Slot clock configuration\r
+#define   B_QNC_PCIE_LSTS_LT                          (BIT11) //Link training\r
+#define R_QNC_PCIE_SLCAP                            0x54  //~ 57h\r
+#define   B_QNC_PCIE_SLCAP_MASK_RSV_VALUE             0x0006007F\r
+#define   V_QNC_PCIE_SLCAP_SLV                        0x0A  //Slot power limit value [14:7]\r
+#define   V_QNC_PCIE_SLCAP_SLV_OFFSET                 7     //Slot power limit value offset is 7 [14:7]\r
+#define   V_QNC_PCIE_SLCAP_PSN_OFFSET                 19    //Slot number offset is 19 [31:19]\r
+#define R_QNC_PCIE_SLCTL                            0x58    //~ 59h\r
+#define   B_QNC_PCIE_SLCTL_HPE                        (BIT5)  // Hot plug interrupt enable\r
+#define   B_QNC_PCIE_SLCTL_PDE                        (BIT3)  // Presense detect change enable\r
+#define   B_QNC_PCIE_SLCTL_ABE                        (BIT0)  // Attention Button Pressed Enable\r
+#define R_QNC_PCIE_SLSTS                            0x5A    //~ 5Bh\r
+#define   B_QNC_PCIE_SLSTS_PDS                        (BIT6)  // Present Detect State = 1b : has device connected\r
+#define   B_QNC_PCIE_SLSTS_PDC                        (BIT3)  // Present Detect changed = 1b : PDS state has changed\r
+#define   B_QNC_PCIE_SLSTS_ABP                        (BIT0)  // Attention Button Pressed\r
+#define R_QNC_PCIE_RCTL                             0x5C    //~ 5Dh\r
+#define   B_QNC_PCIE_RCTL_PIE                         (BIT3)  //Root PCI-E PME Interrupt Enable\r
+#define   B_QNC_PCIE_RCTL_SFE                         (BIT2)  //Root PCI-E System Error on Fatal Error Enable\r
+#define   B_QNC_PCIE_RCTL_SNE                         (BIT1)  //Root PCI-E System Error on Non-Fatal Error Enable\r
+#define   B_QNC_PCIE_RCTL_SCE                         (BIT0)  //Root PCI-E System Error on Correctable Error Enable\r
+#define R_QNC_PCIE_SVID                             0x94  //~ 97h\r
+#define R_QNC_PCIE_CCFG                             0xD0  //~ D3h\r
+#define   B_QNC_PCIE_CCFG_UPSD                        (BIT24)  // Upstream Posted Split Disable\r
+#define   B_QNC_PCIE_CCFG_UNRS                        (BIT15)  // Upstream Non-Posted Request Size\r
+#define   B_QNC_PCIE_CCFG_UPRS                        (BIT14)  // Upstream Posted Request Size\r
+#define R_QNC_PCIE_MPC2                             0xD4  //~ D7h\r
+#define   B_QNC_PCIE_MPC2_IPF                         (BIT11)  // ISOF Packet Fast Transmit Mode\r
+#define R_QNC_PCIE_MPC                              0xD8  //~ DBh\r
+#define   B_QNC_PCIE_MPC_PMCE                         (BIT31)  // PM SCI Enable\r
+#define   B_QNC_PCIE_MPC_HPCE                         (BIT30)  // Hot plug SCI enable\r
+\r
+#define   B_QNC_PCIE_MPC_HPME                         (BIT1)   // Hot plug SMI enable\r
+#define   B_QNC_PCIE_MPC_PMME                         (BIT0)   // PM SMI Enable\r
+#define R_QNC_PCIE_IOSFSBCTL                        0xF6\r
+#define   B_QNC_PCIE_IOSFSBCTL_SBIC_MASK              (BIT1 | BIT0) // IOSF Sideband ISM Idle Counter.\r
+#define   B_QNC_PCIE_IOSFSBCTL_SBIC_IDLE_NEVER        (BIT1 | BIT0) // Never transition to IDLE.\r
+\r
+#define V_PCIE_MAX_TRY_TIMES                       200\r
+\r
+//\r
+// Misc PCI register offsets and sizes\r
+//\r
+#define R_EFI_PCI_SVID                              0x2C\r
+\r
+//\r
+// IO_APIC\r
+//\r
+#define IOAPIC_BASE                                 0xFEC00000\r
+#define IOAPIC_SIZE                                 0x1000\r
+\r
+//\r
+// Chipset configuration registers RCBA - "Root Complex Base Address" (D31:F0:RF0h)\r
+//            Suggested Value for  RCBA = 0xFED1C000\r
+//\r
+\r
+#define R_QNC_RCRB_SPIBASE                          0x3020       // SPI (Serial Peripheral Interface) in RCRB\r
+#define R_QNC_RCRB_SPIS                             (R_QNC_RCRB_SPIBASE + 0x00)  // SPI Status\r
+#define   B_QNC_RCRB_SPIS_SCL                       (BIT15)    // SPI Configuration Lockdown\r
+#define   B_QNC_RCRB_SPIS_BAS                       (BIT3)     // Blocked Access Status\r
+#define   B_QNC_RCRB_SPIS_CDS                       (BIT2)     // Cycle Done Status\r
+#define   B_QNC_RCRB_SPIS_SCIP                      (BIT0)     // SPI Cycle in Progress\r
+\r
+#define R_QNC_RCRB_SPIC                             (R_QNC_RCRB_SPIBASE + 0x02)  // SPI Control\r
+#define   B_QNC_RCRB_SPIC_DC                          (BIT14)    // SPI Data Cycle Enable\r
+#define   B_QNC_RCRB_SPIC_DBC                         0x3F00     // SPI Data Byte Count (1..8,16,24,32,40,48,56,64)\r
+#define   B_QNC_RCRB_SPIC_COP                         (BIT6+BIT5+BIT4)          // SPI Cycle Opcode Pointer\r
+#define   B_QNC_RCRB_SPIC_SPOP                        (BIT3)     // Sequence Prefix Opcode Pointer\r
+#define   B_QNC_RCRB_SPIC_ACS                         (BIT2)     // SPI Atomic Cycle Sequence\r
+#define   B_QNC_RCRB_SPIC_SCGO                        (BIT1)     // SPI Cycle Go\r
+\r
+#define R_QNC_RCRB_SPIA                             (R_QNC_RCRB_SPIBASE + 0x04)  // SPI Address\r
+#define   B_QNC_RCRB_SPIA_MASK                      0x00FFFFFF     // SPI Address mask\r
+#define R_QNC_RCRB_SPID0                            (R_QNC_RCRB_SPIBASE + 0x08)  // SPI Data 0\r
+#define R_QNC_RCRB_SPIPREOP                         (R_QNC_RCRB_SPIBASE + 0x54)  // Prefix Opcode Configuration\r
+#define R_QNC_RCRB_SPIOPTYPE                        (R_QNC_RCRB_SPIBASE + 0x56)  // Opcode Type Configuration\r
+#define   B_QNC_RCRB_SPIOPTYPE_NOADD_READ             0\r
+#define   B_QNC_RCRB_SPIOPTYPE_NOADD_WRITE            (BIT0)\r
+#define   B_QNC_RCRB_SPIOPTYPE_ADD_READ               (BIT1)\r
+#define   B_QNC_RCRB_SPIOPTYPE_ADD_WRITE              (BIT0 + BIT1)\r
+#define R_QNC_RCRB_SPIOPMENU                        (R_QNC_RCRB_SPIBASE + 0x58)  // Opcode Menu Configuration //R_OPMENU\r
+\r
+#define R_QNC_RCRB_SPIPBR0                          (R_QNC_RCRB_SPIBASE + 0x60)  // Protected BIOS Range 0.\r
+#define R_QNC_RCRB_SPIPBR1                          (R_QNC_RCRB_SPIBASE + 0x64)  // Protected BIOS Range 1.\r
+#define R_QNC_RCRB_SPIPBR2                          (R_QNC_RCRB_SPIBASE + 0x68)  // Protected BIOS Range 2.\r
+#define   B_QNC_RCRB_SPIPBRn_WPE                      (BIT31)                    // Write Protection Enable for above 3 registers.\r
+\r
+#define R_QNC_RCRB_AGENT0IR                         0x3140   // AGENT0 interrupt route\r
+#define R_QNC_RCRB_AGENT1IR                         0x3142   // AGENT1 interrupt route\r
+#define R_QNC_RCRB_AGENT2IR                         0x3144   // AGENT2 interrupt route\r
+#define R_QNC_RCRB_AGENT3IR                         0x3146   // AGENT3 interrupt route\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h b/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/CommonHeader.h
new file mode 100644 (file)
index 0000000..ba25fd1
--- /dev/null
@@ -0,0 +1,38 @@
+/** @file\r
+Common header file shared by all source files.\r
+\r
+This file includes package header files, library classes and protocol, PPI & GUID definitions.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef __COMMON_HEADER_H_\r
+#define __COMMON_HEADER_H_\r
+\r
+\r
+\r
+#include <PiPei.h>\r
+#include <IntelQNCBase.h>\r
+\r
+#include <Library/IntelQNCLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/CpuLib.h>\r
+#include <Library/PciCf8Lib.h>\r
+#include <Library/IoLib.h>\r
+#include <Library/PciLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/QNCAccessLib.h>\r
+#include <IndustryStandard/Pci22.h>\r
+\r
+#endif\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c b/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.c
new file mode 100644 (file)
index 0000000..142b508
--- /dev/null
@@ -0,0 +1,777 @@
+/** @file\r
+Lib function for Pei QNC.\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "CommonHeader.h"\r
+\r
+/**\r
+  This function provides the necessary SOC initialization\r
+  before MRC running. It sets RCBA, GPIO, PMBASE\r
+  and some parts of SOC through SOC message method.\r
+  If the function cannot complete it'll ASSERT().\r
+**/\r
+VOID\r
+EFIAPI\r
+PeiQNCPreMemInit (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                            RegValue;\r
+\r
+  // QNCPortWrite(Port#, Offset, Value)\r
+\r
+  //\r
+  // Set the fixed PRI Status encodings config.\r
+  //\r
+  QNCPortWrite (\r
+    QUARK_NC_MEMORY_ARBITER_SB_PORT_ID,\r
+    QUARK_NC_MEMORY_ARBITER_REG_ASTATUS,\r
+    QNC_FIXED_CONFIG_ASTATUS\r
+    );\r
+\r
+  // Sideband register write to Remote Management Unit\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QNC_MSG_TMPM_REG_PMBA, (BIT31 | PcdGet16 (PcdPmbaIoBaseAddress)));\r
+\r
+  // Configurable I/O address in iLB (legacy block)\r
+\r
+  LpcPciCfg32 (R_QNC_LPC_SMBUS_BASE) = BIT31 | PcdGet16 (PcdSmbaIoBaseAddress);\r
+  LpcPciCfg32 (R_QNC_LPC_GBA_BASE) = BIT31 | PcdGet16 (PcdGbaIoBaseAddress);\r
+  LpcPciCfg32 (R_QNC_LPC_PM1BLK) = BIT31 | PcdGet16 (PcdPm1blkIoBaseAddress);\r
+  LpcPciCfg32 (R_QNC_LPC_GPE0BLK) = BIT31 | PcdGet16 (PcdGpe0blkIoBaseAddress);\r
+  LpcPciCfg32 (R_QNC_LPC_WDTBA) = BIT31 | PcdGet16 (PcdWdtbaIoBaseAddress);\r
+\r
+  //\r
+  // Program RCBA Base Address\r
+  //\r
+  LpcPciCfg32AndThenOr (R_QNC_LPC_RCBA, (~B_QNC_LPC_RCBA_MASK), (((UINT32)(PcdGet64 (PcdRcbaMmioBaseAddress))) | B_QNC_LPC_RCBA_EN));\r
+\r
+  //\r
+  // Program Memory Manager fixed config values.\r
+  //\r
+\r
+  RegValue = QNCPortRead (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BTHCTRL);\r
+  RegValue &= ~(DRAM_NON_HOST_RQ_LIMIT_MASK);\r
+  RegValue |= (V_DRAM_NON_HOST_RQ_LIMIT << DRAM_NON_HOST_RQ_LIMIT_BP);\r
+  QNCPortWrite (QUARK_NC_MEMORY_MANAGER_SB_PORT_ID, QUARK_NC_MEMORY_MANAGER_BTHCTRL, RegValue);\r
+\r
+  //\r
+  // Program iCLK fixed config values.\r
+  //\r
+  QncIClkAndThenOr (\r
+    QUARK_ICLK_MUXTOP,\r
+    (UINT32) ~(B_MUXTOP_FLEX2_MASK | B_MUXTOP_FLEX1_MASK),\r
+    (V_MUXTOP_FLEX2 << B_MUXTOP_FLEX2_BP) | (V_MUXTOP_FLEX1 << B_MUXTOP_FLEX1_BP)\r
+    );\r
+  QncIClkAndThenOr (\r
+    QUARK_ICLK_REF2_DBUFF0,\r
+    (UINT32) ~(BIT0), // bit[0] cleared\r
+    0\r
+    );\r
+  QncIClkOr (\r
+    QUARK_ICLK_SSC1,\r
+    BIT0              // bit[0] set\r
+    );\r
+  QncIClkOr (\r
+    QUARK_ICLK_SSC2,\r
+    BIT0              // bit[0] set\r
+    );\r
+  QncIClkOr (\r
+    QUARK_ICLK_SSC3,\r
+    BIT0              // bit[0] set\r
+    );\r
+\r
+  //\r
+  // Set RMU DMA disable bit post boot.\r
+  //\r
+  RegValue = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_OPTIONS_1);\r
+  RegValue |= OPTIONS_1_DMA_DISABLE;\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_OPTIONS_1, RegValue);\r
+}\r
+\r
+/**\r
+  Do north cluster init which needs to be done AFTER MRC init.\r
+\r
+  @param   VOID\r
+\r
+  @retval  VOID\r
+**/\r
+\r
+VOID\r
+EFIAPI\r
+PeiQNCPostMemInit (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Program SVID/SID the same as VID/DID for all devices except root ports.\r
+  //\r
+  QNCMmPci32(0, MC_BUS, MC_DEV, MC_FUN, R_EFI_PCI_SVID) = QNCMmPci32(0, MC_BUS, MC_DEV, MC_FUN, PCI_VENDOR_ID_OFFSET);\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_LPC, PCI_FUNCTION_NUMBER_QNC_LPC, PCI_VENDOR_ID_OFFSET);\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_0, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, PCI_VENDOR_ID_OFFSET);\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, R_EFI_PCI_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_QNC_IOSF2AHB_1, PCI_FUNCTION_NUMBER_QNC_IOSF2AHB, PCI_VENDOR_ID_OFFSET);\r
+  return;\r
+}\r
+\r
+/**\r
+  Used to check QNC if it's S3 state.  Clear the register state after query.\r
+\r
+  @retval TRUE if it's S3 state.\r
+  @retval FALSE if it's not S3 state.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCCheckS3AndClearState (\r
+   VOID\r
+  )\r
+{\r
+  BOOLEAN       S3WakeEventFound;\r
+  UINT16        Pm1Sts;\r
+  UINT16        Pm1En;\r
+  UINT16        Pm1Cnt;\r
+  UINT32        Gpe0Sts;\r
+  UINT32        Gpe0En;\r
+  UINT32        NewValue;\r
+  CHAR8         *EventDescStr;\r
+\r
+  S3WakeEventFound = FALSE;\r
+  EventDescStr = NULL;\r
+\r
+  //\r
+  // Read the ACPI registers,\r
+  //\r
+  Pm1Sts  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S);\r
+  Pm1En   = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E);\r
+  Pm1Cnt  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
+  Gpe0Sts = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S);\r
+  Gpe0En  = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0E);\r
+\r
+  //\r
+  // Clear Power Management 1 Enable Register and\r
+  // General Purpost Event 0 Enables Register\r
+  //\r
+  IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1E, 0);\r
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0E, 0);\r
+\r
+  if ((Pm1Sts & B_QNC_PM1BLK_PM1S_WAKE) != 0 && (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) == V_S3) {\r
+\r
+    //\r
+    // Detect the actual WAKE event\r
+    //\r
+    if ((Pm1Sts & B_QNC_PM1BLK_PM1S_RTC) && (Pm1En & B_QNC_PM1BLK_PM1E_RTC)) {\r
+      EventDescStr = "RTC Alarm";\r
+      S3WakeEventFound = TRUE;\r
+    }\r
+    if ((Pm1Sts & B_QNC_PM1BLK_PM1S_PCIEWSTS) && !(Pm1En & B_QNC_PM1BLK_PM1E_PWAKED)) {\r
+      EventDescStr = "PCIe WAKE";\r
+      S3WakeEventFound = TRUE;\r
+    }\r
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_PCIE) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_PCIE)) {\r
+      EventDescStr = "PCIe";\r
+      S3WakeEventFound = TRUE;\r
+    }\r
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_GPIO) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_GPIO)) {\r
+      EventDescStr = "GPIO";\r
+      S3WakeEventFound = TRUE;\r
+    }\r
+    if ((Gpe0Sts & B_QNC_GPE0BLK_GPE0S_EGPE) && (Gpe0En & B_QNC_GPE0BLK_GPE0E_EGPE)) {\r
+      EventDescStr = "Ext. GPE";\r
+      S3WakeEventFound = TRUE;\r
+    }\r
+    if (S3WakeEventFound == FALSE) {\r
+      EventDescStr = "Unknown";\r
+    }\r
+    DEBUG ((EFI_D_INFO, "S3 Wake Event - %a\n", EventDescStr));\r
+\r
+    //\r
+    // If no Power Button Override event occurs and one enabled wake event occurs,\r
+    // just do S3 resume and clear the state.\r
+    //\r
+    IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, (Pm1Cnt & (~B_QNC_PM1BLK_PM1C_SLPTP)));\r
+\r
+    //\r
+    // Set EOS to de Assert SMI\r
+    //\r
+    IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS,  B_QNC_GPE0BLK_SMIS_EOS);\r
+\r
+    //\r
+    // Enable SMI globally\r
+    //\r
+    NewValue = QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC);\r
+    NewValue |= SMI_EN;\r
+    QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QNC_MSG_FSBIC_REG_HMISC, NewValue);\r
+\r
+    return  TRUE;\r
+  }\r
+\r
+  return  FALSE;\r
+}\r
+\r
+/**\r
+  Used to check QNC if system wakes up from power on reset. Clear the register state after query.\r
+\r
+  @retval TRUE  if system wakes up from power on reset\r
+  @retval FALSE if system does not wake up from power on reset\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QNCCheckPowerOnResetAndClearState (\r
+   VOID\r
+  )\r
+{\r
+  UINT16                Pm1Sts;\r
+  UINT16                Pm1Cnt;\r
+\r
+  //\r
+  // Read the ACPI registers,\r
+  // PM1_STS information cannot be lost after power down, unless CMOS is cleared.\r
+  //\r
+  Pm1Sts  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1S);\r
+  Pm1Cnt  = IoRead16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);\r
+\r
+  //\r
+  // If B_SLP_TYP is S5\r
+  //\r
+  if ((Pm1Sts & B_QNC_PM1BLK_PM1S_WAKE) != 0 && (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) == V_S5) {\r
+    IoWrite16 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, (Pm1Cnt & (~B_QNC_PM1BLK_PM1C_SLPTP)));\r
+    return  TRUE;\r
+  }\r
+\r
+  return  FALSE;\r
+}\r
+\r
+/**\r
+  This function is used to clear SMI and wake status.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCClearSmiAndWake (\r
+  VOID\r
+  )\r
+{\r
+  UINT32    Gpe0Sts;\r
+  UINT32    SmiSts;\r
+\r
+  //\r
+  // Read the ACPI registers\r
+  //\r
+  Gpe0Sts = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S);\r
+  SmiSts  = IoRead32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS);\r
+\r
+  //\r
+  // Clear any SMI or wake state from the boot\r
+  //\r
+  Gpe0Sts |= B_QNC_GPE0BLK_GPE0S_ALL;\r
+  SmiSts  |= B_QNC_GPE0BLK_SMIS_ALL;\r
+\r
+  //\r
+  // Write them back\r
+  //\r
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_GPE0S, Gpe0Sts);\r
+  IoWrite32 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS,  SmiSts);\r
+}\r
+\r
+/** Send DRAM Ready opcode.\r
+\r
+  @param[in]       OpcodeParam  Parameter to DRAM ready opcode.\r
+\r
+  @retval          VOID\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCSendOpcodeDramReady (\r
+  IN UINT32   OpcodeParam\r
+  )\r
+{\r
+\r
+  //\r
+  // Before sending DRAM ready place invalid value in Scrub Config.\r
+  //\r
+  QNCPortWrite (\r
+    QUARK_NC_RMU_SB_PORT_ID,\r
+    QUARK_NC_ECC_SCRUB_CONFIG_REG,\r
+    SCRUB_CFG_INVALID\r
+    );\r
+\r
+  //\r
+  // Send opcode and use param to notify HW of new RMU firmware location.\r
+  //\r
+  McD0PciCfg32 (QNC_ACCESS_PORT_MDR) = OpcodeParam;\r
+  McD0PciCfg32 (QNC_ACCESS_PORT_MCR) = MESSAGE_SHADOW_DW (QUARK_NC_RMU_SB_PORT_ID, 0);\r
+\r
+  //\r
+  // HW completed tasks on DRAM ready when scrub config read back as zero.\r
+  //\r
+  while (QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_ECC_SCRUB_CONFIG_REG) != 0) {\r
+    MicroSecondDelay (10);\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Relocate RMU Main binary to memory after MRC to improve performance.\r
+\r
+  @param[in]  DestBaseAddress  - Specify the new memory address for the RMU Main binary.\r
+  @param[in]  SrcBaseAddress   - Specify the current memory address for the RMU Main binary.\r
+  @param[in]  Size             - Specify size of the RMU Main binary.\r
+\r
+  @retval     VOID\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+RmuMainRelocation (\r
+  IN CONST UINT32   DestBaseAddress,\r
+  IN CONST UINT32   SrcBaseAddress,\r
+  IN CONST UINTN    Size\r
+  )\r
+{\r
+  //\r
+  // Shadow RMU Main binary into main memory.\r
+  //\r
+  CopyMem ((VOID *)(UINTN)DestBaseAddress,(VOID *)(UINTN) SrcBaseAddress, Size);\r
+}\r
+\r
+\r
+/**\r
+  Get the total memory size\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+QNCGetTotalMemorysize (\r
+  VOID\r
+  )\r
+{\r
+  return  QNCPortRead(QUARK_NC_HOST_BRIDGE_SB_PORT_ID, QUARK_NC_HOST_BRIDGE_HMBOUND_REG) & HMBOUND_MASK;\r
+}\r
+\r
+\r
+/**\r
+  Get the memory range of TSEG.\r
+  The TSEG's memory is below TOLM.\r
+\r
+  @param[out] BaseAddress The base address of TSEG's memory range\r
+  @param[out] MemorySize  The size of TSEG's memory range\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCGetTSEGMemoryRange (\r
+  OUT UINT64  *BaseAddress,\r
+  OUT UINT64  *MemorySize\r
+  )\r
+{\r
+  UINT64 Register = 0;\r
+  UINT64 SMMAddress = 0;\r
+\r
+  Register = QncHsmmcRead ();\r
+\r
+  //\r
+  // Get the SMRAM Base address\r
+  //\r
+  SMMAddress = Register & SMM_START_MASK;\r
+  *BaseAddress = LShift16 (SMMAddress);\r
+\r
+  //\r
+  // Get the SMRAM size\r
+  //\r
+  SMMAddress = ((Register & SMM_END_MASK) | (~SMM_END_MASK)) + 1;\r
+  *MemorySize = SMMAddress - (*BaseAddress);\r
+\r
+  DEBUG ((\r
+    EFI_D_INFO,\r
+    "TSEG's memory range: BaseAddress = 0x%x, Size = 0x%x\n",\r
+    (UINT32)*BaseAddress,\r
+    (UINT32)*MemorySize\r
+    ));\r
+}\r
+\r
+/**\r
+  Updates the PAM registers in the MCH for the requested range and mode.\r
+\r
+  @param   Start        The start address of the memory region\r
+  @param   Length       The length, in bytes, of the memory region\r
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable read for legacy memory section.\r
+                        If NULL, then read attribute will not be touched by this call.\r
+  @param   ReadEnable   Pointer to the boolean variable on whether to enable write for legacy memory section.\r
+                        If NULL, then write attribute will not be touched by this call.\r
+  @param   Granularity  A pointer to granularity, in bytes, that the PAM registers support\r
+\r
+  @retval  RETURN_SUCCESS            The PAM registers in the MCH were updated\r
+  @retval  RETURN_INVALID_PARAMETER  The memory range is not valid in legacy region.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+QNCLegacyRegionManipulation (\r
+  IN  UINT32                  Start,\r
+  IN  UINT32                  Length,\r
+  IN  BOOLEAN                 *ReadEnable,\r
+  IN  BOOLEAN                 *WriteEnable,\r
+  OUT UINT32                  *Granularity\r
+  )\r
+{\r
+  //\r
+  // Do nothing cos no such support on QNC\r
+  //\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+/**\r
+  Determine if QNC is supported.\r
+\r
+  @retval FALSE  QNC is not supported.\r
+  @retval TRUE   QNC is supported.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+IsQncSupported (\r
+  VOID\r
+  )\r
+{\r
+  UINT16  SocVendorId;\r
+  UINT16  SocDeviceId;\r
+\r
+  SocVendorId = MmioRead16 (\r
+                  PciDeviceMmBase (MC_BUS,\r
+                  MC_DEV,\r
+                  MC_FUN) + PCI_VENDOR_ID_OFFSET\r
+                  );\r
+\r
+  SocDeviceId = QncGetSocDeviceId();\r
+\r
+  //\r
+  // Verify that this is a supported chipset\r
+  //\r
+  if ((SocVendorId != QUARK_MC_VENDOR_ID) || ((SocDeviceId != QUARK_MC_DEVICE_ID) && (SocDeviceId != QUARK2_MC_DEVICE_ID))) {\r
+    DEBUG ((DEBUG_ERROR, "QNC code doesn't support the Soc VendorId:0x%04x Soc DeviceId:0x%04x!\n", SocVendorId, SocDeviceId));\r
+    return FALSE;\r
+  }\r
+  return TRUE;\r
+}\r
+\r
+/**\r
+  Get the DeviceId of the SoC\r
+\r
+  @retval PCI DeviceId of the SoC\r
+**/\r
+UINT16\r
+EFIAPI\r
+QncGetSocDeviceId (\r
+  VOID\r
+  )\r
+{\r
+  UINT16  SocDeviceId;\r
+\r
+  SocDeviceId = MmioRead16 (\r
+                  PciDeviceMmBase (\r
+                    MC_BUS,\r
+                    MC_DEV,\r
+                    MC_FUN\r
+                    ) + PCI_DEVICE_ID_OFFSET\r
+                  );\r
+\r
+  return SocDeviceId;\r
+}\r
+\r
+/**\r
+  Enable SMI detection of legacy flash access violations.\r
+**/\r
+VOID\r
+EFIAPI\r
+QncEnableLegacyFlashAccessViolationSmi (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  BcValue;\r
+\r
+  BcValue = LpcPciCfg32 (R_QNC_LPC_BIOS_CNTL);\r
+\r
+  //\r
+  // Clear BIOSWE & set BLE.\r
+  //\r
+  BcValue &= (~B_QNC_LPC_BIOS_CNTL_BIOSWE);\r
+  BcValue |= (B_QNC_LPC_BIOS_CNTL_BLE);\r
+\r
+  LpcPciCfg32 (R_QNC_LPC_BIOS_CNTL) = BcValue;\r
+\r
+  DEBUG ((EFI_D_INFO, "BIOS Control Lock Enabled!\n"));\r
+}\r
+\r
+/**\r
+  Setup RMU Thermal sensor registers for Vref mode.\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorSetVRefMode (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                             Tscgf1Config;\r
+  UINT32                             Tscgf2Config;\r
+  UINT32                             Tscgf2Config2;\r
+\r
+  Tscgf1Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG);\r
+  Tscgf2Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG);\r
+  Tscgf2Config2 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCURRENTSEL_VREF_MODE << B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGEN);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGEN_VREF_MODE << B_TSCGF1_CONFIG_IBGEN_BP);\r
+\r
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ISPARECTRL_MASK);\r
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ISPARECTRL_VREF_MODE << B_TSCGF2_CONFIG2_ISPARECTRL_BP);\r
+\r
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK);\r
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCOARSETUNE_VREF_MODE << B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP);\r
+\r
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSCONTROL_MASK);\r
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSCONTROL_VREF_MODE << B_TSCGF2_CONFIG_IDSCONTROL_BP);\r
+\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG, Tscgf1Config);\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG, Tscgf2Config);\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2, Tscgf2Config2);\r
+}\r
+\r
+/**\r
+  Setup RMU Thermal sensor registers for Ratiometric mode.\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorSetRatiometricMode (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                             Tscgf1Config;\r
+  UINT32                             Tscgf2Config;\r
+  UINT32                             Tscgf2Config2;\r
+  UINT32                             Tscgf3Config;\r
+\r
+  Tscgf1Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG);\r
+  Tscgf2Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG);\r
+  Tscgf2Config2 = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2);\r
+  Tscgf3Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCURRENTSEL_MASK);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCURRENTSEL_RATIO_MODE << B_TSCGF1_CONFIG_ISNSCURRENTSEL_BP);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSCHOPSEL_MASK);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSCHOPSEL_RATIO_MODE  << B_TSCGF1_CONFIG_ISNSCHOPSEL_BP);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_ISNSINTERNALVREFEN);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_ISNSINTERNALVREFEN_RATIO_MODE << B_TSCGF1_CONFIG_ISNSINTERNALVREFEN_BP);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGEN);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGEN_RATIO_MODE << B_TSCGF1_CONFIG_IBGEN_BP);\r
+\r
+  Tscgf1Config &= ~(B_TSCGF1_CONFIG_IBGCHOPEN);\r
+  Tscgf1Config |= (V_TSCGF1_CONFIG_IBGCHOPEN_RATIO_MODE << B_TSCGF1_CONFIG_IBGCHOPEN_BP);\r
+\r
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCONFIGSEL_MASK);\r
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCONFIGSEL_RATIO_MODE << B_TSCGF2_CONFIG2_ICALCONFIGSEL_BP);\r
+\r
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ISPARECTRL_MASK);\r
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ISPARECTRL_RATIO_MODE << B_TSCGF2_CONFIG2_ISPARECTRL_BP);\r
+\r
+  Tscgf2Config2 &= ~(B_TSCGF2_CONFIG2_ICALCOARSETUNE_MASK);\r
+  Tscgf2Config2 |= (V_TSCGF2_CONFIG2_ICALCOARSETUNE_RATIO_MODE << B_TSCGF2_CONFIG2_ICALCOARSETUNE_BP);\r
+\r
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSCONTROL_MASK);\r
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSCONTROL_RATIO_MODE << B_TSCGF2_CONFIG_IDSCONTROL_BP);\r
+\r
+  Tscgf2Config &= ~(B_TSCGF2_CONFIG_IDSTIMING_MASK);\r
+  Tscgf2Config |= (V_TSCGF2_CONFIG_IDSTIMING_RATIO_MODE << B_TSCGF2_CONFIG_IDSTIMING_BP);\r
+\r
+  Tscgf3Config &= ~(B_TSCGF3_CONFIG_ITSGAMMACOEFF_MASK);\r
+  Tscgf3Config |= (V_TSCGF3_CONFIG_ITSGAMMACOEFF_RATIO_MODE << B_TSCGF3_CONFIG_ITSGAMMACOEFF_BP);\r
+\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF1_CONFIG, Tscgf1Config);\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG, Tscgf2Config);\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF2_CONFIG2, Tscgf2Config2);\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, Tscgf3Config);\r
+}\r
+\r
+/**\r
+  Setup RMU Thermal sensor trip point values.\r
+\r
+  @param[in]  CatastrophicTripOnDegreesCelsius  - Catastrophic set trip point threshold.\r
+  @param[in]  HotTripOnDegreesCelsius           - Hot set trip point threshold.\r
+  @param[in]  HotTripOffDegreesCelsius          - Hot clear trip point threshold.\r
+\r
+  @retval  EFI_SUCCESS            Trip points setup.\r
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+QNCThermalSensorSetTripValues (\r
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius,\r
+  IN  CONST UINTN             HotTripOnDegreesCelsius,\r
+  IN  CONST UINTN             HotTripOffDegreesCelsius\r
+  )\r
+{\r
+  UINT32 RegisterValue;\r
+\r
+  //\r
+  // Register fields are 8-bit temperature values of granularity 1 degree C\r
+  // where 0x00 corresponds to -50 degrees C\r
+  // and 0xFF corresponds to 205 degrees C.\r
+  //\r
+  // User passes unsigned values in degrees Celsius so trips < 0 not supported.\r
+  //\r
+  // Add 50 to user values to get values for register fields.\r
+  //\r
+\r
+  if ((CatastrophicTripOnDegreesCelsius > 205) || (HotTripOnDegreesCelsius > 205) || (HotTripOffDegreesCelsius > 205)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Set new values.\r
+  //\r
+  RegisterValue =\r
+    ((0 + 50) << TS_CAT_TRIP_CLEAR_THOLD_BP) | // Cat Trip Clear value must be less than Cat Trip Set Value.\r
+    ((CatastrophicTripOnDegreesCelsius + 50) << TS_CAT_TRIP_SET_THOLD_BP) |\r
+    ((HotTripOnDegreesCelsius + 50) << TS_HOT_TRIP_SET_THOLD_BP) |\r
+    ((HotTripOffDegreesCelsius + 50) << TS_HOT_TRIP_CLEAR_THOLD_BP)\r
+    ;\r
+\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP, RegisterValue);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Enable RMU Thermal sensor with a Catastrophic Trip point.\r
+\r
+  @retval  EFI_SUCCESS            Trip points setup.\r
+  @retval  EFI_INVALID_PARAMETER  Invalid trip point value.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+QNCThermalSensorEnableWithCatastrophicTrip (\r
+  IN  CONST UINTN             CatastrophicTripOnDegreesCelsius\r
+  )\r
+{\r
+  UINT32                             Tscgf3Config;\r
+  UINT32                             TsModeReg;\r
+  UINT32                             TsTripReg;\r
+\r
+  //\r
+  // Trip Register fields are 8-bit temperature values of granularity 1 degree C\r
+  // where 0x00 corresponds to -50 degrees C\r
+  // and 0xFF corresponds to 205 degrees C.\r
+  //\r
+  // User passes unsigned values in degrees Celsius so trips < 0 not supported.\r
+  //\r
+  // Add 50 to user values to get values for register fields.\r
+  //\r
+\r
+  if (CatastrophicTripOnDegreesCelsius > 205) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Tscgf3Config = QNCAltPortRead (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG);\r
+  TsModeReg = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_MODE);\r
+  TsTripReg = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP);\r
+\r
+  //\r
+  // Setup Catastrophic Trip point.\r
+  //\r
+  TsTripReg &= ~(TS_CAT_TRIP_SET_THOLD_MASK);\r
+  TsTripReg |= ((CatastrophicTripOnDegreesCelsius + 50) << TS_CAT_TRIP_SET_THOLD_BP);\r
+  TsTripReg &= ~(TS_CAT_TRIP_CLEAR_THOLD_MASK);\r
+  TsTripReg |= ((0 + 50) << TS_CAT_TRIP_CLEAR_THOLD_BP);  // Cat Trip Clear value must be less than Cat Trip Set Value.\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_TRIP, TsTripReg);\r
+\r
+  //\r
+  // To enable the TS do the following:\r
+  //    1)  Take the TS out of reset by setting itsrst to 0x0.\r
+  //    2)  Enable the TS using RMU Thermal sensor mode register.\r
+  //\r
+\r
+  Tscgf3Config &= ~(B_TSCGF3_CONFIG_ITSRST);\r
+  TsModeReg |= TS_ENABLE;\r
+\r
+  QNCAltPortWrite (QUARK_SCSS_SOC_UNIT_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_TSCGF3_CONFIG, Tscgf3Config);\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_TS_MODE, TsModeReg);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Lock all RMU Thermal sensor control & trip point registers.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCThermalSensorLockAllRegisters (\r
+  VOID\r
+  )\r
+{\r
+  UINT32                             RegValue;\r
+  UINT32                             LockMask;\r
+\r
+  LockMask = TS_LOCK_THRM_CTRL_REGS_ENABLE | TS_LOCK_AUX_TRIP_PT_REGS_ENABLE;\r
+\r
+  RegValue = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG);\r
+  RegValue |= LockMask;\r
+  QNCPortWrite (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG, RegValue);\r
+\r
+  ASSERT ((LockMask == (QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_CONFIG) & LockMask)));\r
+}\r
+\r
+/**\r
+  Set chipset policy for double bit ECC error.\r
+\r
+  @param[in]       PolicyValue  Policy to config on double bit ECC error.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+QNCPolicyDblEccBitErr (\r
+  IN  CONST UINT32                        PolicyValue\r
+  )\r
+{\r
+  UINT32 Register;\r
+  Register = QNCPortRead (QUARK_NC_RMU_SB_PORT_ID, QUARK_NC_RMU_REG_WDT_CONTROL);\r
+  Register &= ~(B_WDT_CONTROL_DBL_ECC_BIT_ERR_MASK);\r
+  Register |= PolicyValue;\r
+  QNCPortWrite (\r
+    QUARK_NC_RMU_SB_PORT_ID,\r
+    QUARK_NC_RMU_REG_WDT_CONTROL,\r
+    Register\r
+    );\r
+}\r
+\r
+/**\r
+  Determine if running on secure Quark hardware Sku.\r
+\r
+  @retval FALSE  Base Quark Sku or unprovisioned Secure Sku running.\r
+  @retval TRUE   Provisioned SecureSku hardware running.\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+QncIsSecureProvisionedSku (\r
+  VOID\r
+  )\r
+{\r
+  // Read QUARK Secure SKU Fuse\r
+  return ((QNCAltPortRead (QUARK_SCSS_FUSE_SB_PORT_ID, QUARK_SCSS_SOC_UNIT_SPI_ROM_FUSE) & BIT6) == BIT6);\r
+}\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf b/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/IntelQNCLib.inf
new file mode 100644 (file)
index 0000000..691a7e4
--- /dev/null
@@ -0,0 +1,63 @@
+## @file\r
+# Intel QNC Library Instance\r
+#\r
+# Intel QNC Library Instance\r
+#\r
+# Copyright (c) 2013-2015 Intel Corporation.\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = IntelQNCLib\r
+  FILE_GUID                      = F5B2EA6C-8148-4a4e-88EA-38A4A51F389F\r
+  MODULE_TYPE                    = BASE\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = IntelQNCLib\r
+\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  PciExpress.c\r
+  IntelQNCLib.c\r
+  CommonHeader.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  QuarkSocPkg/QuarkSocPkg.dec\r
+\r
+[LibraryClasses]\r
+  TimerLib\r
+  DebugLib\r
+  PcdLib\r
+  PciLib\r
+  IoLib\r
+  PciCf8Lib\r
+  BaseLib\r
+  CpuLib\r
+  QNCAccessLib\r
+\r
+[Pcd]\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPm1blkIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGbaIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdGpe0blkIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPmbaIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdSmbaIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdWdtbaIoBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdRcbaMmioBaseAddress\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdDeviceEnables\r
+  gEfiQuarkNcSocIdTokenSpaceGuid.PcdPcieRootPortConfiguration\r
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c b/QuarkSocPkg/QuarkNorthCluster/Library/IntelQNCLib/PciExpress.c
new file mode 100644 (file)
index 0000000..5cb0fb8
--- /dev/null
@@ -0,0 +1,949 @@
+/** @file\r
+QNC PCI Express initialization entry\r
+\r
+Copyright (c) 2013-2015 Intel Corporation.\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "CommonHeader.h"\r
+\r
+#define PCIEXP_ROOT_PORT_URE_ENABLE    BIT0   //  unsupported request reporting enable\r
+#define PCIEXP_ROOT_PORT_FEE_ENABLE    BIT1   //  Fatal Error Reporting Enable\r
+#define PCIEXP_ROOT_PORT_NFE_ENABLE    BIT2   //  Non-Fatal Error Reporting Enable\r
+#define PCIEXP_ROOT_PORT_CEE_ENABLE    BIT3   //  Correctable Error Reporting Enable\r
+#define PCIEXP_ROOT_PORT_SFE_ENABLE    BIT4   //  System Error on Fatal Error Enable\r
+#define PCIEXP_ROOT_PORT_SNE_ENABLE    BIT5   //  System Error on Non-Fatal Error Enable\r
+#define PCIEXP_ROOT_PORT_SCE_ENABLE    BIT6   //  System Error on Correctable Error Enable\r
+\r
+EFI_STATUS\r
+PcieStall (\r
+  IN UINTN              Microseconds\r
+  )\r
+{\r
+  MicroSecondDelay (Microseconds);\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Find the Offset to a given Capabilities ID\r
+    CAPID list:\r
+      0x01 = PCI Power Management Interface\r
+      0x04 = Slot Identification\r
+      0x05 = MSI Capability\r
+      0x10 = PCI Express Capability\r
+\r
+  @param[in]  Bus                     Bus number of the interested device\r
+  @param[in]  Device                  Device number of the interested device\r
+  @param[in]  Function                Function number of the interested device\r
+  @param[in]  CapId                   Capability ID to be scanned\r
+\r
+  @retval Offset of desired CAPID\r
+\r
+**/\r
+UINT32\r
+PcieFindCapId (\r
+  UINT8   Bus,\r
+  UINT8   Device,\r
+  UINT8   Function,\r
+  UINT8   CapId\r
+  )\r
+{\r
+  UINT8    CapHeader;\r
+\r
+  //\r
+  // Always start at Offset 0x34\r
+  //\r
+  CapHeader = QNCMmPci8 (0, Bus, Device, Function, R_QNC_PCIE_CAP_PTR);\r
+\r
+  if (CapHeader == 0xFF) {\r
+     return 0;\r
+  }\r
+\r
+  while (CapHeader != 0) {\r
+    if (QNCMmPci8 (0, Bus, Device, Function, CapHeader) == CapId) {\r
+      return CapHeader;\r
+    }\r
+    CapHeader = QNCMmPci8 (0, Bus, Device, Function, CapHeader + 1);\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+\r
+  Search and return the offset of desired Pci Express Capability ID\r
+    CAPID list:\r
+      0x0001 = Advanced Error Rreporting Capability\r
+      0x0002 = Virtual Channel Capability\r
+      0x0003 = Device Serial Number Capability\r
+      0x0004 = Power Budgeting Capability\r
+\r
+  @param[in]  Bus                     Bus number of the interested device\r
+  @param[in]  Device                  Device number of the interested device\r
+  @param[in]  Function                Function number of the interested device\r
+  @param[in]  CapId                   Capability ID to be scanned\r
+\r
+  @retval Offset of desired CAPID\r
+\r
+**/\r
+UINT32\r
+PcieFindExtendedCapId (\r
+  UINT8   Bus,\r
+  UINT8   Device,\r
+  UINT8   Function,\r
+  UINT16  CapId\r
+  )\r
+{\r
+  UINT16    CapHeaderOffset;\r
+  UINT16    CapHeaderId;\r
+\r
+  // Start to search at Offset 0x100\r
+  // Get Capability Header\r
+  CapHeaderId = 0;\r
+  CapHeaderOffset = PCIE_CAP_EXT_HEARDER_OFFSET;\r
+\r
+  while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {\r
+    CapHeaderId = QNCMmPci16 (0, Bus, Device, Function, CapHeaderOffset);\r
+    if (CapHeaderId == CapId) {\r
+      return CapHeaderOffset;\r
+    }\r
+    CapHeaderOffset = (QNCMmPci16 (0, Bus, Device, Function, CapHeaderOffset + 2) >> 4);\r
+  }\r
+  return 0;\r
+}\r
+\r
+/**\r
+\r
+  Map Vc on both root port and downstream device\r
+\r
+  @param[in]  Bus1                    Bus number of the root port\r
+  @param[in]  Device1                 Device number of the root port\r
+  @param[in]  Function1               Function number of the root port\r
+  @param[in]  Bus2                    Bus number of the downstream device\r
+  @param[in]  Device2                 Device number of the downstream device\r
+  @param[in]  Function2               Function number of the downstream device\r
+\r
+  @retval EFI_SUCCESS    Map Vc successful\r
+\r
+**/\r
+EFI_STATUS\r
+PcieInitTcxVc0 (\r
+  IN UINT8   Bus1,\r
+  IN UINT8   Device1,\r
+  IN UINT8   Function1,\r
+  IN UINT8   Bus2,\r
+  IN UINT8   Device2,\r
+  IN UINT8   Function2\r
+  )\r
+{\r
+  UINT32  Offset;\r
+\r
+  //\r
+  // Initialize TCx-VC0 value on the port to only use TC0\r
+  //\r
+  Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);\r
+  if (Offset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  QNCMmPci8AndThenOr (0, Bus1, Device1, Function1, (Offset + PCIE_SLOT_CAP_OFFSET), ~0xF, 1);\r
+\r
+  // Set TCx-VC0 value on the Endpoint\r
+\r
+  Offset = PcieFindExtendedCapId (Bus2, Device2, Function2, 2);\r
+  if (Offset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  QNCMmPci8AndThenOr (0, Bus2, Device2, Function2, (Offset + PCIE_SLOT_CAP_OFFSET), ~0xF, 1);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Map Traffic Class x to Vc0 on both root port and downstream device\r
+\r
+  @param[in]  Bus1                    Bus number of the root port\r
+  @param[in]  Device1                 Device number of the root port\r
+  @param[in]  Function1               Function number of the root port\r
+  @param[in]  Bus2                    Bus number of the downstream device\r
+  @param[in]  Device2                 Device number of the downstream device\r
+  @param[in]  Function2               Function number of the downstream device\r
+  @param[in]  TCx                     Traffic Class to be mapped to vc0\r
+\r
+  @retval EFI_SUCCESS    Map Tcx to Vc0 successful\r
+\r
+**/\r
+EFI_STATUS\r
+PcieMapTcxVc0 (\r
+  IN UINT8   Bus1,\r
+  IN UINT8   Device1,\r
+  IN UINT8   Function1,\r
+  IN UINT8   Bus2,\r
+  IN UINT8   Device2,\r
+  IN UINT8   Function2,\r
+  IN UINT8   TCx\r
+  )\r
+{\r
+  UINT32  Offset;\r
+\r
+  //\r
+  // Set TCx-VC0 value on the port\r
+  //\r
+\r
+  Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);\r
+  if (Offset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  QNCMmPci8 (0, Bus1, Device1, Function1, (Offset + PCIE_SLOT_CAP_OFFSET)) = (UINT8)(1 << TCx);\r
+\r
+  // Set TCx-VC0 value on the Endpoint\r
+\r
+  Offset = PcieFindExtendedCapId (Bus2, Device2, Function2, 2);\r
+  if (Offset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+  QNCMmPci8 (0, Bus2, Device2, Function2, (Offset + PCIE_SLOT_CAP_OFFSET)) = (UINT8)(1 << TCx);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Set common clock for both root port and downstream device.\r
+\r
+  @param[in]  Bus1                    Bus number of the root port\r
+  @param[in]  Device1                 Device number of the root port\r
+  @param[in]  Function1               Function number of the root port\r
+  @param[in]  Bus2                    Device number of the downstream device\r
+  @param[in]  Device2                 Function number of the downstream device\r
+\r
+  @retval EFI_SUCCESS    Set common clock successful\r
+\r
+**/\r
+EFI_STATUS\r
+PcieSetCommonClock (\r
+  IN UINT8   Bus1,\r
+  IN UINT8   Device1,\r
+  IN UINT8   Function1,\r
+  IN UINT8   Bus2,\r
+  IN UINT8   Device2\r
+ )\r
+{\r
+  UINT32      CapOffset1;\r
+  UINT32      CapOffset2;\r
+  UINT8       Function2;\r
+  UINT8       CommonClock;\r
+  EFI_STATUS  Status;\r
+\r
+  //\r
+  // Get the pointer to the Port PCI Express Capability Structure.\r
+  //\r
+  CommonClock = 0;\r
+  CapOffset1 = PcieFindCapId (Bus1, Device1, Function1, PCIE_CAPID);\r
+  if (CapOffset1 == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Step 1\r
+  // Read the Slot Clock Configuration bit of the Link status register of the root port and the endpoint device connected to the port\r
+  // If both components have this bit set to 1, then System BIOS should set the "Common Clock Configuration" bit in the Link Control Registers\r
+  // for both components at both sides of the link to indicate that components at both ends\r
+  // of the link use a common clock source\r
+  //\r
+\r
+  //\r
+  // Check the Port Slot Clock Configuration Bit.\r
+  //\r
+  if ((QNCMmPci16 (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_SCC) == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  for (Function2 = 0; Function2 < 8; Function2++) {\r
+    //\r
+    // Check the Endpoint Slot Clock Configuration Bit.\r
+    //\r
+    CapOffset2 = PcieFindCapId (Bus2, Device2, Function2, PCIE_CAPID);\r
+    if ((CapOffset2 != 0) &&\r
+       ((QNCMmPci16 (0, Bus2, Device2, Function2, (CapOffset2 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_SCC) != 0)) {\r
+\r
+      //\r
+      // Common clock is supported, set common clock bit on root port\r
+      // and the endpoint\r
+      //\r
+      if (CommonClock == 0) {\r
+        QNCMmPci8Or (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_CCC);\r
+        CommonClock++;\r
+      }\r
+      QNCMmPci8Or (0, Bus2, Device2, Function2, (CapOffset2 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_CCC);\r
+    }\r
+  }\r
+\r
+  //\r
+  // Step 2   If the Common Clock Configuration bit was changed by BIOS in step 1,\r
+  // System BIOS should initiate a link training by setting the Retrain Link bit\r
+  // in the Link Control register of the root port (D28:F0/F1 offset\r
+  // 50h [5]) to "1b" and then poll the Link Training bit in the Link Status\r
+  // register of the root port (D28:F0/F1/F2/F3/F4/F5 offset 52h [11]) until it is\r
+  // "0b".\r
+  //\r
+  if (CommonClock == 0) {\r
+    Status = EFI_UNSUPPORTED;\r
+  } else {\r
+    //\r
+    // Retrain the Link per PCI Express Specification.\r
+    //\r
+    QNCMmPci8Or (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_CNT_OFFSET), B_QNC_PCIE_LCTL_RL);\r
+\r
+    //\r
+    // Wait until Re-Training has completed.\r
+    //\r
+    while ((QNCMmPci16 (0, Bus1, Device1, Function1, (CapOffset1 + PCIE_LINK_STS_OFFSET)) & B_QNC_PCIE_LSTS_LT) != 0);\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+\r
+  Enables the CLKREQ# PM on all the end point functions\r
+\r
+  @param[in]  Bus                Bus number of the downstream device\r
+  @param[in]  Device             Device number of the downstream device\r
+\r
+  @retval None\r
+\r
+**/\r
+VOID\r
+PcieSetClkreq (\r
+  IN  UINT8   Bus,\r
+  IN  UINT8   Device\r
+ )\r
+{\r
+  UINT8  Function;\r
+  UINT32 CapOffset;\r
+\r
+  //\r
+  // Parse thro all the functions of the endpoint and find the PCIe Cap ID (offset 10h) and if\r
+  // exists then enable the CLKREQ# bit (BIT8) on that function\r
+  //\r
+  for (Function = 0; Function < 8; Function++) {\r
+    //\r
+    // Find the PCIe Cap Id (offset 10h)\r
+    //\r
+    CapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);\r
+    if (CapOffset == 0) {\r
+       continue;\r
+    }\r
+\r
+    //\r
+    // Check if CLKREQ# is supported by the endpoints\r
+    //\r
+    if ((QNCMmPci32 (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CAP_OFFSET))\r
+      & B_QNC_PCIE_LCAP_CPM) != B_QNC_PCIE_LCAP_CPM) {\r
+      //\r
+      // CLKREQ# is not supported so dont do anything\r
+      //\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Now enable the CLKREQ#\r
+  //\r
+  for (Function = 0; Function < 8; Function++) {\r
+    //\r
+    // Find the PCIe Cap Id (offset 10h)\r
+    //\r
+    CapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);\r
+    if (CapOffset == 0) {\r
+       continue;\r
+    }\r
+\r
+    QNCMmPci16Or (0, Bus, Device, Function, (CapOffset + PCIE_LINK_CNT_OFFSET), BIT8);\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Configure ASPM automatically for both root port and downstream device.\r
+\r
+  @param[in]  RootBus                    Bus number of the root port\r
+  @param[in]  RootDevice                 Device number of the root port\r
+  @param[in]  RootFunction               Function number of the root port\r
+  @param[in]  EndpointBus                Bus number of the downstream device\r
+  @param[in]  EndpointDevice             Device number of the downstream device\r
+  @param[in]  EndpointFunction           Function number of the downstream device\r
+  @param[in]  LinkAspmVal                Currently used ASPM setting\r
+\r
+  @retval EFI_SUCCESS    Configure ASPM successful\r
+\r
+**/\r
+EFI_STATUS\r
+PcieSetAspmAuto (\r
+  IN  UINT8   RootBus,\r
+  IN  UINT8   RootDevice,\r
+  IN  UINT8   RootFunction,\r
+  IN  UINT8   EndpointBus,\r
+  IN  UINT8   EndpointDevice,\r
+  IN  UINT8   EndpointFunction,\r
+  OUT UINT16  *LinkAspmVal\r
+ )\r
+{\r
+  UINT32    RootPcieCapOffset;\r
+  UINT32    EndpointPcieCapOffset;\r
+  UINT16    RootPortAspm;\r
+  UINT16    EndPointAspm;\r
+  UINT16    EndPointVendorId;\r
+  UINT16    EndPointDeviceId;\r
+  UINT8     EndPointRevId;\r
+  UINT16    AspmVal;\r
+  UINT32    PortLxLat;\r
+  UINT32    EndPointLxLat;\r
+  UINT32    LxLat;\r
+\r
+  //\r
+  // Get the pointer to the Port PCI Express Capability Structure.\r
+  //\r
+  RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, PCIE_CAPID);\r
+  if (RootPcieCapOffset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Get the pointer to the Endpoint PCI Express Capability Structure.\r
+  //\r
+  EndpointPcieCapOffset = PcieFindCapId (EndpointBus, EndpointDevice, EndpointFunction, PCIE_CAPID);\r
+  if (EndpointPcieCapOffset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Obtain initial ASPM settings from respective port capability registers.\r
+  //\r
+  RootPortAspm  = (QNCMmPci16 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;\r
+\r
+  //\r
+  // Configure downstream device if present.\r
+  //\r
+  EndPointAspm  = (QNCMmPci16 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;\r
+\r
+  //\r
+  // Mask APMC with values from lookup table.\r
+  // RevID of 0xFF applies to all steppings.\r
+  //\r
+\r
+  EndPointVendorId = QNCMmPci16 (0, EndpointBus, EndpointDevice, EndpointFunction, 0);\r
+  EndPointDeviceId = QNCMmPci16 (0, EndpointBus, EndpointDevice, EndpointFunction, 2);\r
+  EndPointRevId    = QNCMmPci8 (0, EndpointBus, EndpointDevice, EndpointFunction, 8);\r
+\r
+  // TODO: Mask with latency/acceptable latency comparison results.\r
+\r
+  AspmVal = RootPortAspm;\r
+  if (RootPortAspm > EndPointAspm) {\r
+    AspmVal = EndPointAspm;\r
+  }\r
+\r
+  //\r
+  // Check if L1 should be enabled based on port and endpoint L1 exit latency.\r
+  //\r
+  if(AspmVal & BIT1) {\r
+    PortLxLat      = QNCMmPci32 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL1_MASK;\r
+    EndPointLxLat  = QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL1_MASK;\r
+\r
+    LxLat = PortLxLat;\r
+    if(PortLxLat < EndPointLxLat) {\r
+      LxLat = EndPointLxLat;\r
+    }\r
+\r
+    //\r
+    // check if the value is bigger than endpoint L1 acceptable exit latency, if it is\r
+    // larger than accepted value, then we should disable L1\r
+    //\r
+    LxLat >>= 6;\r
+    if(LxLat > (QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_DEV_CAP_OFFSET)) & B_QNC_PCIE_DCAP_E1AL)) {\r
+      AspmVal &= ~BIT1;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Check if L0s should be enabled based on port and endpoint L0s exit latency.\r
+  //\r
+  if(AspmVal & BIT0) {\r
+    PortLxLat      = QNCMmPci32 (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset+ PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL0_MASK;\r
+    EndPointLxLat  = QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_EL0_MASK;\r
+\r
+    LxLat = PortLxLat;\r
+    if(PortLxLat < EndPointLxLat) {\r
+      LxLat = EndPointLxLat;\r
+    }\r
+\r
+    //\r
+    // check if the value is bigger than endpoint L0s acceptable exit latency, if it is\r
+    // larger than accepted value, then we should disable L0s\r
+    //\r
+    LxLat >>= 6;\r
+    if(LxLat > (QNCMmPci32 (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_DEV_CAP_OFFSET)) & B_QNC_PCIE_DCAP_E0AL)) {\r
+      AspmVal &= ~BIT0;\r
+    }\r
+  }\r
+\r
+  RootPortAspm = AspmVal;\r
+\r
+  *LinkAspmVal = AspmVal;\r
+  //\r
+  // Set Endpoint Aspm\r
+  //\r
+  QNCMmPci16AndThenOr (0, EndpointBus, EndpointDevice, EndpointFunction, (EndpointPcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, AspmVal);\r
+\r
+\r
+  //\r
+  // Set Root Port Aspm\r
+  //\r
+  QNCMmPci16AndThenOr (0, RootBus, RootDevice, RootFunction, (RootPcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, RootPortAspm);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Configure ASPM based on the given setting for the interested device.\r
+\r
+  @param[in]  Bus                    Bus number of the interested device\r
+  @param[in]  Device                 Device number of the interested device\r
+  @param[in]  Function               Function number of the interested device\r
+  @param[in]  AspmSetting            Aspm setting\r
+  @param[in]  LinkAspmVal            Currently used ASPM setting\r
+\r
+  @retval EFI_SUCCESS    Configure ASPM successful\r
+\r
+**/\r
+EFI_STATUS\r
+PcieSetAspmManual (\r
+  IN  UINT8   Bus,\r
+  IN  UINT8   Device,\r
+  IN  UINT8   Function,\r
+  IN  UINT8   AspmSetting,\r
+  OUT UINT16  *LinkAspmVal\r
+ )\r
+{\r
+  UINT32    PcieCapOffset;\r
+  UINT16    PortAspm;\r
+\r
+  //\r
+  // Get the pointer to the Port PCI Express Capability Structure.\r
+  //\r
+  PcieCapOffset = PcieFindCapId (Bus, Device, Function, PCIE_CAPID);\r
+  if (PcieCapOffset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  // Read the Link Capability register's ASPM setting\r
+  PortAspm = (QNCMmPci16 (0, Bus, Device, Function, (PcieCapOffset + PCIE_LINK_CAP_OFFSET)) & B_QNC_PCIE_LCAP_APMS_MASK) >> V_QNC_PCIE_LCAP_APMS_OFFSET;\r
+  // Mask it with the Setup selection\r
+  PortAspm &= AspmSetting;\r
+\r
+  *LinkAspmVal = PortAspm;\r
+  // Write it to the Link Control register\r
+  QNCMmPci16AndThenOr (0, Bus, Device, Function, (PcieCapOffset + PCIE_LINK_CNT_OFFSET), 0xFFFC, PortAspm);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+\r
+  Perform Initialization on one PCI Express root port.\r
+\r
+  @param[in]  RootPortIndex          Index of PCI Express root port\r
+  @param[in]  RootPortConfig         Pointer to the given pcie root port configuration\r
+  @param[in]  PciExpressBar          Base address of pcie space\r
+  @param[in]  QNCRootComplexBar       Base address of root complex\r
+  @param[in]  QNCPmioBase             Base address of PM IO space\r
+  @param[in]  QNCGpeBase              Base address of gpe IO space\r
+\r
+  @retval EFI_SUCCESS    Initialization successful\r
+\r
+**/\r
+EFI_STATUS\r
+QNCRootPortInit (\r
+  IN UINT32                                    RootPortIndex,\r
+  IN PCIEXP_ROOT_PORT_CONFIGURATION            *RootPortConfig,\r
+  IN UINT64                                    PciExpressBar,\r
+  IN UINT32                                    QNCRootComplexBar,\r
+  IN UINT32                                    QNCPmioBase,\r
+  IN UINT32                                    QNCGpeBase\r
+  )\r
+{\r
+  UINT64            RPBase;\r
+  UINT64            EndPointBase;\r
+  UINT64            LpcBase;\r
+  UINT16            AspmVal;\r
+  UINT16            SlotStatus;\r
+  UINTN             Index;\r
+  UINT32            CapOffset;\r
+  UINT32            DwordReg;\r
+\r
+  RPBase = PciExpressBar + (((PCI_BUS_NUMBER_QNC << 8) + ((PCI_DEVICE_NUMBER_PCIE_ROOTPORT) << 3) + ((PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex) << 0)) << 12);\r
+  LpcBase = PciExpressBar + (((PCI_BUS_NUMBER_QNC << 8) + (31 << 3) + (0 << 0)) << 12);\r
+  CapOffset = PcieFindCapId (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), PCIE_CAPID);\r
+\r
+  if (CapOffset == 0) {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // Initialize "Slot Implmemented Bit" for this root port\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.SlotImplemented) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_XCAP, B_QNC_PCIE_XCAP_SI);\r
+  }\r
+\r
+  //\r
+  // For Root Port Slots Numbering on the CRBs.\r
+  //  Root Port 0 = Slot 1\r
+  //  Root Port 1 = Slot 2\r
+  //  Root Port 2 = Slot 3\r
+  //  Root Port 3 = Slot 4\r
+  //\r
+  DwordReg = QNCMmio32 (RPBase, R_QNC_PCIE_SLCAP);\r
+  DwordReg &= B_QNC_PCIE_SLCAP_MASK_RSV_VALUE;\r
+  DwordReg |= (V_QNC_PCIE_SLCAP_SLV << V_QNC_PCIE_SLCAP_SLV_OFFSET);\r
+  DwordReg |= ((RootPortConfig[RootPortIndex].Bits.PhysicalSlotNumber) << V_QNC_PCIE_SLCAP_PSN_OFFSET) ;\r
+  QNCMmio32 (RPBase, R_QNC_PCIE_SLCAP) = DwordReg;\r
+\r
+  //\r
+  // Check for a Presence Detect Change.\r
+  //\r
+  SlotStatus = QNCMmio16 (RPBase, R_QNC_PCIE_SLSTS);\r
+  if ((SlotStatus & (B_QNC_PCIE_SLSTS_PDS + B_QNC_PCIE_SLSTS_PDC)) == 0) {\r
+    return EFI_NOT_FOUND;\r
+  }\r
+\r
+  //\r
+  // Temporarily Hardcode the Root Port Bridge Number to 2.\r
+  //\r
+  // This Endpoint check should immediately pass.  Howerver, a 900ms delay\r
+  // has been added to match the timing requirements of the PCI Express Base\r
+  // Specification, Revision 1.0A, Section 6.6 ("...software must allow 1.0s\r
+  // after a reset of a device, before it may determine that a device which\r
+  // fails to return a Successful Completion status for a valid Configuration\r
+  // Request is a broken device").  Note that a 100ms delay was already added\r
+  // after the Root Ports were first taken out of reset.\r
+  //\r
+  QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF, 0x00020200);\r
+  //\r
+  // Only do this when a downstream device is present\r
+  //\r
+  EndPointBase = PciExpressBar + (((2 << 8) + (0 << 3) + (0 << 0)) << 12);\r
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {\r
+    for (Index = 0; Index < V_PCIE_MAX_TRY_TIMES; Index++){\r
+      if (QNCMmio16 (EndPointBase, 0x0) != 0xFFFF) {\r
+        break;\r
+      }\r
+      PcieStall (15);\r
+    }\r
+    if (Index >= V_PCIE_MAX_TRY_TIMES) {\r
+      //\r
+      // Clear Bus Numbers.\r
+      //\r
+      QNCMmio32And (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF);\r
+      return EFI_NOT_FOUND;\r
+    }\r
+  }\r
+\r
+  //\r
+  // PCI Express* Virtual Channels\r
+  // Clear TC1-7 Traffic classes.\r
+  // Map TC0-VC0\r
+  //\r
+  PcieInitTcxVc0 (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0);\r
+  PcieMapTcxVc0 (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0, 0x0);\r
+\r
+  //\r
+  // Set Common Clock for inserted cards\r
+  //\r
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {\r
+    PcieSetCommonClock (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0);\r
+  }\r
+\r
+  //\r
+  // Flow for Enabling ASPM\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.AspmEnable) {\r
+    if (RootPortConfig[RootPortIndex].Bits.AspmAutoEnable) {\r
+      PcieSetAspmAuto (PCI_BUS_NUMBER_QNC, (UINT8)(PCI_DEVICE_NUMBER_PCIE_ROOTPORT), (UINT8)(PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex), 2, 0, 0, &AspmVal);\r
+    } else {\r
+      //\r
+      // Set ASPM values according to setup selections, masked by capabilities\r
+      //\r
+      PcieSetAspmManual (\r
+        PCI_BUS_NUMBER_QNC,\r
+        (UINT8) (PCI_DEVICE_NUMBER_PCIE_ROOTPORT),\r
+        (UINT8) (PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0 + RootPortIndex),\r
+        (UINT8) ((RootPortConfig[RootPortIndex].Bits.AspmL0sEnable & 0x01) | (RootPortConfig[RootPortIndex].Bits.AspmL1Enable << 1)),\r
+        &AspmVal\r
+        );\r
+    }\r
+  }\r
+\r
+  //\r
+  // Enable the PCIe CLKREQ#\r
+  //\r
+  if ((SlotStatus & B_QNC_PCIE_SLSTS_PDS) != 0) {\r
+    PcieSetClkreq (2, 0);\r
+  }\r
+\r
+  //\r
+  // Clear Bus Numbers\r
+  //\r
+  QNCMmio32And (RPBase, R_QNC_PCIE_BNUM, 0xFF0000FF);\r
+\r
+  //\r
+  // Additional configurations\r
+  //\r
+\r
+  //\r
+  // PCI-E Unsupported Request Reporting Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_URE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_URE);\r
+  }\r
+\r
+  //\r
+  // Device Fatal Error Reporting Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_FEE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_FEE);\r
+  }\r
+\r
+  //\r
+  // Device Non Fatal Error Reporting Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_NFE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_NFE);\r
+  }\r
+\r
+  //\r
+  // Device Correctable Error Reporting Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_CEE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_DCTL, B_QNC_PCIE_DCTL_CEE);\r
+  }\r
+  //\r
+  // Root PCI-E PME Interrupt Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PmeInterruptEnable) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_PIE);\r
+  }\r
+  //\r
+  // Root PCI-E System Error on Fatal Error Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SFE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SFE);\r
+  }\r
+\r
+  //\r
+  // Root PCI-E System Error on Non-Fatal Error Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SNE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SNE);\r
+  }\r
+\r
+  //\r
+  // Root PCI-E System Error on Correctable Error Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PortErrorMask & PCIEXP_ROOT_PORT_SCE_ENABLE) {\r
+    QNCMmio16Or (RPBase, R_QNC_PCIE_RCTL, B_QNC_PCIE_RCTL_SCE);\r
+  }\r
+\r
+  //\r
+  // Root PCI-E Powermanagement SCI Enabled\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.PmSciEnable) {\r
+    //\r
+    // Make sure that PME Interrupt Enable bit of Root Control register\r
+    // of PCI Express Capability struceture is cleared\r
+    //\r
+    QNCMmio32And (RPBase, R_QNC_PCIE_RCTL, (~B_QNC_PCIE_RCTL_PIE));\r
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_MPC, (~B_QNC_PCIE_MPC_PMME), B_QNC_PCIE_MPC_PMCE);\r
+\r
+    //\r
+    // Make sure GPE0 Stutus RW1C Bit is clear.\r
+    //\r
+    DwordReg = IoRead32 (QNCGpeBase + R_QNC_GPE0BLK_GPE0S);\r
+    if ((DwordReg & B_QNC_GPE0BLK_GPE0S_PCIE) != 0) {\r
+      IoWrite32 (QNCGpeBase + R_QNC_GPE0BLK_GPE0S, B_QNC_GPE0BLK_GPE0S_PCIE);\r
+    }\r
+  }\r
+\r
+  //\r
+  // PCIe Hot Plug SCI Enable\r
+  //\r
+  if (RootPortConfig[RootPortIndex].Bits.HotplugSciEnable) {\r
+    //\r
+    // Write clear for :\r
+    // Attention Button Pressed (bit0)\r
+    // Presence Detect Changed (bit3)\r
+    //\r
+    QNCMmio32Or (RPBase, R_QNC_PCIE_SLSTS, (B_QNC_PCIE_SLSTS_PDC | B_QNC_PCIE_SLSTS_ABP));\r
+\r
+    //\r
+    // Sequence 2: Program the following bits in Slot Control register at offset 18h\r
+    // of PCI Express* Capability structure:\r
+    // Attention Button Pressed Enable (bit0) = 1b\r
+    // Presence Detect Changed Enable (bit3) = 1b\r
+    // Hot Plug Interrupt Enable (bit5) = 0b\r
+    //\r
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_SLCTL, (~B_QNC_PCIE_SLCTL_HPE), (B_QNC_PCIE_SLCTL_PDE | B_QNC_PCIE_SLCTL_ABE));\r
+\r
+    //\r
+    // Sequence 3: Program Misc Port Config (MPC) register at PCI config space offset\r
+    // D8h as follows:\r
+    // Hot Plug SCI Enable (HPCE, bit30) = 1b\r
+    // Hot Plug SMI Enable (HPME, bit1) = 0b\r
+    //\r
+    QNCMmio32AndThenOr (RPBase, R_QNC_PCIE_MPC, (~B_QNC_PCIE_MPC_HPME), B_QNC_PCIE_MPC_HPCE);\r
+  }\r
+\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Perform Initialization of the Downstream Root Ports\r
+**/\r
+VOID\r
+QNCDownStreamPortsInit (\r
+  IN PCIEXP_ROOT_PORT_CONFIGURATION             *RootPortConfig,\r
+  IN QNC_DEVICE_ENABLES                      *QNCDeviceEnables,\r
+  IN UINT64                                     PciExpressBar,\r
+  IN UINT32                                     QNCRootComplexBar,\r
+  IN UINT32                                     QNCPmioBase,\r
+  IN UINT32                                     QNCGpeBase,\r
+  OUT UINTN                                     *RpEnableMask\r
+  )\r
+{\r
+  EFI_STATUS     Status;\r
+  UINT32         Index;\r
+\r
+  //\r
+  // Initialize every root port and downstream device\r
+  //\r
+  for (Index = 0;Index < MAX_PCI_EXPRESS_ROOT_PORTS;Index++) {\r
+    if ((QNCDeviceEnables->Uint32 & (1 << Index)) != 0) {\r
+      Status = QNCRootPortInit (\r
+               Index,\r
+               RootPortConfig,\r
+               PciExpressBar,\r
+               QNCRootComplexBar,\r
+               QNCPmioBase,\r
+               QNCGpeBase\r
+               );\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        (*RpEnableMask) |= LShiftU64(1, Index);\r
+        DEBUG ((EFI_D_INFO, " Root Port %x device found, enabled. RpEnableMask: 0x%x\n", Index + 1, *RpEnableMask));\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  Do early init of pci express rootports on Soc.\r
+\r
+**/\r
+\r
+VOID\r
+EFIAPI\r
+PciExpressEarlyInit (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Setup Message Bus Idle Counter (SBIC) values.\r
+  //\r
+  QNCMmPci8(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_IOSFSBCTL) = QNCMmPci8AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_IOSFSBCTL, (~B_QNC_PCIE_IOSFSBCTL_SBIC_MASK), V_PCIE_ROOT_PORT_SBIC_VALUE);\r
+  QNCMmPci8(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_IOSFSBCTL) = QNCMmPci8AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_IOSFSBCTL, (~B_QNC_PCIE_IOSFSBCTL_SBIC_MASK), V_PCIE_ROOT_PORT_SBIC_VALUE);\r
+\r
+  //\r
+  // Program SVID/SID the same as VID/DID for Root ports.\r
+  //\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, PCI_VENDOR_ID_OFFSET);\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_SVID) = QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, PCI_VENDOR_ID_OFFSET);\r
+\r
+  //\r
+  // Set the IPF bit in MCR2\r
+  //\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_MPC2) = QNCMmPci32Or(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_MPC2, B_QNC_PCIE_MPC2_IPF);\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_MPC2) = QNCMmPci32Or(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_1, R_QNC_PCIE_MPC2, B_QNC_PCIE_MPC2_IPF);\r
+\r
+  //\r
+  // Set up the Posted and Non Posted Request sizes for PCIe\r
+  //\r
+  QNCMmPci32(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_CCFG) = QNCMmPci32AndThenOr(0, PCI_BUS_NUMBER_QNC, PCI_DEVICE_NUMBER_PCIE_ROOTPORT, PCI_FUNCTION_NUMBER_PCIE_ROOTPORT_0, R_QNC_PCIE_CCFG, ~B_QNC_PCIE_CCFG_UPSD, (B_QNC_PCIE_CCFG_UNRS | B_QNC_PCIE_CCFG_UPRS));\r
+\r
+  return;\r
+}\r
+\r
+\r
+/**\r
+  Complete initialization all the pci express rootports on Soc.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+PciExpressInit (\r
+  )\r
+{\r
+  UINT64                            PciExpressBar;\r
+  UINT32                            QNCRootComplexBar;\r
+  UINT32                            QNCGpioBase;\r
+  UINT32                            QNCPmioBase;\r
+  UINT32                            QNCGpeBase;\r
+  UINTN                             RpEnableMask;\r
+  PCIEXP_ROOT_PORT_CONFIGURATION    *mRootPortConfig;\r
+  QNC_DEVICE_ENABLES                mQNCDeviceEnables;\r
+\r
+  //\r
+  // Get BAR registers\r
+  //\r
+  QNCRootComplexBar  = QNC_RCRB_BASE;\r
+  QNCGpioBase        = LpcPciCfg32 (R_QNC_LPC_GBA_BASE) & B_QNC_LPC_GPA_BASE_MASK;\r
+  QNCPmioBase        = LpcPciCfg32 (R_QNC_LPC_PM1BLK) & B_QNC_LPC_PM1BLK_MASK;\r
+  QNCGpeBase         = LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & B_QNC_LPC_GPE0BLK_MASK;\r
+  RpEnableMask = 0;                 // assume all root ports are disabled\r
+\r
+  PciExpressBar = PcdGet64 (PcdPciExpressBaseAddress);\r
+\r
+  //\r
+  // Get platform information from PCD entries\r
+  //\r
+  mQNCDeviceEnables.Uint32 = PcdGet32 (PcdDeviceEnables);\r
+  mRootPortConfig = (PCIEXP_ROOT_PORT_CONFIGURATION*) PcdGetPtr (PcdPcieRootPortConfiguration);\r
+\r
+  DEBUG ((EFI_D_INFO, " mRootPortConfig: 0x%x,  value1: 0x%x, value2: 0x%x, value3: 0x%x, value4: 0x%x\n",\r
+          mRootPortConfig, mRootPortConfig[0].Uint32, mRootPortConfig[1].Uint32,\r
+          mRootPortConfig[2].Uint32, mRootPortConfig[3].Uint32));\r
+\r
+  QNCDownStreamPortsInit (\r
+                         mRootPortConfig,\r
+                         &mQNCDeviceEnables,\r
+                         PciExpressBar,\r
+                         QNCRootComplexBar,\r
+                         QNCPmioBase,\r
+                         QNCGpeBase,\r
+                         &RpEnableMask\r
+                         );\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
diff --git a/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c b/QuarkSocPkg/QuarkNorthCluster/Library/MtrrLib/MtrrLib.c
new file mode 100644 (file)
index 0000000..4a88dff
--- /dev/null
@@ -0,0 +1,2117 @@
+/** @file\r
+MTRR setting library\r
+\r
+Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include <Base.h>\r
+\r
+#include <Library/MtrrLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/CpuLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/QNCAccessLib.h>\r
+\r
+#define QUARK_SOC_CPUID_FAMILY_MODEL_STEPPING         0x590\r
+\r
+//\r
+// Context to save and restore when MTRRs are programmed\r
+//\r
+typedef struct {\r
+  UINTN    Cr4;\r
+  BOOLEAN  InterruptState;\r
+} MTRR_CONTEXT;\r
+\r
+//\r
+// This table defines the offset, base and length of the fixed MTRRs\r
+//\r
+CONST FIXED_MTRR  mMtrrLibFixedMtrrTable[] = {\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000, 0,       SIZE_64KB },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_80000, 0x80000, SIZE_16KB },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX16K_A0000, 0xA0000, SIZE_16KB },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C0000,  0xC0000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_C8000,  0xC8000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D0000,  0xD0000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_D8000,  0xD8000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E0000,  0xE0000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_E8000,  0xE8000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F0000,  0xF0000, SIZE_4KB  },\r
+  { QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000,  0xF8000, SIZE_4KB  }\r
+};\r
+\r
+//\r
+// Lookup table used to print MTRRs\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 *mMtrrMemoryCacheTypeShortName[] = {\r
+  "UC",  // CacheUncacheable\r
+  "WC",  // CacheWriteCombining\r
+  "R*",  // Invalid\r
+  "R*",  // Invalid\r
+  "WT",  // CacheWriteThrough\r
+  "WP",  // CacheWriteProtected\r
+  "WB",  // CacheWriteBack\r
+  "R*"   // Invalid\r
+};\r
+\r
+UINT64\r
+MtrrRegisterRead (\r
+  IN  UINT32  MtrrRegister\r
+  )\r
+{\r
+  UINT64  Result;\r
+\r
+  Result = (UINT64)QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister);\r
+  if (MtrrRegister >= QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000 && MtrrRegister <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000) {\r
+    Result = Result | LShiftU64 ((UINT64)QNCPortRead (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister + 1), 32);\r
+  }\r
+  return Result;\r
+}\r
+\r
+UINT64\r
+MtrrRegisterWrite (\r
+  IN  UINT32  MtrrRegister,\r
+  IN  UINT64  Value\r
+  )\r
+{\r
+  QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister, (UINT32)Value);\r
+  if (MtrrRegister >= QUARK_NC_HOST_BRIDGE_MTRR_FIX64K_00000 && MtrrRegister <= QUARK_NC_HOST_BRIDGE_MTRR_FIX4K_F8000) {\r
+    QNCPortWrite (QUARK_NC_HOST_BRIDGE_SB_PORT_ID, MtrrRegister + 1, (UINT32)RShiftU64 (Value, 32));\r
+  }\r
+  return Value;\r
+}\r
+\r
+UINT64\r
+MtrrRegisterBitFieldWrite (\r
+  IN  UINT32  MtrrRegister,\r
+  IN  UINTN   StartBit,\r
+  IN  UINTN   EndBit,\r
+  IN  UINT64  Value\r
+  )\r
+{\r
+  return MtrrRegisterWrite (\r
+           MtrrRegister,\r
+           BitFieldWrite64 (\r
+             MtrrRegisterRead (MtrrRegister),\r
+             StartBit,\r
+             EndBit,\r
+             Value\r
+             )\r
+           );\r
+}\r
+\r
+/**\r
+  Worker function returns the variable MTRR count for the CPU.\r
+\r
+  @return Variable MTRR count\r
+\r
+**/\r
+UINT32\r
+GetVariableMtrrCountWorker (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  VariableMtrrCount;\r
+\r
+  VariableMtrrCount = (UINT32)(MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_CAP) & MTRR_LIB_IA32_MTRR_CAP_VCNT_MASK);\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  return VariableMtrrCount;\r
+}\r
+\r
+/**\r
+  Returns the variable MTRR count for the CPU.\r
+\r
+  @return Variable MTRR count\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetVariableMtrrCount (\r
+  VOID\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return 0;\r
+  }\r
+  return GetVariableMtrrCountWorker ();\r
+}\r
+\r
+/**\r
+  Worker function returns the firmware usable variable MTRR count for the CPU.\r
+\r
+  @return Firmware usable variable MTRR count\r
+\r
+**/\r
+UINT32\r
+GetFirmwareVariableMtrrCountWorker (\r
+  VOID\r
+  )\r
+{\r
+  UINT32  VariableMtrrCount;\r
+  UINT32  ReservedMtrrNumber;\r
+\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  ReservedMtrrNumber = PcdGet32 (PcdCpuNumberOfReservedVariableMtrrs);\r
+  if (VariableMtrrCount < ReservedMtrrNumber) {\r
+    return 0;\r
+  }\r
+\r
+  return VariableMtrrCount - ReservedMtrrNumber;\r
+}\r
+\r
+/**\r
+  Returns the firmware usable variable MTRR count for the CPU.\r
+\r
+  @return Firmware usable variable MTRR count\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+GetFirmwareVariableMtrrCount (\r
+  VOID\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return 0;\r
+  }\r
+  return GetFirmwareVariableMtrrCountWorker ();\r
+}\r
+\r
+/**\r
+  Worker function returns the default MTRR cache type for the system.\r
+\r
+  If MtrrSetting is not NULL, returns the default MTRR cache type from input\r
+  MTRR settings buffer.\r
+  If MtrrSetting is NULL, returns the default MTRR cache type from MSR.\r
+\r
+  @param[in]  MtrrSetting    A buffer holding all MTRRs content.\r
+\r
+  @return  The default MTRR cache type.\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+MtrrGetDefaultMemoryTypeWorker (\r
+  IN MTRR_SETTINGS      *MtrrSetting\r
+  )\r
+{\r
+  if (MtrrSetting == NULL) {\r
+    return (MTRR_MEMORY_CACHE_TYPE) (MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE) & 0x7);\r
+  } else {\r
+    return (MTRR_MEMORY_CACHE_TYPE) (MtrrSetting->MtrrDefType & 0x7);\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Returns the default MTRR cache type for the system.\r
+\r
+  @return  The default MTRR cache type.\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+EFIAPI\r
+MtrrGetDefaultMemoryType (\r
+  VOID\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return CacheUncacheable;\r
+  }\r
+  return MtrrGetDefaultMemoryTypeWorker (NULL);\r
+}\r
+\r
+/**\r
+  Preparation before programming MTRR.\r
+\r
+  This function will do some preparation for programming MTRRs:\r
+  disable cache, invalid cache and disable MTRR caching functionality\r
+\r
+  @param[out] MtrrContext  Pointer to context to save\r
+\r
+**/\r
+VOID\r
+PreMtrrChange (\r
+  OUT MTRR_CONTEXT  *MtrrContext\r
+  )\r
+{\r
+  //\r
+  // Disable interrupts and save current interrupt state\r
+  //\r
+  MtrrContext->InterruptState = SaveAndDisableInterrupts();\r
+\r
+  //\r
+  // Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)\r
+  //\r
+  AsmDisableCache ();\r
+\r
+  //\r
+  // Save original CR4 value and clear PGE flag (Bit 7)\r
+  //\r
+  MtrrContext->Cr4 = AsmReadCr4 ();\r
+  AsmWriteCr4 (MtrrContext->Cr4 & (~BIT7));\r
+\r
+  //\r
+  // Flush all TLBs\r
+  //\r
+  CpuFlushTlb ();\r
+\r
+  //\r
+  // Disable MTRRs\r
+  //\r
+  MtrrRegisterBitFieldWrite (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE, 10, 11, 0);\r
+}\r
+\r
+/**\r
+  Cleaning up after programming MTRRs.\r
+\r
+  This function will do some clean up after programming MTRRs:\r
+  Flush all TLBs,  re-enable caching, restore CR4.\r
+\r
+  @param[in] MtrrContext  Pointer to context to restore\r
+\r
+**/\r
+VOID\r
+PostMtrrChangeEnableCache (\r
+  IN MTRR_CONTEXT  *MtrrContext\r
+  )\r
+{\r
+  //\r
+  // Flush all TLBs\r
+  //\r
+  CpuFlushTlb ();\r
+\r
+  //\r
+  // Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)\r
+  //\r
+  AsmEnableCache ();\r
+\r
+  //\r
+  // Restore original CR4 value\r
+  //\r
+  AsmWriteCr4 (MtrrContext->Cr4);\r
+\r
+  //\r
+  // Restore original interrupt state\r
+  //\r
+  SetInterruptState (MtrrContext->InterruptState);\r
+}\r
+\r
+/**\r
+  Cleaning up after programming MTRRs.\r
+\r
+  This function will do some clean up after programming MTRRs:\r
+  enable MTRR caching functionality, and enable cache\r
+\r
+  @param[in] MtrrContext  Pointer to context to restore\r
+\r
+**/\r
+VOID\r
+PostMtrrChange (\r
+  IN MTRR_CONTEXT  *MtrrContext\r
+  )\r
+{\r
+  //\r
+  // Enable Cache MTRR\r
+  //\r
+  MtrrRegisterBitFieldWrite (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE, 10, 11, 3);\r
+\r
+  PostMtrrChangeEnableCache (MtrrContext);\r
+}\r
+\r
+/**\r
+  Worker function gets the content in fixed MTRRs\r
+\r
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.\r
+\r
+  @retval The pointer of FixedSettings\r
+\r
+**/\r
+MTRR_FIXED_SETTINGS*\r
+MtrrGetFixedMtrrWorker (\r
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      FixedSettings->Mtrr[Index] =\r
+        MtrrRegisterRead (mMtrrLibFixedMtrrTable[Index].Msr);\r
+  }\r
+\r
+  return FixedSettings;\r
+}\r
+\r
+\r
+/**\r
+  This function gets the content in fixed MTRRs\r
+\r
+  @param[out]  FixedSettings  A buffer to hold fixed MTRRs content.\r
+\r
+  @retval The pointer of FixedSettings\r
+\r
+**/\r
+MTRR_FIXED_SETTINGS*\r
+EFIAPI\r
+MtrrGetFixedMtrr (\r
+  OUT MTRR_FIXED_SETTINGS         *FixedSettings\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return FixedSettings;\r
+  }\r
+\r
+  return MtrrGetFixedMtrrWorker (FixedSettings);\r
+}\r
+\r
+\r
+/**\r
+  Worker function will get the raw value in variable MTRRs\r
+\r
+  If MtrrSetting is not NULL, gets the variable MTRRs raw value from input\r
+  MTRR settings buffer.\r
+  If MtrrSetting is NULL, gets the variable MTRRs raw value from MTRRs.\r
+\r
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.\r
+  @param[in]  VariableMtrrCount  Number of variable MTRRs.\r
+  @param[out] VariableSettings   A buffer to hold variable MTRRs content.\r
+\r
+  @return The VariableSettings input pointer\r
+\r
+**/\r
+MTRR_VARIABLE_SETTINGS*\r
+MtrrGetVariableMtrrWorker (\r
+  IN  MTRR_SETTINGS           *MtrrSetting,\r
+  IN  UINT32                  VariableMtrrCount,\r
+  OUT MTRR_VARIABLE_SETTINGS  *VariableSettings\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+    if (MtrrSetting == NULL) {\r
+      VariableSettings->Mtrr[Index].Base =\r
+        MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1));\r
+      VariableSettings->Mtrr[Index].Mask =\r
+        MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_PHYSBASE0 + (Index << 1) + 1);\r
+    } else {\r
+      VariableSettings->Mtrr[Index].Base = MtrrSetting->Variables.Mtrr[Index].Base;\r
+      VariableSettings->Mtrr[Index].Mask = MtrrSetting->Variables.Mtrr[Index].Mask;\r
+    }\r
+  }\r
+\r
+  return  VariableSettings;\r
+}\r
+\r
+/**\r
+  This function will get the raw value in variable MTRRs\r
+\r
+  @param[out]  VariableSettings   A buffer to hold variable MTRRs content.\r
+\r
+  @return The VariableSettings input pointer\r
+\r
+**/\r
+MTRR_VARIABLE_SETTINGS*\r
+EFIAPI\r
+MtrrGetVariableMtrr (\r
+  OUT MTRR_VARIABLE_SETTINGS         *VariableSettings\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return VariableSettings;\r
+  }\r
+\r
+  return MtrrGetVariableMtrrWorker (\r
+           NULL,\r
+           GetVariableMtrrCountWorker (),\r
+           VariableSettings\r
+           );\r
+}\r
+\r
+/**\r
+  Programs fixed MTRRs registers.\r
+\r
+  @param[in]      MemoryCacheType  The memory type to set.\r
+  @param[in, out] Base             The base address of memory range.\r
+  @param[in, out] Length           The length of memory range.\r
+  @param[out]     ReturnMsrNum     The index of the fixed MTRR MSR to program.\r
+  @param[out]     ReturnClearMask  The bits to clear in the fixed MTRR MSR.\r
+  @param[out]     ReturnOrMask     The bits to set in the fixed MTRR MSR.\r
+\r
+  @retval RETURN_SUCCESS      The cache type was updated successfully\r
+  @retval RETURN_UNSUPPORTED  The requested range or cache type was invalid\r
+                              for the fixed MTRRs.\r
+\r
+**/\r
+RETURN_STATUS\r
+ProgramFixedMtrr (\r
+  IN     UINT64               MemoryCacheType,\r
+  IN OUT UINT64               *Base,\r
+  IN OUT UINT64               *Length,\r
+  OUT    UINT32               *ReturnMsrNum,\r
+  OUT    UINT64               *ReturnClearMask,\r
+  OUT    UINT64               *ReturnOrMask\r
+  )\r
+{\r
+  UINT32  MsrNum;\r
+  UINT32  ByteShift;\r
+  UINT64  TempQword;\r
+  UINT64  OrMask;\r
+  UINT64  ClearMask;\r
+\r
+  TempQword = 0;\r
+  OrMask    = 0;\r
+  ClearMask = 0;\r
+\r
+  for (MsrNum = 0; MsrNum < MTRR_NUMBER_OF_FIXED_MTRR; MsrNum++) {\r
+    if ((*Base >= mMtrrLibFixedMtrrTable[MsrNum].BaseAddress) &&\r
+        (*Base <\r
+            (\r
+              mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +\r
+              (8 * mMtrrLibFixedMtrrTable[MsrNum].Length)\r
+            )\r
+          )\r
+        ) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (MsrNum == MTRR_NUMBER_OF_FIXED_MTRR) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  //\r
+  // We found the fixed MTRR to be programmed\r
+  //\r
+  for (ByteShift = 0; ByteShift < 8; ByteShift++) {\r
+    if (*Base ==\r
+         (\r
+           mMtrrLibFixedMtrrTable[MsrNum].BaseAddress +\r
+           (ByteShift * mMtrrLibFixedMtrrTable[MsrNum].Length)\r
+         )\r
+       ) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (ByteShift == 8) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  for (\r
+        ;\r
+        ((ByteShift < 8) && (*Length >= mMtrrLibFixedMtrrTable[MsrNum].Length));\r
+        ByteShift++\r
+      ) {\r
+    OrMask |= LShiftU64 ((UINT64) MemoryCacheType, (UINT32) (ByteShift * 8));\r
+    ClearMask |= LShiftU64 ((UINT64) 0xFF, (UINT32) (ByteShift * 8));\r
+    *Length -= mMtrrLibFixedMtrrTable[MsrNum].Length;\r
+    *Base += mMtrrLibFixedMtrrTable[MsrNum].Length;\r
+  }\r
+\r
+  if (ByteShift < 8 && (*Length != 0)) {\r
+    return RETURN_UNSUPPORTED;\r
+  }\r
+\r
+  *ReturnMsrNum    = MsrNum;\r
+  *ReturnClearMask = ClearMask;\r
+  *ReturnOrMask    = OrMask;\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Worker function gets the attribute of variable MTRRs.\r
+\r
+  This function shadows the content of variable MTRRs into an\r
+  internal array: VariableMtrr.\r
+\r
+  @param[in]   VariableSettings           The variable MTRR values to shadow\r
+  @param[in]   FirmwareVariableMtrrCount  The number of variable MTRRs available to firmware\r
+  @param[in]   MtrrValidBitsMask          The mask for the valid bit of the MTRR\r
+  @param[in]   MtrrValidAddressMask       The valid address mask for MTRR\r
+  @param[out]  VariableMtrr               The array to shadow variable MTRRs content\r
+\r
+  @return                       The return value of this parameter indicates the\r
+                                number of MTRRs which has been used.\r
+\r
+**/\r
+UINT32\r
+MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+  IN  MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
+  IN  UINTN                   FirmwareVariableMtrrCount,\r
+  IN  UINT64                  MtrrValidBitsMask,\r
+  IN  UINT64                  MtrrValidAddressMask,\r
+  OUT VARIABLE_MTRR           *VariableMtrr\r
+  )\r
+{\r
+  UINTN   Index;\r
+  UINT32  UsedMtrr;\r
+\r
+  ZeroMem (VariableMtrr, sizeof (VARIABLE_MTRR) * MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+  for (Index = 0, UsedMtrr = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+    if ((VariableSettings->Mtrr[Index].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) != 0) {\r
+      VariableMtrr[Index].Msr         = (UINT32)Index;\r
+      VariableMtrr[Index].BaseAddress = (VariableSettings->Mtrr[Index].Base & MtrrValidAddressMask);\r
+      VariableMtrr[Index].Length      = ((~(VariableSettings->Mtrr[Index].Mask & MtrrValidAddressMask)) & MtrrValidBitsMask) + 1;\r
+      VariableMtrr[Index].Type        = (VariableSettings->Mtrr[Index].Base & 0x0ff);\r
+      VariableMtrr[Index].Valid       = TRUE;\r
+      VariableMtrr[Index].Used        = TRUE;\r
+      UsedMtrr++;\r
+    }\r
+  }\r
+  return UsedMtrr;\r
+}\r
+\r
+\r
+/**\r
+  Gets the attribute of variable MTRRs.\r
+\r
+  This function shadows the content of variable MTRRs into an\r
+  internal array: VariableMtrr.\r
+\r
+  @param[in]   MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
+  @param[in]   MtrrValidAddressMask  The valid address mask for MTRR\r
+  @param[out]  VariableMtrr          The array to shadow variable MTRRs content\r
+\r
+  @return                       The return value of this paramter indicates the\r
+                                number of MTRRs which has been used.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+MtrrGetMemoryAttributeInVariableMtrr (\r
+  IN  UINT64                    MtrrValidBitsMask,\r
+  IN  UINT64                    MtrrValidAddressMask,\r
+  OUT VARIABLE_MTRR             *VariableMtrr\r
+  )\r
+{\r
+  MTRR_VARIABLE_SETTINGS  VariableSettings;\r
+\r
+  if (!IsMtrrSupported ()) {\r
+    return 0;\r
+  }\r
+\r
+  MtrrGetVariableMtrrWorker (\r
+    NULL,\r
+    GetVariableMtrrCountWorker (),\r
+    &VariableSettings\r
+    );\r
+\r
+  return MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+           &VariableSettings,\r
+           GetFirmwareVariableMtrrCountWorker (),\r
+           MtrrValidBitsMask,\r
+           MtrrValidAddressMask,\r
+           VariableMtrr\r
+           );\r
+}\r
+\r
+\r
+/**\r
+  Checks overlap between given memory range and MTRRs.\r
+\r
+  @param[in]  FirmwareVariableMtrrCount  The number of variable MTRRs available\r
+                                         to firmware.\r
+  @param[in]  Start                      The start address of memory range.\r
+  @param[in]  End                        The end address of memory range.\r
+  @param[in]  VariableMtrr               The array to shadow variable MTRRs content\r
+\r
+  @retval TRUE             Overlap exists.\r
+  @retval FALSE            No overlap.\r
+\r
+**/\r
+BOOLEAN\r
+CheckMemoryAttributeOverlap (\r
+  IN UINTN             FirmwareVariableMtrrCount,\r
+  IN PHYSICAL_ADDRESS  Start,\r
+  IN PHYSICAL_ADDRESS  End,\r
+  IN VARIABLE_MTRR     *VariableMtrr\r
+  )\r
+{\r
+  UINT32  Index;\r
+\r
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+    if (\r
+         VariableMtrr[Index].Valid &&\r
+         !(\r
+           (Start > (VariableMtrr[Index].BaseAddress +\r
+                     VariableMtrr[Index].Length - 1)\r
+           ) ||\r
+           (End < VariableMtrr[Index].BaseAddress)\r
+         )\r
+       ) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
+\r
+/**\r
+  Marks a variable MTRR as non-valid.\r
+\r
+  @param[in]   Index         The index of the array VariableMtrr to be invalidated\r
+  @param[in]   VariableMtrr  The array to shadow variable MTRRs content\r
+  @param[out]  UsedMtrr      The number of MTRRs which has already been used\r
+\r
+**/\r
+VOID\r
+InvalidateShadowMtrr (\r
+  IN   UINTN              Index,\r
+  IN   VARIABLE_MTRR      *VariableMtrr,\r
+  OUT  UINT32             *UsedMtrr\r
+  )\r
+{\r
+  VariableMtrr[Index].Valid = FALSE;\r
+  *UsedMtrr = *UsedMtrr - 1;\r
+}\r
+\r
+\r
+/**\r
+  Combines memory attributes.\r
+\r
+  If overlap exists between given memory range and MTRRs, try to combine them.\r
+\r
+  @param[in]       FirmwareVariableMtrrCount  The number of variable MTRRs\r
+                                              available to firmware.\r
+  @param[in]       Attributes                 The memory type to set.\r
+  @param[in, out]  Base                       The base address of memory range.\r
+  @param[in, out]  Length                     The length of memory range.\r
+  @param[in]       VariableMtrr               The array to shadow variable MTRRs content\r
+  @param[in, out]  UsedMtrr                   The number of MTRRs which has already been used\r
+  @param[out]      OverwriteExistingMtrr      Returns whether an existing MTRR was used\r
+\r
+  @retval EFI_SUCCESS            Memory region successfully combined.\r
+  @retval EFI_ACCESS_DENIED      Memory region cannot be combined.\r
+\r
+**/\r
+RETURN_STATUS\r
+CombineMemoryAttribute (\r
+  IN     UINT32             FirmwareVariableMtrrCount,\r
+  IN     UINT64             Attributes,\r
+  IN OUT UINT64             *Base,\r
+  IN OUT UINT64             *Length,\r
+  IN     VARIABLE_MTRR      *VariableMtrr,\r
+  IN OUT UINT32             *UsedMtrr,\r
+  OUT    BOOLEAN            *OverwriteExistingMtrr\r
+  )\r
+{\r
+  UINT32  Index;\r
+  UINT64  CombineStart;\r
+  UINT64  CombineEnd;\r
+  UINT64  MtrrEnd;\r
+  UINT64  EndAddress;\r
+  BOOLEAN CoveredByExistingMtrr;\r
+\r
+  *OverwriteExistingMtrr = FALSE;\r
+  CoveredByExistingMtrr = FALSE;\r
+  EndAddress = *Base +*Length - 1;\r
+\r
+  for (Index = 0; Index < FirmwareVariableMtrrCount; Index++) {\r
+\r
+    MtrrEnd = VariableMtrr[Index].BaseAddress + VariableMtrr[Index].Length - 1;\r
+    if (\r
+         !VariableMtrr[Index].Valid ||\r
+         (\r
+           *Base > (MtrrEnd) ||\r
+           (EndAddress < VariableMtrr[Index].BaseAddress)\r
+         )\r
+       ) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Combine same attribute MTRR range\r
+    //\r
+    if (Attributes == VariableMtrr[Index].Type) {\r
+      //\r
+      // if the MTRR range contain the request range, set a flag, then continue to\r
+      // invalidate any MTRR of the same request range with higher priority cache type.\r
+      //\r
+      if (VariableMtrr[Index].BaseAddress <= *Base && MtrrEnd >= EndAddress) {\r
+        CoveredByExistingMtrr = TRUE;\r
+        continue;\r
+      }\r
+      //\r
+      // invalid this MTRR, and program the combine range\r
+      //\r
+      CombineStart  =\r
+        (*Base) < VariableMtrr[Index].BaseAddress ?\r
+          (*Base) :\r
+          VariableMtrr[Index].BaseAddress;\r
+      CombineEnd    = EndAddress > MtrrEnd ? EndAddress : MtrrEnd;\r
+\r
+      //\r
+      // Record the MTRR usage status in VariableMtrr array.\r
+      //\r
+      InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr);\r
+      *Base       = CombineStart;\r
+      *Length     = CombineEnd - CombineStart + 1;\r
+      EndAddress  = CombineEnd;\r
+      *OverwriteExistingMtrr = TRUE;\r
+      continue;\r
+    } else {\r
+      //\r
+      // The cache type is different, but the range is convered by one MTRR\r
+      //\r
+      if (VariableMtrr[Index].BaseAddress == *Base && MtrrEnd == EndAddress) {\r
+        InvalidateShadowMtrr (Index, VariableMtrr, UsedMtrr);\r
+        continue;\r
+      }\r
+\r
+    }\r
+\r
+    if ((Attributes== MTRR_CACHE_WRITE_THROUGH &&\r
+         VariableMtrr[Index].Type == MTRR_CACHE_WRITE_BACK) ||\r
+        (Attributes == MTRR_CACHE_WRITE_BACK &&\r
+         VariableMtrr[Index].Type == MTRR_CACHE_WRITE_THROUGH) ||\r
+        (Attributes == MTRR_CACHE_UNCACHEABLE) ||\r
+        (VariableMtrr[Index].Type == MTRR_CACHE_UNCACHEABLE)\r
+     ) {\r
+      *OverwriteExistingMtrr = TRUE;\r
+      continue;\r
+    }\r
+    //\r
+    // Other type memory overlap is invalid\r
+    //\r
+    return RETURN_ACCESS_DENIED;\r
+  }\r
+\r
+  if (CoveredByExistingMtrr) {\r
+    *Length = 0;\r
+  }\r
+\r
+  return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+  Calculates the maximum value which is a power of 2, but less the MemoryLength.\r
+\r
+  @param[in]  MemoryLength        The number to pass in.\r
+\r
+  @return The maximum value which is align to power of 2 and less the MemoryLength\r
+\r
+**/\r
+UINT64\r
+Power2MaxMemory (\r
+  IN UINT64                     MemoryLength\r
+  )\r
+{\r
+  UINT64  Result;\r
+\r
+  if (RShiftU64 (MemoryLength, 32) != 0) {\r
+    Result = LShiftU64 (\r
+               (UINT64) GetPowerOfTwo32 (\r
+                          (UINT32) RShiftU64 (MemoryLength, 32)\r
+                          ),\r
+               32\r
+               );\r
+  } else {\r
+    Result = (UINT64) GetPowerOfTwo32 ((UINT32) MemoryLength);\r
+  }\r
+\r
+  return Result;\r
+}\r
+\r
+\r
+/**\r
+  Determines the MTRR numbers used to program a memory range.\r
+\r
+  This function first checks the alignment of the base address.\r
+  If the alignment of the base address <= Length, cover the memory range\r
+ (BaseAddress, alignment) by a MTRR, then BaseAddress += alignment and\r
+  Length -= alignment. Repeat the step until alignment > Length.\r
+\r
+  Then this function determines which direction of programming the variable\r
+  MTRRs for the remaining length will use fewer MTRRs.\r
+\r
+  @param[in]  BaseAddress Length of Memory to program MTRR\r
+  @param[in]  Length      Length of Memory to program MTRR\r
+  @param[in]  MtrrNumber  Pointer to the number of necessary MTRRs\r
+\r
+  @retval TRUE        Positive direction is better.\r
+          FALSE       Negative direction is better.\r
+\r
+**/\r
+BOOLEAN\r
+GetMtrrNumberAndDirection (\r
+  IN UINT64      BaseAddress,\r
+  IN UINT64      Length,\r
+  IN UINTN       *MtrrNumber\r
+  )\r
+{\r
+  UINT64  TempQword;\r
+  UINT64  Alignment;\r
+  UINT32  Positive;\r
+  UINT32  Subtractive;\r
+\r
+  *MtrrNumber = 0;\r
+\r
+  if (BaseAddress != 0) {\r
+    do {\r
+      //\r
+      // Calculate the alignment of the base address.\r
+      //\r
+      Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress));\r
+\r
+      if (Alignment > Length) {\r
+        break;\r
+      }\r
+\r
+      (*MtrrNumber)++;\r
+      BaseAddress += Alignment;\r
+      Length -= Alignment;\r
+    } while (TRUE);\r
+\r
+    if (Length == 0) {\r
+      return TRUE;\r
+    }\r
+  }\r
+\r
+  TempQword   = Length;\r
+  Positive    = 0;\r
+  Subtractive = 0;\r
+\r
+  do {\r
+    TempQword -= Power2MaxMemory (TempQword);\r
+    Positive++;\r
+  } while (TempQword != 0);\r
+\r
+  TempQword = Power2MaxMemory (LShiftU64 (Length, 1)) - Length;\r
+  Subtractive++;\r
+  do {\r
+    TempQword -= Power2MaxMemory (TempQword);\r
+    Subtractive++;\r
+  } while (TempQword != 0);\r
+\r
+  if (Positive <= Subtractive) {\r
+    *MtrrNumber += Positive;\r
+    return TRUE;\r
+  } else {\r
+    *MtrrNumber += Subtractive;\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Invalid variable MTRRs according to the value in the shadow array.\r
+\r
+  This function programs MTRRs according to the values specified\r
+  in the shadow array.\r
+\r
+  @param[in, out]  VariableSettings   Variable MTRR settings\r
+  @param[in]       VariableMtrrCount  Number of variable MTRRs\r
+  @param[in, out]  VariableMtrr       Shadow of variable MTRR contents\r
+\r
+**/\r
+VOID\r
+InvalidateMtrr (\r
+  IN OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
+  IN     UINTN                   VariableMtrrCount,\r
+  IN OUT VARIABLE_MTRR           *VariableMtrr\r
+  )\r
+{\r
+  UINTN         Index;\r
+\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+    if (!VariableMtrr[Index].Valid && VariableMtrr[Index].Used) {\r
+       VariableSettings->Mtrr[Index].Base = 0;\r
+       VariableSettings->Mtrr[Index].Mask = 0;\r
+       VariableMtrr[Index].Used = FALSE;\r
+    }\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Programs variable MTRRs\r
+\r
+  This function programs variable MTRRs\r
+\r
+  @param[in, out]  VariableSettings      Variable MTRR settings.\r
+  @param[in]       MtrrNumber            Index of MTRR to program.\r
+  @param[in]       BaseAddress           Base address of memory region.\r
+  @param[in]       Length                Length of memory region.\r
+  @param[in]       MemoryCacheType       Memory type to set.\r
+  @param[in]       MtrrValidAddressMask  The valid address mask for MTRR\r
+\r
+**/\r
+VOID\r
+ProgramVariableMtrr (\r
+  IN OUT MTRR_VARIABLE_SETTINGS  *VariableSettings,\r
+  IN     UINTN                   MtrrNumber,\r
+  IN     PHYSICAL_ADDRESS        BaseAddress,\r
+  IN     UINT64                  Length,\r
+  IN     UINT64                  MemoryCacheType,\r
+  IN     UINT64                  MtrrValidAddressMask\r
+  )\r
+{\r
+  UINT64        TempQword;\r
+\r
+  //\r
+  // MTRR Physical Base\r
+  //\r
+  TempQword = (BaseAddress & MtrrValidAddressMask) | MemoryCacheType;\r
+  VariableSettings->Mtrr[MtrrNumber].Base = TempQword;\r
+\r
+  //\r
+  // MTRR Physical Mask\r
+  //\r
+  TempQword = ~(Length - 1);\r
+  VariableSettings->Mtrr[MtrrNumber].Mask = (TempQword & MtrrValidAddressMask) | MTRR_LIB_CACHE_MTRR_ENABLED;\r
+}\r
+\r
+\r
+/**\r
+  Converts the Memory attribute value to MTRR_MEMORY_CACHE_TYPE.\r
+\r
+  If MtrrSetting is not NULL, gets the default memory attribute from input\r
+  MTRR settings buffer.\r
+  If MtrrSetting is NULL, gets the default memory attribute from MSR.\r
+\r
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.\r
+  @param[in]  MtrrType           MTRR memory type\r
+\r
+  @return The enum item in MTRR_MEMORY_CACHE_TYPE\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+GetMemoryCacheTypeFromMtrrType (\r
+  IN MTRR_SETTINGS         *MtrrSetting,\r
+  IN UINT64                MtrrType\r
+  )\r
+{\r
+  switch (MtrrType) {\r
+  case MTRR_CACHE_UNCACHEABLE:\r
+    return CacheUncacheable;\r
+  case MTRR_CACHE_WRITE_COMBINING:\r
+    return CacheWriteCombining;\r
+  case MTRR_CACHE_WRITE_THROUGH:\r
+    return CacheWriteThrough;\r
+  case MTRR_CACHE_WRITE_PROTECTED:\r
+    return CacheWriteProtected;\r
+  case MTRR_CACHE_WRITE_BACK:\r
+    return CacheWriteBack;\r
+  default:\r
+    //\r
+    // MtrrType is MTRR_CACHE_INVALID_TYPE, that means\r
+    // no MTRR covers the range\r
+    //\r
+    return MtrrGetDefaultMemoryTypeWorker (MtrrSetting);\r
+  }\r
+}\r
+\r
+/**\r
+  Initializes the valid bits mask and valid address mask for MTRRs.\r
+\r
+  This function initializes the valid bits mask and valid address mask for MTRRs.\r
+\r
+  @param[out]  MtrrValidBitsMask     The mask for the valid bit of the MTRR\r
+  @param[out]  MtrrValidAddressMask  The valid address mask for the MTRR\r
+\r
+**/\r
+VOID\r
+MtrrLibInitializeMtrrMask (\r
+  OUT UINT64 *MtrrValidBitsMask,\r
+  OUT UINT64 *MtrrValidAddressMask\r
+  )\r
+{\r
+  UINT32  RegEax;\r
+  UINT8   PhysicalAddressBits;\r
+\r
+  AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+\r
+  if (RegEax >= 0x80000008) {\r
+    AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+\r
+    PhysicalAddressBits = (UINT8) RegEax;\r
+\r
+    *MtrrValidBitsMask    = LShiftU64 (1, PhysicalAddressBits) - 1;\r
+    *MtrrValidAddressMask = *MtrrValidBitsMask & 0xfffffffffffff000ULL;\r
+  } else {\r
+    *MtrrValidBitsMask    = MTRR_LIB_MSR_VALID_MASK;\r
+    *MtrrValidAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;\r
+  }\r
+}\r
+\r
+\r
+/**\r
+  Determines the real attribute of a memory range.\r
+\r
+  This function is to arbitrate the real attribute of the memory when\r
+  there are 2 MTRRs covers the same memory range.  For further details,\r
+  please refer the IA32 Software Developer's Manual, Volume 3,\r
+  Section 10.11.4.1.\r
+\r
+  @param[in]  MtrrType1    The first kind of Memory type\r
+  @param[in]  MtrrType2    The second kind of memory type\r
+\r
+**/\r
+UINT64\r
+MtrrPrecedence (\r
+  IN UINT64    MtrrType1,\r
+  IN UINT64    MtrrType2\r
+  )\r
+{\r
+  UINT64 MtrrType;\r
+\r
+  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
+  switch (MtrrType1) {\r
+  case MTRR_CACHE_UNCACHEABLE:\r
+    MtrrType = MTRR_CACHE_UNCACHEABLE;\r
+    break;\r
+  case MTRR_CACHE_WRITE_COMBINING:\r
+    if (\r
+         MtrrType2==MTRR_CACHE_WRITE_COMBINING ||\r
+         MtrrType2==MTRR_CACHE_UNCACHEABLE\r
+       ) {\r
+      MtrrType = MtrrType2;\r
+    }\r
+    break;\r
+  case MTRR_CACHE_WRITE_THROUGH:\r
+    if (\r
+         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||\r
+         MtrrType2==MTRR_CACHE_WRITE_BACK\r
+       ) {\r
+      MtrrType = MTRR_CACHE_WRITE_THROUGH;\r
+    } else if(MtrrType2==MTRR_CACHE_UNCACHEABLE) {\r
+      MtrrType = MTRR_CACHE_UNCACHEABLE;\r
+    }\r
+    break;\r
+  case MTRR_CACHE_WRITE_PROTECTED:\r
+    if (MtrrType2 == MTRR_CACHE_WRITE_PROTECTED ||\r
+        MtrrType2 == MTRR_CACHE_UNCACHEABLE) {\r
+      MtrrType = MtrrType2;\r
+    }\r
+    break;\r
+  case MTRR_CACHE_WRITE_BACK:\r
+    if (\r
+         MtrrType2== MTRR_CACHE_UNCACHEABLE ||\r
+         MtrrType2==MTRR_CACHE_WRITE_THROUGH ||\r
+         MtrrType2== MTRR_CACHE_WRITE_BACK\r
+       ) {\r
+      MtrrType = MtrrType2;\r
+    }\r
+    break;\r
+  case MTRR_CACHE_INVALID_TYPE:\r
+    MtrrType = MtrrType2;\r
+    break;\r
+  default:\r
+    break;\r
+  }\r
+\r
+  if (MtrrType2 == MTRR_CACHE_INVALID_TYPE) {\r
+    MtrrType = MtrrType1;\r
+  }\r
+  return MtrrType;\r
+}\r
+\r
+/**\r
+  Worker function will get the memory cache type of the specific address.\r
+\r
+  If MtrrSetting is not NULL, gets the memory cache type from input\r
+  MTRR settings buffer.\r
+  If MtrrSetting is NULL, gets the memory cache type from MTRRs.\r
+\r
+  @param[in]  MtrrSetting        A buffer holding all MTRRs content.\r
+  @param[in]  Address            The specific address\r
+\r
+  @return Memory cache type of the specific address\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+MtrrGetMemoryAttributeByAddressWorker (\r
+  IN MTRR_SETTINGS      *MtrrSetting,\r
+  IN PHYSICAL_ADDRESS   Address\r
+  )\r
+{\r
+  UINT64                  TempQword;\r
+  UINTN                   Index;\r
+  UINTN                   SubIndex;\r
+  UINT64                  MtrrType;\r
+  UINT64                  TempMtrrType;\r
+  MTRR_MEMORY_CACHE_TYPE  CacheType;\r
+  VARIABLE_MTRR           VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT64                  MtrrValidBitsMask;\r
+  UINT64                  MtrrValidAddressMask;\r
+  UINTN                   VariableMtrrCount;\r
+  MTRR_VARIABLE_SETTINGS  VariableSettings;\r
+\r
+  //\r
+  // Check if MTRR is enabled, if not, return UC as attribute\r
+  //\r
+  if (MtrrSetting == NULL) {\r
+    TempQword = MtrrRegisterRead (QUARK_NC_HOST_BRIDGE_IA32_MTRR_DEF_TYPE);\r
+  } else {\r
+    TempQword = MtrrSetting->MtrrDefType;\r
+  }\r
+  MtrrType = MTRR_CACHE_INVALID_TYPE;\r
+\r
+  if ((TempQword & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+    return CacheUncacheable;\r
+  }\r
+\r
+  //\r
+  // If address is less than 1M, then try to go through the fixed MTRR\r
+  //\r
+  if (Address < BASE_1MB) {\r
+    if ((TempQword & MTRR_LIB_CACHE_FIXED_MTRR_ENABLED) != 0) {\r
+      //\r
+      // Go through the fixed MTRR\r
+      //\r
+      for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+         if (Address >= mMtrrLibFixedMtrrTable[Index].BaseAddress &&\r
+             Address  < (\r
+                          mMtrrLibFixedMtrrTable[Index].BaseAddress +\r
+                          (mMtrrLibFixedMtrrTable[Index].Length * 8)\r
+                        )\r
+            ) {\r
+           SubIndex =\r
+             ((UINTN)Address - mMtrrLibFixedMtrrTable[Index].BaseAddress) /\r
+               mMtrrLibFixedMtrrTable[Index].Length;\r
+           if (MtrrSetting == NULL) {\r
+             TempQword = MtrrRegisterRead (mMtrrLibFixedMtrrTable[Index].Msr);\r
+           } else {\r
+             TempQword = MtrrSetting->Fixed.Mtrr[Index];\r
+           }\r
+           MtrrType =  RShiftU64 (TempQword, SubIndex * 8) & 0xFF;\r
+           return GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
+         }\r
+      }\r
+    }\r
+  }\r
+  MtrrLibInitializeMtrrMask(&MtrrValidBitsMask, &MtrrValidAddressMask);\r
+\r
+  MtrrGetVariableMtrrWorker (\r
+    MtrrSetting,\r
+    GetVariableMtrrCountWorker (),\r
+    &VariableSettings\r
+    );\r
+\r
+  MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+           &VariableSettings,\r
+           GetFirmwareVariableMtrrCountWorker (),\r
+           MtrrValidBitsMask,\r
+           MtrrValidAddressMask,\r
+           VariableMtrr\r
+           );\r
+\r
+  //\r
+  // Go through the variable MTRR\r
+  //\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  ASSERT (VariableMtrrCount <= MTRR_NUMBER_OF_VARIABLE_MTRR);\r
+\r
+  for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+    if (VariableMtrr[Index].Valid) {\r
+      if (Address >= VariableMtrr[Index].BaseAddress &&\r
+          Address < VariableMtrr[Index].BaseAddress+VariableMtrr[Index].Length) {\r
+        TempMtrrType = VariableMtrr[Index].Type;\r
+        MtrrType = MtrrPrecedence (MtrrType, TempMtrrType);\r
+      }\r
+    }\r
+  }\r
+  CacheType = GetMemoryCacheTypeFromMtrrType (MtrrSetting, MtrrType);\r
+\r
+  return CacheType;\r
+}\r
+\r
+\r
+/**\r
+  This function will get the memory cache type of the specific address.\r
+\r
+  This function is mainly for debug purpose.\r
+\r
+  @param[in]  Address   The specific address\r
+\r
+  @return Memory cache type of the specific address\r
+\r
+**/\r
+MTRR_MEMORY_CACHE_TYPE\r
+EFIAPI\r
+MtrrGetMemoryAttribute (\r
+  IN PHYSICAL_ADDRESS   Address\r
+  )\r
+{\r
+  if (!IsMtrrSupported ()) {\r
+    return CacheUncacheable;\r
+  }\r
+\r
+  return MtrrGetMemoryAttributeByAddressWorker (NULL, Address);\r
+}\r
+\r
+/**\r
+  Worker function prints all MTRRs for debugging.\r
+\r
+  If MtrrSetting is not NULL, print MTRR settings from from input MTRR\r
+  settings buffer.\r
+  If MtrrSetting is NULL, print MTRR settings from MTRRs.\r
+\r
+  @param  MtrrSetting    A buffer holding all MTRRs content.\r
+**/\r
+VOID\r
+MtrrDebugPrintAllMtrrsWorker (\r
+  IN MTRR_SETTINGS    *MtrrSetting\r
+  )\r
+{\r
+  DEBUG_CODE (\r
+    MTRR_SETTINGS  LocalMtrrs;\r
+    MTRR_SETTINGS  *Mtrrs;\r
+    UINTN          Index;\r
+    UINTN          Index1;\r
+    UINTN          VariableMtrrCount;\r
+    UINT64         Base;\r
+    UINT64         Limit;\r
+    UINT64         MtrrBase;\r
+    UINT64         MtrrLimit;\r
+    UINT64         RangeBase;\r
+    UINT64         RangeLimit;\r
+    UINT64         NoRangeBase;\r
+    UINT64         NoRangeLimit;\r
+    UINT32         RegEax;\r
+    UINTN          MemoryType;\r
+    UINTN          PreviousMemoryType;\r
+    BOOLEAN        Found;\r
+\r
+    if (!IsMtrrSupported ()) {\r
+      return;\r
+    }\r
+\r
+    DEBUG((DEBUG_CACHE, "MTRR Settings\n"));\r
+    DEBUG((DEBUG_CACHE, "=============\n"));\r
+\r
+    if (MtrrSetting != NULL) {\r
+      Mtrrs = MtrrSetting;\r
+    } else {\r
+      MtrrGetAllMtrrs (&LocalMtrrs);\r
+      Mtrrs = &LocalMtrrs;\r
+    }\r
+\r
+    DEBUG((DEBUG_CACHE, "MTRR Default Type: %016lx\n", Mtrrs->MtrrDefType));\r
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      DEBUG((DEBUG_CACHE, "Fixed MTRR[%02d]   : %016lx\n", Index, Mtrrs->Fixed.Mtrr[Index]));\r
+    }\r
+\r
+    VariableMtrrCount = GetVariableMtrrCount ();\r
+    for (Index = 0; Index < VariableMtrrCount; Index++) {\r
+      DEBUG((DEBUG_CACHE, "Variable MTRR[%02d]: Base=%016lx Mask=%016lx\n",\r
+        Index,\r
+        Mtrrs->Variables.Mtrr[Index].Base,\r
+        Mtrrs->Variables.Mtrr[Index].Mask\r
+        ));\r
+    }\r
+    DEBUG((DEBUG_CACHE, "\n"));\r
+    DEBUG((DEBUG_CACHE, "MTRR Ranges\n"));\r
+    DEBUG((DEBUG_CACHE, "====================================\n"));\r
+\r
+    Base = 0;\r
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
+    for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+      Base = mMtrrLibFixedMtrrTable[Index].BaseAddress;\r
+      for (Index1 = 0; Index1 < 8; Index1++) {\r
+      MemoryType = (UINTN)(RShiftU64 (Mtrrs->Fixed.Mtrr[Index], Index1 * 8) & 0xff);\r
+        if (MemoryType > CacheWriteBack) {\r
+          MemoryType = MTRR_CACHE_INVALID_TYPE;\r
+        }\r
+        if (MemoryType != PreviousMemoryType) {\r
+          if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
+            DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+          }\r
+          PreviousMemoryType = MemoryType;\r
+          DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
+        }\r
+        Base += mMtrrLibFixedMtrrTable[Index].Length;\r
+      }\r
+    }\r
+    DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+\r
+    VariableMtrrCount = GetVariableMtrrCount ();\r
+\r
+    Limit        = BIT36 - 1;\r
+    AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+    if (RegEax >= 0x80000008) {\r
+      AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+      Limit = LShiftU64 (1, RegEax & 0xff) - 1;\r
+    }\r
+    Base = BASE_1MB;\r
+    PreviousMemoryType = MTRR_CACHE_INVALID_TYPE;\r
+    do {\r
+      MemoryType = MtrrGetMemoryAttributeByAddressWorker (Mtrrs, Base);\r
+      if (MemoryType > CacheWriteBack) {\r
+        MemoryType = MTRR_CACHE_INVALID_TYPE;\r
+      }\r
+\r
+      if (MemoryType != PreviousMemoryType) {\r
+        if (PreviousMemoryType != MTRR_CACHE_INVALID_TYPE) {\r
+          DEBUG((DEBUG_CACHE, "%016lx\n", Base - 1));\r
+        }\r
+        PreviousMemoryType = MemoryType;\r
+        DEBUG((DEBUG_CACHE, "%a:%016lx-", mMtrrMemoryCacheTypeShortName[MemoryType], Base));\r
+      }\r
+\r
+      RangeBase    = BASE_1MB;\r
+      NoRangeBase  = BASE_1MB;\r
+      RangeLimit   = Limit;\r
+      NoRangeLimit = Limit;\r
+\r
+      for (Index = 0, Found = FALSE; Index < VariableMtrrCount; Index++) {\r
+        if ((Mtrrs->Variables.Mtrr[Index].Mask & BIT11) == 0) {\r
+          //\r
+          // If mask is not valid, then do not display range\r
+          //\r
+          continue;\r
+        }\r
+        MtrrBase  = (Mtrrs->Variables.Mtrr[Index].Base & (~(SIZE_4KB - 1)));\r
+        MtrrLimit = MtrrBase + ((~(Mtrrs->Variables.Mtrr[Index].Mask & (~(SIZE_4KB - 1)))) & Limit);\r
+\r
+        if (Base >= MtrrBase && Base < MtrrLimit) {\r
+          Found = TRUE;\r
+        }\r
+\r
+        if (Base >= MtrrBase && MtrrBase > RangeBase) {\r
+          RangeBase = MtrrBase;\r
+        }\r
+        if (Base > MtrrLimit && MtrrLimit > RangeBase) {\r
+          RangeBase = MtrrLimit + 1;\r
+        }\r
+        if (Base < MtrrBase && MtrrBase < RangeLimit) {\r
+          RangeLimit = MtrrBase - 1;\r
+        }\r
+        if (Base < MtrrLimit && MtrrLimit <= RangeLimit) {\r
+          RangeLimit = MtrrLimit;\r
+        }\r
+\r
+        if (Base > MtrrLimit && NoRangeBase < MtrrLimit) {\r
+          NoRangeBase = MtrrLimit + 1;\r
+        }\r
+        if (Base < MtrrBase && NoRangeLimit > MtrrBase) {\r
+          NoRangeLimit = MtrrBase - 1;\r
+        }\r
+      }\r
+\r
+      if (Found) {\r
+        Base = RangeLimit + 1;\r
+      } else {\r
+        Base = NoRangeLimit + 1;\r
+      }\r
+    } while (Base < Limit);\r
+    DEBUG((DEBUG_CACHE, "%016lx\n\n", Base - 1));\r
+  );\r
+}\r
+\r
+\r
+/**\r
+  This function prints all MTRRs for debugging.\r
+**/\r
+VOID\r
+EFIAPI\r
+MtrrDebugPrintAllMtrrs (\r
+  VOID\r
+  )\r
+{\r
+  MtrrDebugPrintAllMtrrsWorker (NULL);\r
+}\r
+\r
+\r
+/**\r
+  Worker function attempts to set the attributes for a memory range.\r
+\r
+  If MtrrSettings is not NULL, set the attributes into the input MTRR\r
+  settings buffer.\r
+  If MtrrSettings is NULL, set the attributes into MTRRs registers.\r
+\r
+  @param[in, out]  MtrrSetting       A buffer holding all MTRRs content.\r
+  @param[in]       BaseAddress       The physical address that is the start\r
+                                     address of a memory region.\r
+  @param[in]       Length            The size in bytes of the memory region.\r
+  @param[in]       Attribute         The bit mask of attributes to set for the\r
+                                     memory region.\r
+\r
+  @retval RETURN_SUCCESS            The attributes were set for the memory\r
+                                    region.\r
+  @retval RETURN_INVALID_PARAMETER  Length is zero.\r
+  @retval RETURN_UNSUPPORTED        The processor does not support one or\r
+                                    more bytes of the memory resource range\r
+                                    specified by BaseAddress and Length.\r
+  @retval RETURN_UNSUPPORTED        The bit mask of attributes is not support\r
+                                    for the memory resource range specified\r
+                                    by BaseAddress and Length.\r
+  @retval RETURN_ACCESS_DENIED      The attributes for the memory resource\r
+                                    range specified by BaseAddress and Length\r
+                                    cannot be modified.\r
+  @retval RETURN_OUT_OF_RESOURCES   There are not enough system resources to\r
+                                    modify the attributes of the memory\r
+                                    resource range.\r
+\r
+**/\r
+RETURN_STATUS\r
+MtrrSetMemoryAttributeWorker (\r
+  IN OUT MTRR_SETTINGS           *MtrrSetting,\r
+  IN PHYSICAL_ADDRESS            BaseAddress,\r
+  IN UINT64                      Length,\r
+  IN MTRR_MEMORY_CACHE_TYPE      Attribute\r
+  )\r
+{\r
+  UINT64                    TempQword;\r
+  RETURN_STATUS             Status;\r
+  UINT64                    MemoryType;\r
+  UINT64                    Alignment;\r
+  BOOLEAN                   OverLap;\r
+  BOOLEAN                   Positive;\r
+  UINT32                    MsrNum;\r
+  UINTN                     MtrrNumber;\r
+  VARIABLE_MTRR             VariableMtrr[MTRR_NUMBER_OF_VARIABLE_MTRR];\r
+  UINT32                    UsedMtrr;\r
+  UINT64                    MtrrValidBitsMask;\r
+  UINT64                    MtrrValidAddressMask;\r
+  BOOLEAN                   OverwriteExistingMtrr;\r
+  UINT32                    FirmwareVariableMtrrCount;\r
+  MTRR_CONTEXT              MtrrContext;\r
+  BOOLEAN                   MtrrContextValid;\r
+  BOOLEAN                   FixedSettingsValid[MTRR_NUMBER_OF_FIXED_MTRR];\r
+  BOOLEAN                   FixedSettingsModified[MTRR_NUMBER_OF_FIXED_MTRR];\r
+  MTRR_FIXED_SETTINGS       WorkingFixedSettings;\r
+  UINT32                    VariableMtrrCount;\r
+  MTRR_VARIABLE_SETTINGS    OriginalVariableSettings;\r
+  BOOLEAN                   ProgramVariableSettings;\r
+  MTRR_VARIABLE_SETTINGS    WorkingVariableSettings;\r
+  UINT32                    Index;\r
+  UINT64                    ClearMask;\r
+  UINT64                    OrMask;\r
+  UINT64                    NewValue;\r
+  MTRR_VARIABLE_SETTINGS    *VariableSettings;\r
+\r
+  MtrrContextValid  = FALSE;\r
+  VariableMtrrCount = 0;\r
+  ZeroMem (&WorkingFixedSettings, sizeof (WorkingFixedSettings));\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+    FixedSettingsValid[Index]    = FALSE;\r
+    FixedSettingsModified[Index] = FALSE;\r
+  }\r
+  ProgramVariableSettings = FALSE;\r
+\r
+  if (!IsMtrrSupported ()) {\r
+    Status = RETURN_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  MtrrLibInitializeMtrrMask (&MtrrValidBitsMask, &MtrrValidAddressMask);\r
+\r
+  TempQword = 0;\r
+  MemoryType = (UINT64)Attribute;\r
+  OverwriteExistingMtrr = FALSE;\r
+\r
+  //\r
+  // Check for an invalid parameter\r
+  //\r
+  if (Length == 0) {\r
+    Status = RETURN_INVALID_PARAMETER;\r
+    goto Done;\r
+  }\r
+\r
+  if (\r
+       (BaseAddress & ~MtrrValidAddressMask) != 0 ||\r
+       (Length & ~MtrrValidAddressMask) != 0\r
+     ) {\r
+    Status = RETURN_UNSUPPORTED;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Check if Fixed MTRR\r
+  //\r
+  Status = RETURN_SUCCESS;\r
+  if (BaseAddress < BASE_1MB) {\r
+    while ((BaseAddress < BASE_1MB) && (Length > 0) && Status == RETURN_SUCCESS) {\r
+      Status = ProgramFixedMtrr (MemoryType, &BaseAddress, &Length, &MsrNum, &ClearMask, &OrMask);\r
+      if (RETURN_ERROR (Status)) {\r
+        goto Done;\r
+      }\r
+      if (MtrrSetting != NULL) {\r
+        MtrrSetting->Fixed.Mtrr[MsrNum] = (MtrrSetting->Fixed.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+        MtrrSetting->MtrrDefType |= MTRR_LIB_CACHE_FIXED_MTRR_ENABLED;\r
+      } else {\r
+        if (!FixedSettingsValid[MsrNum]) {\r
+          WorkingFixedSettings.Mtrr[MsrNum] = MtrrRegisterRead (mMtrrLibFixedMtrrTable[MsrNum].Msr);\r
+          FixedSettingsValid[MsrNum] = TRUE;\r
+        }\r
+        NewValue = (WorkingFixedSettings.Mtrr[MsrNum] & ~ClearMask) | OrMask;\r
+        if (WorkingFixedSettings.Mtrr[MsrNum] != NewValue) {\r
+          WorkingFixedSettings.Mtrr[MsrNum] = NewValue;\r
+          FixedSettingsModified[MsrNum] = TRUE;\r
+        }\r
+      }\r
+    }\r
+\r
+    if (Length == 0) {\r
+      //\r
+      // A Length of 0 can only make sense for fixed MTTR ranges.\r
+      // Since we just handled the fixed MTRRs, we can skip the\r
+      // variable MTRR section.\r
+      //\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Since memory ranges below 1MB will be overridden by the fixed MTRRs,\r
+  // we can set the base to 0 to save variable MTRRs.\r
+  //\r
+  if (BaseAddress == BASE_1MB) {\r
+    BaseAddress = 0;\r
+    Length += SIZE_1MB;\r
+  }\r
+\r
+  //\r
+  // Read all variable MTRRs\r
+  //\r
+  VariableMtrrCount = GetVariableMtrrCountWorker ();\r
+  FirmwareVariableMtrrCount = GetFirmwareVariableMtrrCountWorker ();\r
+  if (MtrrSetting != NULL) {\r
+    VariableSettings = &MtrrSetting->Variables;\r
+  } else {\r
+    MtrrGetVariableMtrrWorker (NULL, VariableMtrrCount, &OriginalVariableSettings);\r
+    CopyMem (&WorkingVariableSettings, &OriginalVariableSettings, sizeof (WorkingVariableSettings));\r
+    ProgramVariableSettings = TRUE;\r
+    VariableSettings = &WorkingVariableSettings;\r
+  }\r
+\r
+  //\r
+  // Check for overlap\r
+  //\r
+  UsedMtrr = MtrrGetMemoryAttributeInVariableMtrrWorker (\r
+               VariableSettings,\r
+               FirmwareVariableMtrrCount,\r
+               MtrrValidBitsMask,\r
+               MtrrValidAddressMask,\r
+               VariableMtrr\r
+               );\r
+  OverLap = CheckMemoryAttributeOverlap (\r
+              FirmwareVariableMtrrCount,\r
+              BaseAddress,\r
+              BaseAddress + Length - 1,\r
+              VariableMtrr\r
+              );\r
+  if (OverLap) {\r
+    Status = CombineMemoryAttribute (\r
+               FirmwareVariableMtrrCount,\r
+               MemoryType,\r
+               &BaseAddress,\r
+               &Length,\r
+               VariableMtrr,\r
+               &UsedMtrr,\r
+               &OverwriteExistingMtrr\r
+               );\r
+    if (RETURN_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    if (Length == 0) {\r
+      //\r
+      // Combined successfully, invalidate the now-unused MTRRs\r
+      //\r
+      InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
+      Status = RETURN_SUCCESS;\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  //\r
+  // The memory type is the same with the type specified by\r
+  // MTRR_LIB_IA32_MTRR_DEF_TYPE.\r
+  //\r
+  if ((!OverwriteExistingMtrr) && (Attribute == MtrrGetDefaultMemoryType ())) {\r
+    //\r
+    // Invalidate the now-unused MTRRs\r
+    //\r
+    InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
+    goto Done;\r
+  }\r
+\r
+  Positive = GetMtrrNumberAndDirection (BaseAddress, Length, &MtrrNumber);\r
+\r
+  if ((UsedMtrr + MtrrNumber) > FirmwareVariableMtrrCount) {\r
+    Status = RETURN_OUT_OF_RESOURCES;\r
+    goto Done;\r
+  }\r
+\r
+  //\r
+  // Invalidate the now-unused MTRRs\r
+  //\r
+  InvalidateMtrr (VariableSettings, VariableMtrrCount, VariableMtrr);\r
+\r
+  //\r
+  // Find first unused MTRR\r
+  //\r
+  for (MsrNum = 0; MsrNum < VariableMtrrCount; MsrNum++) {\r
+    if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (BaseAddress != 0) {\r
+    do {\r
+      //\r
+      // Calculate the alignment of the base address.\r
+      //\r
+      Alignment = LShiftU64 (1, (UINTN)LowBitSet64 (BaseAddress));\r
+\r
+      if (Alignment > Length) {\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Find unused MTRR\r
+      //\r
+      for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+        if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+          break;\r
+        }\r
+      }\r
+\r
+      ProgramVariableMtrr (\r
+        VariableSettings,\r
+        MsrNum,\r
+        BaseAddress,\r
+        Alignment,\r
+        MemoryType,\r
+        MtrrValidAddressMask\r
+        );\r
+      BaseAddress += Alignment;\r
+      Length -= Alignment;\r
+    } while (TRUE);\r
+\r
+    if (Length == 0) {\r
+      goto Done;\r
+    }\r
+  }\r
+\r
+  TempQword = Length;\r
+\r
+  if (!Positive) {\r
+    Length = Power2MaxMemory (LShiftU64 (TempQword, 1));\r
+\r
+    //\r
+    // Find unused MTRR\r
+    //\r
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+      if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+        break;\r
+      }\r
+    }\r
+\r
+    ProgramVariableMtrr (\r
+      VariableSettings,\r
+      MsrNum,\r
+      BaseAddress,\r
+      Length,\r
+      MemoryType,\r
+      MtrrValidAddressMask\r
+      );\r
+    BaseAddress += Length;\r
+    TempQword   = Length - TempQword;\r
+    MemoryType  = MTRR_CACHE_UNCACHEABLE;\r
+  }\r
+\r
+  do {\r
+    //\r
+    // Find unused MTRR\r
+    //\r
+    for (; MsrNum < VariableMtrrCount; MsrNum++) {\r
+      if ((VariableSettings->Mtrr[MsrNum].Mask & MTRR_LIB_CACHE_MTRR_ENABLED) == 0) {\r
+        break;\r
+      }\r
+    }\r
+\r
+    Length = Power2MaxMemory (TempQword);\r
+    if (!Positive) {\r
+      BaseAddress -= Length;\r
+    }\r
+\r
+    ProgramVariableMtrr (\r
+      VariableSettings,\r
+      MsrNum,\r
+      BaseAddress,\r
+      Length,\r
+      MemoryType,\r
+      MtrrValidAddressMask\r
+      );\r
+\r
+    if (Positive) {\r
+      BaseAddress += Length;\r
+    }\r
+    TempQword -= Length;\r
+\r
+  } while (TempQword > 0);\r
+\r
+Done:\r
+\r
+  //\r
+  // Write fixed MTRRs that have been modified\r
+  //\r
+  for (Index = 0; Index < MTRR_NUMBER_OF_FIXED_MTRR; Index++) {\r
+    if (FixedSettingsModified[Index]) {\r
+      if (!MtrrContextValid) {\r
+        PreMt