summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint/PchInit
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /ReferenceCode/Chipset/LynxPoint/PchInit
downloadzprj-master.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint/PchInit')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.c48
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.h47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.c295
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.h44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.c326
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.h47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.c239
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.h42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.c31
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.h65
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.c3032
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.h360
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.cif21
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.mak127
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.sdl81
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c602
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c915
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c330
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchFvi.c137
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c2469
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs48
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.h653
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h110
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif28
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf134
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak150
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c134
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchLan.c152
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchMisc.c395
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchPm.c3389
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c2154
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c1547
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c997
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsb.c439
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.c522
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.h54
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c831
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c2232
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif17
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h253
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf108
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak117
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c198
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c105
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c753
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs46
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h106
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl71
55 files changed, 25444 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.c
new file mode 100644
index 0000000..4c23c06
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.c
@@ -0,0 +1,48 @@
+/** @file
+ Intializes all common Hsio structures
+
+@copyright
+ Copyright (c) 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+#include "PchHsio.h"
+
+#ifdef ULT_FLAG
+
+IOBP_MMIO_TABLE_STRUCT PchSerialIoSnoopLptLp[] = {
+ { 0xCB000240, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000248, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000250, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000258, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000260, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000268, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000270, (UINT32)~(0x000C0000), 0x00040000 },
+ { 0xCB000014, (UINT32)~(0x00006000), 0x00002000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSerialIoIntsLptLp[] = { // Device INTx PCI IRQ ACPI IRQ
+ { 0xCB000240, (UINT32)~(0x0000003C), 0x00000008 }, // D21:F0 = INTB IRQ20 IRQ6
+ { 0xCB000248, (UINT32)~(0x0000003C), 0x0000000C }, // D21:F1 = INTC IRQ21 IRQ7
+ { 0xCB000250, (UINT32)~(0x0000003C), 0x0000000C }, // D21:F2 = INTC IRQ21 IRQ7
+ { 0xCB000258, (UINT32)~(0x0000003C), 0x0000000C }, // D21:F3 = INTC IRQ21 IRQ7
+ { 0xCB000260, (UINT32)~(0x0000003C), 0x0000000C }, // D21:F4 = INTC IRQ21 IRQ7
+ { 0xCB000268, (UINT32)~(0x0000003C), 0x00000010 }, // D21:F5 = INTD IRQ21 IRQ13
+ { 0xCB000270, (UINT32)~(0x0000003C), 0x00000010 } // D21:F6 = INTD IRQ21 IRQ13
+}; // D23:F0 = INTA IRQ22 IRQ5
+
+#endif // ULT_FLAG \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.h
new file mode 100644
index 0000000..4dc83d9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIO.h
@@ -0,0 +1,47 @@
+/** @file
+
+ Header file with all common Hsio information
+
+@copyright
+ Copyright (c) 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+#ifndef _PCH_HSIO_H_
+#define _PCH_HSIO_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "IobpDefinitions.h"
+#ifdef TRAD_FLAG
+#include "PchHsioLptHB0.h"
+#include "PchHsioLptHCx.h"
+#endif //TRAD_FLAG
+#ifdef ULT_FLAG
+#include "PchHsioLptLpBx.h"
+#endif //ULT_FLAG
+#endif
+
+
+#ifdef ULT_FLAG
+extern IOBP_MMIO_TABLE_STRUCT PchSerialIoSnoopLptLp[8];
+extern IOBP_MMIO_TABLE_STRUCT PchSerialIoIntsLptLp[7];
+#endif // ULT_FLAG
+
+#endif //_PCH_HSIO_H_ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.c
new file mode 100644
index 0000000..190f824
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.c
@@ -0,0 +1,295 @@
+/** @file
+ Intializes all include B0 Hsio structures
+
+@copyright
+ Copyright (c) 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+#include "PchHsio.h"
+
+#ifdef TRAD_FLAG
+
+UINT8 PchChipsetInitTableLptH_B0[] = {
+ 0x79, 0x56, //U16 CRC-16
+ 0x23, 0x02, //U16 Version
+ 0x1A, //U8 NumEntries
+ // Hsio Entries
+ // Offset Value EP
+ 0x40,0xC1, 0xA6,0x05,0x08,0x00, 0xEB,
+ 0x44,0xC1, 0x94,0x03,0x04,0x00, 0xEB,
+ 0x40,0x83, 0x96,0x05,0x08,0x00, 0xE9,
+ 0x40,0x83, 0x96,0x05,0x08,0x00, 0xEA,
+ 0x44,0x83, 0x94,0x03,0x04,0x00, 0xE9,
+ 0x44,0x83, 0x94,0x03,0x04,0x00, 0xEA,
+ 0x0C,0x80, 0x50,0xAB,0x02,0x0E, 0xEB,
+ 0x0C,0x80, 0x50,0xAB,0x02,0x0E, 0xE9,
+ 0x00,0xC1, 0x89,0x5F,0x0B,0x0F, 0xEB,
+ 0x00,0xC1, 0x89,0x5F,0x0B,0x0F, 0xE9,
+ 0x7C,0xC1, 0x00,0x3F,0x40,0x3D, 0xEB,
+ 0x7C,0xC1, 0x00,0x3F,0x00,0x4F, 0xE9,
+ 0x78,0xC1, 0x84,0x1B,0x00,0x00, 0xE9,
+ 0xCC,0xC1, 0x04,0x43,0x35,0x00, 0xEB,
+ 0x90,0xC0, 0x55,0x51,0x3E,0x2B, 0xE9,
+ 0x90,0x82, 0x55,0x51,0x3E,0x2B, 0xEA,
+ 0x8C,0xC0, 0x46,0x20,0x78,0x0C, 0xE9,
+ 0x8C,0x82, 0x46,0x20,0x78,0x0C, 0xEA,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xEB,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xE9,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xEA,
+ 0xCC,0xC1, 0x04,0x43,0x35,0x00, 0xE9,
+ 0xCC,0xC1, 0x04,0x43,0x35,0x00, 0xEA,
+ 0x2C,0xC0, 0x00,0x0A,0x00,0x0F, 0xEB,
+ 0x2C,0x82, 0x00,0x0A,0x00,0x0F, 0xE9,
+ 0x2C,0x82, 0x00,0x0A,0x00,0x0F, 0xEA
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_B0[] = {
+ { 0xEA008008, (UINT32)~(0xFF000000), 0x1C000000 },
+ { 0xEA00800C, (UINT32)~(0x00007FFF), 0x00002B50 },
+ { 0xEA0024A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0026A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0008A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA000AA4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0024AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0026AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0008AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA000AAC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA002488, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA002688, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA000888, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA000A88, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA002494, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA002694, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA000894, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA000A94, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA002540, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA002740, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA000940, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA000B40, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA002544, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002744, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA000944, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA000B44, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002548, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002748, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA000948, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA000B48, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002550, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA002750, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA000950, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA000B50, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA002554, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA002754, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA000954, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA000B54, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA002410, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002610, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA000810, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA000A10, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002400, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002600, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA000800, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA000A00, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002408, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002608, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA000808, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA000A08, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002418, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002618, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA000818, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA000A18, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002428, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002628, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA000828, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA000A28, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002438, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002638, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA000838, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA000A38, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002440, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002640, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA000840, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA000A40, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA00242C, (UINT32)~(0x00020000), 0x00020000 },
+ { 0xEA00262C, (UINT32)~(0x00020000), 0x00020000 },
+ { 0xEA00082C, (UINT32)~(0x00020000), 0x00020000 },
+ { 0xEA000A2C, (UINT32)~(0x00020000), 0x00020000 },
+ { 0xEA00241C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00261C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00081C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA000A1C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA002500, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA002700, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA000900, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA000B00, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA00257C, (UINT32)~(0x000F3F00), 0x00003F00 },
+ { 0xEA00277C, (UINT32)~(0x000F3F00), 0x00003F00 },
+ { 0xEA00097C, (UINT32)~(0x000F3F00), 0x00003F00 },
+ { 0xEA000B7C, (UINT32)~(0x000F3F00), 0x00003F00 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_B0[] = {
+ { 0xEA0020A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0022A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0020AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0022AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA002088, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA002288, (UINT32)~(0x0000FF00), 0x00008000 },
+ { 0xEA002094, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA002294, (UINT32)~(0x80000000), 0x80000000 },
+ { 0xEA002140, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA002340, (UINT32)~(0x00FFFFFF), 0x00180918 },
+ { 0xEA002144, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002344, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002148, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002348, (UINT32)~(0x00FFFFFF), 0x00140918 },
+ { 0xEA002150, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA002350, (UINT32)~(0x3F000000), 0x02000000 },
+ { 0xEA002154, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA002354, (UINT32)~(0x003F0000), 0x00020000 },
+ { 0xEA002010, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002210, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002000, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002200, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002008, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002208, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002018, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002218, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002028, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002228, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002038, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002238, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002040, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002240, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA00202C, (UINT32)~(0x00020700), 0x00020100 },
+ { 0xEA00222C, (UINT32)~(0x00020700), 0x00020100 },
+ { 0xEA00201C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00221C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA002100, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA002300, (UINT32)~(0x0000E03E), 0x00004008 },
+ { 0xEA00217C, (UINT32)~(0x000F3F00), 0x00003F00 },
+ { 0xEA00237C, (UINT32)~(0x000F3F00), 0x00003F00 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptH_B0[] = {
+ { 0xE9003140, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE9003340, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE9001540, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE9001740, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE900316C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900336C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900156C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900176C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE9003168, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9003368, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9001568, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9001768, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE900314C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE900334C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE900154C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE900174C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE9003164, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9003364, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9001564, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9001764, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9003170, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9003370, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9001570, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9001770, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE90031CC, (UINT32)~(0x00001407), 0x00001401 },
+ { 0xE90033CC, (UINT32)~(0x00001407), 0x00001401 },
+ { 0xE90015CC, (UINT32)~(0x00001407), 0x00001401 },
+ { 0xE90017CC, (UINT32)~(0x00001407), 0x00001401 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptH_B0[] = {
+ { 0xE9002D40, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE9002F40, (UINT32)~(0x00FFFFFF), 0x00040998 },
+ { 0xE9002D6C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE9002F6C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE9002D44, (UINT32)~(0x000000FF), 0x00000014 },
+ { 0xE9002F44, (UINT32)~(0x000000FF), 0x00000014 },
+ { 0xE9002D68, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002F68, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002D4C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE9002F4C, (UINT32)~(0x00FF0000), 0x00140000 },
+ { 0xE9002D64, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002F64, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002D70, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002F70, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002DCC, (UINT32)~(0x00001407), 0x00001401 },
+ { 0xE9002FCC, (UINT32)~(0x00001407), 0x00001401 },
+ { 0xE9002C2C, (UINT32)~(0x00000700), 0x00000100 },
+ { 0xE9002E2C, (UINT32)~(0x00000700), 0x00000100 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptH_B0[] = {
+ { 0xE9002E08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002C08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002A08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002808, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002608, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002408, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002208, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002008, (UINT32)~(0xF0000100), 0xE0000100 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchDmiHsioLptH_B0[] = {
+ { 0xEB002090, (UINT32)~(0x0000FF00), 0x00005100 },
+ { 0xEB002290, (UINT32)~(0x0000FF00), 0x00005100 },
+ { 0xEB000490, (UINT32)~(0x0000FF00), 0x00005100 },
+ { 0xEB000690, (UINT32)~(0x0000FF00), 0x00005100 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_DT_B0[] = {
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA000890, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA000A90, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA00248C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00268C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00088C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA000A8C, (UINT32)~(0x00FF0000), 0x00800000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_DT_B0[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA00208C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00228C, (UINT32)~(0x00FF0000), 0x00800000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_MB_B0[] = {
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA000890, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA000A90, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA00248C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00268C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00088C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA000A8C, (UINT32)~(0x00FF0000), 0x00800000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_MB_B0[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA00208C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00228C, (UINT32)~(0x00FF0000), 0x00800000 }
+};
+
+#endif // TRAD_FLAG
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.h
new file mode 100644
index 0000000..efdd645
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHSIOLptHB0.h
@@ -0,0 +1,44 @@
+/** @file
+
+ Header file with all LptHB0 Hsio information
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+
+
+#ifdef TRAD_FLAG
+#ifndef _PCH_HSIO_LPTHB0_H_
+#define _PCH_HSIO_LPTHB0_H_
+
+#define PCH_LPTH_HSIO_VER_B0 0x23
+
+extern UINT8 PchChipsetInitTableLptH_B0[187];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_B0[82];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_B0[40];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptH_B0[28];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptH_B0[18];
+extern IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptH_B0[8];
+extern IOBP_MMIO_TABLE_STRUCT PchDmiHsioLptH_B0[4];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_DT_B0[8];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_DT_B0[4];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_MB_B0[8];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_MB_B0[4];
+
+#endif //_PCH_HSIO_LPTHB0_H_
+#endif //TRAD_FLAG \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.c
new file mode 100644
index 0000000..68e74df
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.c
@@ -0,0 +1,326 @@
+/** @file
+ Initializes all LPTHCx Hsio structures
+
+@copyright
+ Copyright (c) 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement.
+
+**/
+
+#include "PchHsio.h"
+
+#ifdef TRAD_FLAG
+
+UINT8 PchChipsetInitTableLptH_Cx[] = {
+ 0x9D, 0x59, //U16 CRC-16
+ 0x2C, 0x03, //U16 Version
+ 0x29, //U8 NumEntries;
+ // HSIO Entries
+ // Offset Value EP
+ 0x2C,0xC0, 0x00,0x0A,0x00,0x0F, 0xEB,
+ 0x2C,0x82, 0x00,0x0A,0x00,0x0F, 0xE9,
+ 0x40,0xC1, 0x9C,0x05,0x88,0x00, 0xE9,
+ 0x98,0xC0, 0x41,0x3B,0x20,0x1F, 0xEB,
+ 0x98,0xC0, 0x41,0x3B,0x20,0x1F, 0xE9,
+ 0x98,0xC0, 0x41,0x3B,0x20,0x1F, 0xEA,
+ 0x2C,0x82, 0x00,0x0A,0x00,0x0F, 0xEA,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xEB,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xE9,
+ 0x94,0xC0, 0x55,0x60,0x40,0x47, 0xEB,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xEA,
+ 0x40,0x83, 0x9C,0x05,0x88,0x00, 0xEA,
+ 0x78,0xC1, 0x80,0x19,0x00,0x00, 0xEB,
+ 0x94,0xC0, 0x55,0x60,0x40,0x47, 0xE9,
+ 0x94,0xC0, 0x55,0x60,0x40,0x47, 0xEA,
+ 0x88,0xC0, 0x3A,0x98,0x80,0x55, 0xEB,
+ 0x78,0xC1, 0x80,0x19,0x00,0x00, 0xE9,
+ 0x88,0xC0, 0x3A,0x98,0x80,0x55, 0xE9,
+ 0x88,0x82, 0x3A,0x98,0x80,0x55, 0xEA,
+ 0x8C,0xC0, 0x46,0x20,0x78,0x0C, 0xEB,
+ 0x8C,0xC0, 0x46,0x20,0x78,0x0C, 0xE9,
+ 0x8C,0x82, 0x46,0x20,0x78,0x0C, 0xEA,
+ 0x78,0xC1, 0x80,0x19,0x00,0x00, 0xEA,
+ 0xCC,0xC1, 0x04,0x43,0x25,0x38, 0xE9,
+ 0xCC,0xC1, 0x04,0x43,0x25,0x38, 0xEB,
+ 0xCC,0xC1, 0x04,0x43,0x25,0x38, 0xEA,
+ 0x7C,0xC1, 0x00,0x24,0xA0,0x4E, 0xE9,
+ 0x7C,0xC1, 0x00,0x24,0xC0,0x3E, 0xEB,
+ 0x7C,0xC1, 0x00,0x24,0xC0,0x3E, 0xEA,
+ 0x40,0xC1, 0xAC,0x05,0x88,0x00, 0xEB,
+ 0x90,0xC0, 0x55,0x51,0x3E,0x2B, 0xEB,
+ 0x90,0xC0, 0x55,0x51,0x3E,0x2B, 0xE9,
+ 0x90,0x82, 0x55,0x51,0x3E,0x2B, 0xEA,
+ 0x08,0xC0, 0x00,0xA0,0x00,0xB0, 0xE9,
+ 0x08,0xC0, 0x00,0xA0,0x00,0xB0, 0xEA,
+ 0x44,0xC1, 0x94,0x03,0x84,0x00, 0xEB,
+ 0x44,0xC1, 0x94,0x03,0x84,0x00, 0xE9,
+ 0x44,0x83, 0x94,0x03,0x84,0x00, 0xEA,
+ 0x38,0xC0, 0x32,0x00,0xCE,0x38, 0xEB,
+ 0x38,0xC0, 0x32,0x00,0xCE,0x38, 0xE9,
+ 0x38,0xC0, 0x32,0x00,0xCE,0x38, 0xEA
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_Cx[] = {
+ { 0xEA002008, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002208, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002038, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA002238, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA00202C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA00222C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA002040, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002240, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002010, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002210, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002018, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002218, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002000, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002200, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002028, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002228, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA00201C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00221C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00208C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00228C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA0020A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0022A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0020AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0022AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA002140, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002340, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002144, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002344, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002148, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002348, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA00217C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00237C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA002178, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA002378, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA00210C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00230C, (UINT32)~(0x0038000F), 0x00000005 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_Cx[] = {
+ { 0xEA008008, (UINT32)~(0xFF000000), 0x1C000000 },
+ { 0xEA002408, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002608, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA000808, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA000A08, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002438, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA002638, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA000838, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA000A38, (UINT32)~(0x3F00000F), 0x0700000D },
+ { 0xEA002440, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002640, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA000840, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA000A40, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002410, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA002610, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA000810, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA000A10, (UINT32)~(0xFFFF0000), 0x0D510000 },
+ { 0xEA00242C, (UINT32)~(0x00020800), 0x00020000 },
+ { 0xEA00262C, (UINT32)~(0x00020800), 0x00020000 },
+ { 0xEA00082C, (UINT32)~(0x00020800), 0x00020000 },
+ { 0xEA000A2C, (UINT32)~(0x00020800), 0x00020000 },
+ { 0xEA002418, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002618, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA000818, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA000A18, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002400, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002600, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA000800, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA000A00, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002428, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002628, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA000828, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA000A28, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA00241C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00261C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00081C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA000A1C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00248C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00268C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00088C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA000A8C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA0024A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0026A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0008A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA000AA4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0024AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0026AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0008AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA000AAC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA002540, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002740, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA000940, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA000B40, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002544, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002744, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA000944, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA000B44, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002548, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002748, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA000948, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA000B48, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA00257C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00277C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00097C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA000B7C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA002578, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA002778, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA000978, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA000B78, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA00250C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00270C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00090C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA000B0C, (UINT32)~(0x0038000F), 0x00000005 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptH_Cx[] = {
+ { 0xE9002C2C, (UINT32)~(0x00000700), 0x00000100 },
+ { 0xE9002E2C, (UINT32)~(0x00000700), 0x00000100 },
+ { 0xE9002DCC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE9002FCC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE9002D68, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002F68, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002D6C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE9002F6C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE9002D4C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE9002F4C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE9002D14, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002F14, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002D64, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002F64, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002D70, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002F70, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002C38, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9002E38, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9002D40, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9002F40, (UINT32)~(0x00800000), 0x00000000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptH_Cx[] = {
+ { 0xE90031CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE90033CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE90015CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE90017CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE9003168, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9003368, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9001568, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9001768, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE900316C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900336C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900156C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900176C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900314C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE900334C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE900154C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE900174C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE9003114, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9003314, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9001514, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9001714, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9003164, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9003364, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9001564, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9001764, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9003170, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9003370, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9001570, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9001770, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9003038, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9003238, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9001438, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9001638, (UINT32)~(0x3F00000F), 0x0700000B },
+ { 0xE9003140, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9003340, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9001540, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9001740, (UINT32)~(0x00800000), 0x00000000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptH_Cx[] = {
+ { 0xE9002E08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002C08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002A08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002808, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002608, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002408, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002208, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9002008, (UINT32)~(0xF0000100), 0xE0000100 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_MB_Cx[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00004C5A }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_MB_Cx[] = {
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA000890, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA000A90, (UINT32)~(0x0000FFFF), 0x00004C5A }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_DT_Cx[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00003E67 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_DT_Cx[] = {
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA000890, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA000A90, (UINT32)~(0x0000FFFF), 0x00003E67 }
+};
+
+IOBP_SATA_RXEQ_TABLE PchSataRxEqSharedHsioLptH_Cx[] = {
+ { 0x0400, 0xEA002154, (UINT32)~(0x00003F00) },
+ { 0x0400, 0xEA002158, (UINT32)~(0x0000003F) },
+ { 0x0500, 0xEA002354, (UINT32)~(0x00003F00) },
+ { 0x0500, 0xEA002358, (UINT32)~(0x0000003F) },
+ { 0x0401, 0xEA002154, (UINT32)~(0x3F00003F) },
+ { 0x0501, 0xEA002354, (UINT32)~(0x3F00003F) },
+ { 0x0402, 0xEA002150, (UINT32)~(0x3F000000) },
+ { 0x0402, 0xEA002154, (UINT32)~(0x003F0000) },
+ { 0x0502, 0xEA002350, (UINT32)~(0x3F000000) },
+ { 0x0502, 0xEA002354, (UINT32)~(0x003F0000) }
+};
+
+IOBP_SATA_RXEQ_TABLE PchSataRxEqHsioLptH_Cx[] = {
+ { 0x0000, 0xEA002554, (UINT32)~(0x00003F00) },
+ { 0x0000, 0xEA002558, (UINT32)~(0x0000003F) },
+ { 0x0100, 0xEA002754, (UINT32)~(0x00003F00) },
+ { 0x0100, 0xEA002758, (UINT32)~(0x0000003F) },
+ { 0x0200, 0xEA000954, (UINT32)~(0x00003F00) },
+ { 0x0200, 0xEA000958, (UINT32)~(0x0000003F) },
+ { 0x0300, 0xEA000B54, (UINT32)~(0x00003F00) },
+ { 0x0300, 0xEA000B58, (UINT32)~(0x0000003F) },
+ { 0x0001, 0xEA002554, (UINT32)~(0x3F00003F) },
+ { 0x0101, 0xEA002754, (UINT32)~(0x3F00003F) },
+ { 0x0201, 0xEA000954, (UINT32)~(0x3F00003F) },
+ { 0x0301, 0xEA000B54, (UINT32)~(0x3F00003F) },
+ { 0x0002, 0xEA002550, (UINT32)~(0x3F000000) },
+ { 0x0002, 0xEA002554, (UINT32)~(0x003F0000) },
+ { 0x0102, 0xEA002750, (UINT32)~(0x3F000000) },
+ { 0x0102, 0xEA002754, (UINT32)~(0x003F0000) },
+ { 0x0202, 0xEA000950, (UINT32)~(0x3F000000) },
+ { 0x0202, 0xEA000954, (UINT32)~(0x003F0000) },
+ { 0x0302, 0xEA000B50, (UINT32)~(0x3F000000) },
+ { 0x0302, 0xEA000B54, (UINT32)~(0x003F0000) }
+};
+
+#endif // TRAD_FLAG
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.h
new file mode 100644
index 0000000..95ebdf7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptHCx.h
@@ -0,0 +1,47 @@
+/** @file
+
+ Header file with all LPTHCx Hsio information
+
+@copyright
+ Copyright (c) 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement.
+
+**/
+
+
+#ifdef TRAD_FLAG
+#ifndef _PCH_HSIO_LPTHCX_H_
+#define _PCH_HSIO_LPTHCX_H_
+
+#define PCH_LPTH_HSIO_VER_CX 0x2C
+
+extern UINT8 PchChipsetInitTableLptH_Cx[292];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_Cx[36];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_Cx[73];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptH_Cx[20];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptH_Cx[36];
+extern IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptH_Cx[8];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_MB_Cx[2];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_MB_Cx[4];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptH_DT_Cx[2];
+extern IOBP_MMIO_TABLE_STRUCT PchSataHsioLptH_DT_Cx[4];
+extern IOBP_SATA_RXEQ_TABLE PchSataRxEqSharedHsioLptH_Cx[10];
+extern IOBP_SATA_RXEQ_TABLE PchSataRxEqHsioLptH_Cx[20];
+
+
+#endif //_PCH_HSIO_LPTHCX_H_
+#endif //TRAD_FLAG
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.c
new file mode 100644
index 0000000..85d763b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.c
@@ -0,0 +1,239 @@
+/** @file
+ Initializes all LPTLPBx Hsio structures
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement.
+
+**/
+
+#include "PchHsio.h"
+
+#ifdef ULT_FLAG
+
+UINT8 PchChipsetInitTableLptLp_Bx[] = {
+ 0xC2, 0xFB, //U16 CRC-16
+ 0x19, 0x11, //U16 Version
+ 0x20, //U8 NumEntries;
+ // HSIO Entries
+ // Offset Value EP
+ 0x0C,0xC0, 0x09,0x37,0x22,0x07, 0xE9,
+ 0x0C,0xC0, 0x09,0x37,0x22,0x07, 0xEA,
+ 0x2C,0x82, 0x00,0x0A,0x00,0x0F, 0xE9,
+ 0x40,0xC1, 0x9C,0x05,0x88,0x00, 0xEA,
+ 0x2C,0xC0, 0x00,0x0A,0x00,0x0F, 0xEA,
+ 0x98,0xC0, 0x41,0x3B,0x20,0x1F, 0xE9,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xE9,
+ 0x98,0xC0, 0x41,0x3B,0x20,0x1F, 0xEA,
+ 0x40,0xC1, 0x9C,0x05,0x88,0x00, 0xE9,
+ 0x94,0xC0, 0x55,0x60,0x40,0x47, 0xE9,
+ 0x30,0xC0, 0x00,0x0F,0x00,0x00, 0xEA,
+ 0x78,0xC1, 0x80,0x19,0x00,0x00, 0xE9,
+ 0x94,0xC0, 0x55,0x60,0x40,0x47, 0xEA,
+ 0x78,0xC1, 0x80,0x19,0x00,0x00, 0xEA,
+ 0x88,0xC0, 0x3A,0x98,0x80,0x55, 0xE9,
+ 0x88,0xC0, 0x3A,0x98,0x80,0x55, 0xEA,
+ 0x8C,0xC0, 0x46,0x20,0x78,0x0C, 0xE9,
+ 0x8C,0xC0, 0x46,0x20,0x78,0x0C, 0xEA,
+ 0x90,0xC0, 0x55,0x51,0x3E,0x2B, 0xE9,
+ 0x90,0xC0, 0x55,0x51,0x3E,0x2B, 0xEA,
+ 0xCC,0xC1, 0x04,0x43,0x00,0x38, 0xE9,
+ 0x7C,0xC1, 0x00,0x24,0xA0,0x4E, 0xE9,
+ 0xCC,0xC1, 0x04,0x43,0x00,0x38, 0xEA,
+ 0x7C,0xC1, 0x00,0x24,0xC0,0x3E, 0xEA,
+ 0xC4,0xC1, 0x00,0x02,0x00,0x00, 0xEA,
+ 0xC4,0xC1, 0x00,0x02,0x00,0x00, 0xE9,
+ 0x08,0xC0, 0x00,0xA0,0x00,0xB0, 0xE9,
+ 0x08,0xC0, 0x00,0xA0,0x00,0xB0, 0xEA,
+ 0x44,0xC1, 0x94,0x03,0x84,0x00, 0xE9,
+ 0x44,0xC1, 0x94,0x03,0x84,0x00, 0xEA,
+ 0x0C,0xC0, 0x09,0x17,0x22,0x07, 0xE9,
+ 0x0C,0xC0, 0x09,0x17,0x22,0x07, 0xEA
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptLp_Bx[] = {
+ { 0xE90021CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE90023CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE9002168, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002368, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE900216C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900236C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900214C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE900234C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE9002164, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002364, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002170, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002370, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002114, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002314, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002038, (UINT32)~(0x0000000F), 0x0000000B },
+ { 0xE9002238, (UINT32)~(0x0000000F), 0x0000000B },
+ { 0xE9002014, (UINT32)~(0x0000FE00), 0x00006600 },
+ { 0xE9002214, (UINT32)~(0x0000FE00), 0x00006600 },
+ { 0xE9002140, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9002340, (UINT32)~(0x00800000), 0x00000000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptLp_Bx[] = {
+ { 0xE90025CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE90027CC, (UINT32)~(0x00001407), 0x00001407 },
+ { 0xE9002568, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE9002768, (UINT32)~(0x01000F3C), 0x00000A28 },
+ { 0xE900242C, (UINT32)~(0x00000700), 0x00000100 },
+ { 0xE900262C, (UINT32)~(0x00000700), 0x00000100 },
+ { 0xE900256C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900276C, (UINT32)~(0x000000FF), 0x0000003F },
+ { 0xE900254C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE900274C, (UINT32)~(0x00FFFF00), 0x00120500 },
+ { 0xE9002564, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002764, (UINT32)~(0x0000F000), 0x00005000 },
+ { 0xE9002570, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002770, (UINT32)~(0x00000018), 0x00000000 },
+ { 0xE9002514, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002714, (UINT32)~(0x38000700), 0x00000100 },
+ { 0xE9002438, (UINT32)~(0x0000000F), 0x0000000B },
+ { 0xE9002638, (UINT32)~(0x0000000F), 0x0000000B },
+ { 0xE9002414, (UINT32)~(0x0000FE00), 0x00006600 },
+ { 0xE9002614, (UINT32)~(0x0000FE00), 0x00006600 },
+ { 0xE9002540, (UINT32)~(0x00800000), 0x00000000 },
+ { 0xE9002740, (UINT32)~(0x00800000), 0x00000000 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_Bx[] = {
+ { 0xEA008008, (UINT32)~(0xFF000000), 0x1C000000 },
+ { 0xEA002008, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002208, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002408, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002608, (UINT32)~(0xFFFC6108), 0xEA6C6108 },
+ { 0xEA002038, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002238, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002438, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA002638, (UINT32)~(0x0000000F), 0x0000000D },
+ { 0xEA00202C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA00222C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA00242C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA00262C, (UINT32)~(0x00020F00), 0x00020100 },
+ { 0xEA002040, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002240, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002440, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002640, (UINT32)~(0x1F000000), 0x01000000 },
+ { 0xEA002010, (UINT32)~(0xFFFF0000), 0x55510000 },
+ { 0xEA002210, (UINT32)~(0xFFFF0000), 0x55510000 },
+ { 0xEA002410, (UINT32)~(0xFFFF0000), 0x55510000 },
+ { 0xEA002610, (UINT32)~(0xFFFF0000), 0x55510000 },
+ { 0xEA002140, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002340, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002540, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002740, (UINT32)~(0x00FFFFFF), 0x00140718 },
+ { 0xEA002144, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002344, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002544, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002744, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002148, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002348, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002548, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA002748, (UINT32)~(0x00FFFFFF), 0x00140998 },
+ { 0xEA00217C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00237C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00257C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00277C, (UINT32)~(0x03000000), 0x03000000 },
+ { 0xEA00208C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00228C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00248C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA00268C, (UINT32)~(0x00FF0000), 0x00800000 },
+ { 0xEA0020A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0022A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0024A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0026A4, (UINT32)~(0x0030FF00), 0x00308300 },
+ { 0xEA0020AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0022AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0024AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA0026AC, (UINT32)~(0x00000030), 0x00000020 },
+ { 0xEA002018, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002218, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002418, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002618, (UINT32)~(0xFFFF0300), 0x38250100 },
+ { 0xEA002000, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002200, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002400, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002600, (UINT32)~(0xCF030000), 0xCF030000 },
+ { 0xEA002028, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002228, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002428, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA002628, (UINT32)~(0xFF1F0000), 0x580E0000 },
+ { 0xEA00201C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00221C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00241C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA00261C, (UINT32)~(0x00007C00), 0x00002400 },
+ { 0xEA002178, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA002378, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA002578, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA002778, (UINT32)~(0x00001F00), 0x00001800 },
+ { 0xEA00210C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00230C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00250C, (UINT32)~(0x0038000F), 0x00000005 },
+ { 0xEA00270C, (UINT32)~(0x0038000F), 0x00000005 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptLp_Bx[] = {
+ { 0xE9000808, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9000A08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9000C08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9000E08, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9001008, (UINT32)~(0xF0000100), 0xE0000100 },
+ { 0xE9001208, (UINT32)~(0xF0000100), 0xE0000100 }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_MB_Bx[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00004C5A },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00004C5A }
+};
+
+IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_DT_Bx[] = {
+ { 0xEA002090, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002290, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002490, (UINT32)~(0x0000FFFF), 0x00003E67 },
+ { 0xEA002690, (UINT32)~(0x0000FFFF), 0x00003E67 }
+};
+
+IOBP_SATA_RXEQ_TABLE PchSataRxEqSharedHsioLptLp_Bx[] = {
+ { 0x0300, 0xEA002154, (UINT32)~(0x00003F00) },
+ { 0x0300, 0xEA002158, (UINT32)~(0x0000003F) },
+ { 0x0200, 0xEA002354, (UINT32)~(0x00003F00) },
+ { 0x0200, 0xEA002358, (UINT32)~(0x0000003F) },
+ { 0x0100, 0xEA002554, (UINT32)~(0x00003F00) },
+ { 0x0100, 0xEA002558, (UINT32)~(0x0000003F) },
+ { 0x0000, 0xEA002754, (UINT32)~(0x00003F00) },
+ { 0x0000, 0xEA002758, (UINT32)~(0x0000003F) },
+ { 0x0301, 0xEA002154, (UINT32)~(0x3F00003F) },
+ { 0x0201, 0xEA002354, (UINT32)~(0x3F00003F) },
+ { 0x0101, 0xEA002554, (UINT32)~(0x3F00003F) },
+ { 0x0001, 0xEA002754, (UINT32)~(0x3F00003F) },
+ { 0x0302, 0xEA002150, (UINT32)~(0x3F000000) },
+ { 0x0302, 0xEA002154, (UINT32)~(0x003F0000) },
+ { 0x0202, 0xEA002350, (UINT32)~(0x3F000000) },
+ { 0x0202, 0xEA002354, (UINT32)~(0x003F0000) },
+ { 0x0102, 0xEA002550, (UINT32)~(0x3F000000) },
+ { 0x0102, 0xEA002554, (UINT32)~(0x003F0000) },
+ { 0x0002, 0xEA002750, (UINT32)~(0x3F000000) },
+ { 0x0002, 0xEA002754, (UINT32)~(0x003F0000) }
+};
+
+#endif // ULT_FLAG
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.h
new file mode 100644
index 0000000..d46962a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchHsioLptLpBx.h
@@ -0,0 +1,42 @@
+/** @file
+
+ Header file with all LPTLPBx Hsio information
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement.
+
+**/
+
+
+#ifdef ULT_FLAG
+#ifndef _PCH_HSIO_LPTLPBX_H_
+#define _PCH_HSIO_LPTLPBX_H_
+
+#define PCH_LPTLP_HSIO_VER_BX 0x19
+
+extern UINT8 PchChipsetInitTableLptLp_Bx[229];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3HsioLptLp_Bx[20];
+extern IOBP_MMIO_TABLE_STRUCT PchUsb3SharedHsioLptLp_Bx[22];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_Bx[73];
+extern IOBP_MMIO_TABLE_STRUCT PchGbeSharedHsioLptLp_Bx[6];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_MB_Bx[4];
+extern IOBP_MMIO_TABLE_STRUCT PchSataSharedHsioLptLp_DT_Bx[4];
+extern IOBP_SATA_RXEQ_TABLE PchSataRxEqSharedHsioLptLp_Bx[20];
+
+#endif //_PCH_HSIO_LPTLPBX_H_
+#endif //ULT_FLAG
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.c
new file mode 100644
index 0000000..5bd895a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.c
@@ -0,0 +1,31 @@
+/** @file
+ This file defines variable shared between PCH Init DXE driver and PCH
+ Init S3 Resume PEIM.
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+///
+/// Include the protocol header file
+///
+#include "PchInitVar.h"
+
+///
+/// Protocol GUID definition
+///
+EFI_GUID gPchInitPeiVariableGuid = PCH_INIT_PEI_VARIABLE_GUID;
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.h
new file mode 100644
index 0000000..7bd461b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchInitVar.h
@@ -0,0 +1,65 @@
+/** @file
+ This file defines variable shared between PCH Init DXE driver and PCH
+ Init S3 Resume PEIM.
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+#ifndef _PCH_INIT_VAR_H_
+#define _PCH_INIT_VAR_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#endif
+///
+/// Define the PCH Init Var GUID
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_INIT_PEI_VARIABLE_GUID \
+ { \
+ 0xa31b27a4, 0xcae6, 0x48ff, 0x8c, 0x5a, 0x29, 0x42, 0x21, 0xe6, 0xf3, 0x89 \
+ }
+#else
+#define PCH_INIT_PEI_VARIABLE_GUID \
+ { \
+ 0xa31b27a4, 0xcae6, 0x48ff, \
+ { \
+ 0x8c, 0x5a, 0x29, 0x42, 0x21, 0xe6, 0xf3, 0x89 \
+ } \
+ }
+#endif
+///
+/// Extern the GUID for PPI users.
+///
+extern EFI_GUID gPchInitPeiVariableGuid;
+
+#define PCH_INIT_PEI_VARIABLE_NAME L"PchInitPei"
+
+///
+/// Define the Pch Init Variable structure
+///
+
+typedef struct _PCH_LATE_INIT_SMM_VARIABLE {
+ UINT16 IoTrapAddress;
+ UINT32 PciMemBase;
+} PCH_LATE_INIT_SMM_VARIABLE;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.c
new file mode 100644
index 0000000..e53d783
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.c
@@ -0,0 +1,3032 @@
+/** @file
+ Initializes PCH USB Controllers.
+
+@copyright
+ Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchUsbCommon.h"
+#include "Token.h"
+
+const USB_CONTROLLER EhciControllersMap[PchEhciControllerMax] = {
+ {
+ PCI_DEVICE_NUMBER_PCH_USB,
+ PCI_FUNCTION_NUMBER_PCH_EHCI
+ },
+ {
+ PCI_DEVICE_NUMBER_PCH_USB_EXT,
+ PCI_FUNCTION_NUMBER_PCH_EHCI2
+ }
+};
+
+UINTN PCH_H_PORTSCxUSB2[] = {
+ R_PCH_XHCI_PORTSC01USB2,
+ R_PCH_XHCI_PORTSC02USB2,
+ R_PCH_XHCI_PORTSC03USB2,
+ R_PCH_XHCI_PORTSC04USB2,
+ R_PCH_XHCI_PORTSC05USB2,
+ R_PCH_XHCI_PORTSC06USB2,
+ R_PCH_XHCI_PORTSC07USB2,
+ R_PCH_XHCI_PORTSC08USB2,
+ R_PCH_XHCI_PORTSC09USB2,
+ R_PCH_H_XHCI_PORTSC10USB2,
+ R_PCH_H_XHCI_PORTSC11USB2,
+ R_PCH_H_XHCI_PORTSC12USB2,
+ R_PCH_H_XHCI_PORTSC13USB2,
+ R_PCH_H_XHCI_PORTSC14USB2,
+ R_PCH_H_XHCI_PORTSC15USB2
+};
+
+UINTN PCH_LP_PORTSCxUSB2[] = {
+ R_PCH_XHCI_PORTSC01USB2,
+ R_PCH_XHCI_PORTSC02USB2,
+ R_PCH_XHCI_PORTSC03USB2,
+ R_PCH_XHCI_PORTSC04USB2,
+ R_PCH_XHCI_PORTSC05USB2,
+ R_PCH_XHCI_PORTSC06USB2,
+ R_PCH_XHCI_PORTSC07USB2,
+ R_PCH_XHCI_PORTSC08USB2,
+ R_PCH_XHCI_PORTSC09USB2
+};
+
+UINTN PCH_H_PORTSCxUSB3[] = {
+ R_PCH_H_XHCI_PORTSC1USB3,
+ R_PCH_H_XHCI_PORTSC2USB3,
+ R_PCH_H_XHCI_PORTSC3USB3,
+ R_PCH_H_XHCI_PORTSC4USB3,
+ R_PCH_H_XHCI_PORTSC5USB3,
+ R_PCH_H_XHCI_PORTSC6USB3
+};
+
+UINTN PCH_LP_PORTSCxUSB3[] = {
+ R_PCH_LP_XHCI_PORTSC1USB3,
+ R_PCH_LP_XHCI_PORTSC2USB3,
+ R_PCH_LP_XHCI_PORTSC3USB3,
+ R_PCH_LP_XHCI_PORTSC4USB3
+};
+
+///
+/// Table: USB2 Pins Mapping between XHCI/EHCI Port
+/// -------------------------------------------
+/// | USB2 Pin | EHCI Port | XHCI Port |
+/// |--------------+----------------+-----------|
+/// | USB[P,N][0] | EHCI 1 Port 0 | Port 0 |
+/// | USB[P,N][1] | EHCI 1 Port 1 | Port 1 |
+/// | USB[P,N][2] | EHCI 1 Port 2 | Port 2 |
+/// | USB[P,N][3] | EHCI 1 Port 3 | Port 3 |
+/// | USB[P,N][4] | EHCI 1 Port 4 | Port 8 |
+/// | USB[P,N][5] | EHCI 1 Port 5 | Port 9 |
+/// | USB[P,N][6] | EHCI 1 Port 6 | Port 12 |
+/// | USB[P,N][7] | EHCI 1 Port 7 | Port 13 |
+/// | USB[P,N][8] | EHCI 2 Port 8 | Port 4 |
+/// | USB[P,N][9] | EHCI 2 Port 9 | Port 5 |
+/// | USB[P,N][10] | EHCI 2 Port 10 | Port 6 |
+/// | USB[P,N][11] | EHCI 2 Port 11 | Port 7 |
+/// | USB[P,N][12] | EHCI 2 Port 12 | Port 10 |
+/// | USB[P,N][13] | EHCI 2 Port 13 | Port 11 |
+/// -------------------------------------------
+///
+const UINT32 XhciUsb2InternalPortNumberLookUpTable[] = {
+ 0,1,2,3,8,9,12,13,4,5,6,7,10,11,12,13
+};
+
+/**
+ Configures PCH USB controller
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] BusNumber PCI Bus Number of the PCH device
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[out] FuncDisableReg Function Disable Register
+ @param[in] Revision The policy revision used for backward compatible check
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+CommonUsbInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMmioBase,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 BusNumber,
+ IN UINT32 RootComplexBar,
+ OUT UINT32 *FuncDisableReg,
+ IN UINT8 Revision
+ )
+{
+ UINTN PciD31F0RegBase;
+ UINTN XhciPciMmBase;
+ UINTN Ehci1PciMmBase;
+ UINTN Ehci2PciMmBase;
+ UINT16 LpcDeviceId;
+ UINT16 PmBase;
+ UINT16 RegData16 =0;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "CommonUsbInit() - Start\n"));
+
+ PchSeries = GetPchSeries();
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ XhciPciMmBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+ Ehci1PciMmBase = MmPciAddress (
+ 0,
+ BusNumber,
+ EhciControllersMap[PchEhci1].Device,
+ EhciControllersMap[PchEhci1].Function,
+ 0
+ );
+ Ehci2PciMmBase = 0;
+ if (PchSeries == PchH) {
+ Ehci2PciMmBase = MmPciAddress (
+ 0,
+ BusNumber,
+ EhciControllersMap[PchEhci2].Device,
+ EhciControllersMap[PchEhci2].Function,
+ 0
+ );
+ }
+
+ PmBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ ///
+ /// Check to disable USB Controllers
+ ///
+ if (UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_DISABLE) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_EHCI1;
+ }
+
+ if (PchSeries == PchH) {
+ if (UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_DISABLE) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_EHCI2;
+ }
+ }
+
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 13.2.3 Hiding/Disabling xHCI Controller
+ /// In some instances, the System BIOS may choose to "hide" the xHCI controller. When
+ /// the xHCI device is hidden, all high speed shareable ports should be routed to the EHCI
+ /// controller to avoid the situation where USB ports are not functioning. To hide a host
+ /// controller, the BIOS must program the Function Disable register (RCBA + 3418h). See
+ /// the PCH EDS for a description of the register.
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_XHCI;
+ }
+
+ ///
+ /// Init USB Host Controllers
+ ///
+ CommonEhciHcsInit (
+ UsbConfig,
+ EhciMmioBase,
+ BusNumber,
+ Revision,
+ LpcDeviceId,
+ RootComplexBar
+ );
+
+ ///
+ /// Assign memory resources
+ ///
+ XhciMemorySpaceOpen (
+ UsbConfig,
+ XhciMmioBase,
+ XhciPciMmBase
+ );
+
+ CommonXhciHcInit (
+ UsbConfig,
+ XhciMmioBase,
+ Revision,
+ LpcDeviceId,
+ XhciPciMmBase
+ );
+
+ ///
+ /// Init Port Switching Flow
+ ///
+ PerformXhciEhciPortSwitchingFlow (
+ UsbConfig,
+ XhciMmioBase,
+ Revision,
+ LpcDeviceId,
+ XhciPciMmBase,
+ PciD31F0RegBase
+ );
+ ///
+ /// Setup USB Over-Current Mapping.
+ ///
+ EhciOverCurrentMapping (
+ UsbConfig,
+ Ehci1PciMmBase,
+ Ehci2PciMmBase
+ );
+
+ XhciOverCurrentMapping (
+ UsbConfig,
+ XhciPciMmBase
+ );
+
+ //
+ // Tune the USB 2.0 high-speed signals quality.
+ //
+ Usb2PortLengthProgramming (
+ UsbConfig,
+ LpcDeviceId,
+ RootComplexBar
+ );
+
+ ///
+ /// Support USB Per-Port Disable Control Override feature
+ ///
+#if defined OEM_USB_PER_PORT_DISABLE_SUPPORT && OEM_USB_PER_PORT_DISABLE_SUPPORT == 0
+ if (UsbConfig->UsbPerPortCtl == PCH_DEVICE_ENABLE) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 12.2 Disabling USB Ports
+ /// The PCH USB Port Disable Override Register (D26/29:F0 + 64h) can be locked by setting
+ /// the Write Enable bit of the PCH USB Per-Port Register Write Control Register,
+ /// PMBASE + 3Ch[1].
+ ///
+ /// Open the Per-Port Disable Control Override
+ ///
+ RegData16 = IoRead16 ((UINTN) ((UINT64) (PmBase + R_PCH_UPRWC)));
+ RegData16 |= B_PCH_UPRWC_WR_EN;
+ IoWrite16 ((UINTN) ((UINT64) (PmBase + R_PCH_UPRWC)), RegData16);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PmBase + R_PCH_UPRWC),
+ 1,
+ &RegData16
+ );
+#endif
+
+ EhciPortDisableOverride (
+ UsbConfig,
+ Ehci1PciMmBase,
+ Ehci2PciMmBase
+ );
+
+ XhciPortDisableOverride (
+ UsbConfig,
+ XhciPciMmBase,
+ Revision
+ );
+
+ ///
+ /// Close the Per-Port Disable Control Override
+ ///
+ RegData16 &= (~B_PCH_UPRWC_WR_EN);
+ IoWrite16 ((UINTN) ((UINT64) (PmBase + R_PCH_UPRWC)), RegData16);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PmBase + R_PCH_UPRWC),
+ 1,
+ &RegData16
+ );
+#endif
+ }
+#endif
+ ///
+ /// Support USBR feature
+ ///
+ if (UsbConfig->Ehci1Usbr == PCH_DEVICE_ENABLE &&
+ UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) {
+ EhciUsbrEnable (Ehci1PciMmBase);
+ }
+ if (PchSeries == PchH) {
+ if (UsbConfig->Ehci2Usbr == PCH_DEVICE_ENABLE && UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) {
+ EhciUsbrEnable (Ehci2PciMmBase);
+ }
+ }
+ ///
+ /// Clear memory resources
+ ///
+ XhciMemorySpaceClose (
+ UsbConfig,
+ XhciMmioBase,
+ XhciPciMmBase
+ );
+
+ DEBUG ((EFI_D_INFO, "CommonUsbInit() - End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Performs basic configuration of PCH EHCI controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+ @param[in] BusNumber PCI Bus Number of the PCH device
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+CommonEhciHcsInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMmioBase,
+ IN UINT8 BusNumber,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINTN EhciPciMmBase;
+ UINT8 Index;
+ UINT16 PciCmd;
+ BOOLEAN SkipRst;
+ UINT32 DwordReg;
+ UINT8 NumberOfPorts;
+ EFI_STATUS Status;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ PCH_SERIES PchSeries;
+#ifndef AMI_OVERRIDE_EHCI_MMIOBASE
+ UINT32 TempMmioBase = EhciMmioBase;
+#endif
+
+ PchSeries = GetPchSeries();
+
+ for (Index = 0; Index < GetPchEhciMaxControllerNum (); Index++) {
+ EhciPciMmBase = MmPciAddress (
+ 0,
+ BusNumber,
+ EhciControllersMap[Index].Device,
+ EhciControllersMap[Index].Function,
+ 0
+ );
+
+#ifndef AMI_OVERRIDE_EHCI_MMIOBASE
+ if (EhciMmioBase != TempMmioBase)
+ EhciMmioBase = TempMmioBase;
+#endif
+ ///
+ /// Set EHCI structural parameter
+ ///
+ if (UsbConfig->Usb20Settings[Index].Enable == PCH_DEVICE_DISABLE) {
+ MmioWrite32 (EhciPciMmBase + R_PCH_EHCI_MEM_BASE, 0);
+ MmioWrite16 (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER, 0);
+ } else {
+ PciCmd = 0;
+ ///
+ /// Shared EHCI/XHCI ports w/a.
+ /// This step is required when some of the ports are routed to EHCI
+ /// and other ports are routed XHCI at the same time.
+ ///
+ /// Clear D26/D29:F0 + 78h [1:0]
+ ///
+ if (UsbConfig->Usb30Settings.ManualMode == PCH_DEVICE_ENABLE) {
+ MmioAnd16 (
+ (EhciPciMmBase + 0x78),
+ (UINT16) ~(BIT1 | BIT0));
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support DeepSx and RapidStart resume from G3 state, all resume well registers
+ /// need to be saved into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + 0x78),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x78)
+ );
+#endif
+ }
+ ///
+ /// For some cases, like usb debug mode, the Ehci memory resource will have been assigned and
+ /// enabled here. If so, then set SkipRst flag to skip the steps that are for Ehci memory
+ /// resource clear and host controller reset
+ ///
+ if ((MmioRead32 (EhciPciMmBase + R_PCH_EHCI_MEM_BASE) == 0) &&
+ !(MmioRead16 (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER) & B_PCH_EHCI_COMMAND_MSE)) {
+ MmioWrite32 ((EhciPciMmBase + R_PCH_EHCI_MEM_BASE), EhciMmioBase);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_MEM_BASE)
+ );
+#endif
+ ///
+ /// Clear SkipRst flag
+ ///
+ SkipRst = FALSE;
+ } else {
+ ///
+ /// Use the memory address of Ehci controller that has been assigned before initialization
+ /// to do the programming.
+ ///
+ EhciMmioBase = MmioRead32 (EhciPciMmBase + R_PCH_EHCI_MEM_BASE);
+ ///
+ /// Save Pci command register
+ ///
+ PciCmd = MmioRead16 (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER);
+ ///
+ /// Set SkipRst flag
+ ///
+ SkipRst = TRUE;
+ }
+
+ MmioOr16 (
+ (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER),
+ (UINT16) (B_PCH_EHCI_COMMAND_MSE | B_PCH_EHCI_COMMAND_BME)
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER)
+ );
+#endif
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 12.10
+ /// Additional Programming Requirements during USB Initialization
+ ///
+ /// Step 1
+ /// Program D29/D26:MEM_BASE + 20h [1] = 1b,
+ /// This should be done before FS/LS initialitiation and also after S4/S5
+ ///
+ /// For some cases, like usb debug mode, we will skip this step, in case something will be destroyed
+ /// after doing host controller reset
+ ///
+ if (!SkipRst) {
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Reset the EHCI when running in PEI phase where USB precondition feature is enabled
+ /// or in DXE phase where USB precondition feature is disabled
+ /// If the precondition is enabled and running in DXE phase, EHCI has reset done already
+ ///
+ if (USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ MmioOr16 ((EhciMmioBase + R_PCH_EHCI_USB2CMD), B_PCH_EHCI_USB2CMD_HCRESET);
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ }
+ ///
+ /// Step 2
+ /// Configure number of controller and port:
+ ///
+ /// Step 2.a
+ /// Set D26/D29:F0:80h [0] = 1b
+ ///
+ MmioOr16 ((EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL), (UINT16) V_PCH_EHCI_ACCESS_CNTL_ENABLE);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL)
+ );
+#endif
+ ///
+ /// Step 2.b
+ /// Set both EHCI's N_CC bit, D26 & D29 MEM_BASE + offset 04h [15:12], to 0000b
+ ///
+ MmioBitFieldWrite32 (
+ (EhciMmioBase + R_PCH_EHCI_HCSPARAMS),
+ N_PCH_EHCI_HCSPARAMS_N_CC,
+ (N_PCH_EHCI_HCSPARAMS_N_CC + 3),
+ 0
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciMmioBase + R_PCH_EHCI_HCSPARAMS),
+ 1,
+ (VOID *) (UINTN) (EhciMmioBase + R_PCH_EHCI_HCSPARAMS)
+ );
+#endif
+ ///
+ /// Step 2.c
+ /// Set both EHCI's N_PORTS bit, D26 & D29 MEM_BASE + offset 04h [3:0], to 2h
+ ///
+ NumberOfPorts = 2;
+ if (Index == PchEhci1) {
+ if (UsbConfig->Ehci1Usbr == PCH_DEVICE_ENABLE) {
+ NumberOfPorts = NumberOfPorts + 1;
+ }
+ } else {
+ if (PchSeries == PchH) {
+ if (Index == PchEhci2) {
+ if (UsbConfig->Ehci2Usbr == PCH_DEVICE_ENABLE) {
+ NumberOfPorts = NumberOfPorts + 1;
+ }
+ }
+ }
+ }
+ MmioBitFieldWrite32 (
+ (EhciMmioBase + R_PCH_EHCI_HCSPARAMS),
+ N_PCH_EHCI_HCSPARAMS_N_PORTS,
+ (N_PCH_EHCI_HCSPARAMS_N_PORTS + 3),
+ NumberOfPorts
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciMmioBase + R_PCH_EHCI_HCSPARAMS),
+ 1,
+ (VOID *) (UINTN) (EhciMmioBase + R_PCH_EHCI_HCSPARAMS)
+ );
+#endif
+ ///
+ /// Step 2.d
+ /// Clear D26/D29:F0:80h [0] to 0b
+ ///
+ MmioAnd16 ((EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL), (UINT16) (~V_PCH_EHCI_ACCESS_CNTL_ENABLE));
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_ACCESS_CNTL)
+ );
+#endif
+ ///
+ /// Step 3
+ /// Program D29/D26:F0 + 78h[2] = 1b.
+ ///
+ DwordReg = MmioRead32 (EhciPciMmBase + 0x78);
+ DwordReg |= (UINT32) (BIT2);
+ MmioWrite32 (
+ (UINTN) (EhciPciMmBase + 0x78),
+ DwordReg
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + 0x78),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x78)
+ );
+#endif
+ ///
+ /// Step 4
+ /// Program D29/D26:F0 + 7Ch[14,7] = 1b
+ ///
+ MmioOr32 (EhciPciMmBase + 0x7C, (UINT32) BIT14 | BIT7);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + 0x7C),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x7C)
+ );
+#endif
+ ///
+ /// Step 5
+ /// Program D29/D26:F0 + 8Ch[11:8] = 0100b
+ /// Step 6
+ /// Program D29/D26:F0 + 8Ch[26,17] = 0b, 1b
+ ///
+ DwordReg = MmioRead32 (EhciPciMmBase + 0x8C);
+ DwordReg |= (UINT32) (BIT17 | BIT10);
+ DwordReg &= (UINT32)~(BIT26 | BIT11 | BIT9 | BIT8);
+ MmioWrite32 (
+ (UINTN) (EhciPciMmBase + 0x8C),
+ DwordReg
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + 0x8C),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x8C)
+ );
+
+ if (SkipRst) {
+ ///
+ /// Restore Pci command register
+ ///
+ MmioWrite16 ((EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER), PciCmd);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER)
+ );
+#endif
+ } else {
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// If precondition is enabled, execute USB precondition function by each phase call
+ ///
+ if (USB_PRECONDITION_POLICY_SUPPORT (UsbConfig)) {
+ EHCI_PRECONDITION (EhciControllersMap[Index].Device, EhciMmioBase);
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Clear memory resource and command register after initialization
+ ///
+ MmioAnd16 (
+ (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER),
+ (UINT16)~(B_PCH_EHCI_COMMAND_MSE | B_PCH_EHCI_COMMAND_BME)
+ );
+ MmioWrite32 ((EhciPciMmBase + R_PCH_EHCI_MEM_BASE), 0);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_COMMAND_REGISTER)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + R_PCH_EHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + R_PCH_EHCI_MEM_BASE)
+ );
+#endif
+ }
+ }
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Execute the code if running in PEI phase when USB precondition feature is enabled
+ /// or in DXE phase when USB precondition feature disabled
+ /// If the precondition is enabled and running in DXE phase,
+ /// the code has already run once in PEI but the save S3 script need to run again in DXE phase
+ /// but only run if and only if both EHCI is not disabled
+ ///
+ if ((USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) ||
+ ((USB_RUN_IN_DXE) && ((UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) ||
+ ((UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) && (PchSeries == PchH)))))
+ {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// PCH BIOS Spec Rev 0.5.5 Section 12.10
+ /// Additional Programming Requirements during USB Initialization
+ /// Step 7
+ /// IOBP Programming:
+ /// a) Set IOBP register 0xE5007F04 to 00004481h.
+ /// b) Set IOBP register 0xE500400F[0] + (PortNumber * 0x100) = 0b.
+ /// c) Set IOBP register 0xE5007F14[20:19] to 11b.
+ /// d) Set IOBP register 0xE5007F02[23:22] to 00b for LPT-LP
+ ///
+ /// Set IOBP register 0xE5007F04[14:13] to 10b.
+ ///
+ Data32And = 0;
+ Data32Or = 0x00004481;
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5007F04,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5007F04,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ ///
+ /// Set IOBP register 0xE500400F[0] + (PortNumber * 0x100) = 0b.
+ ///
+ Data32And = (UINT32)~(BIT0);
+ Data32Or = (UINT32) (0);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE500400F + ((Index + 1) * 0x100),
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE500400F + ((Index + 1) * 0x100),
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ ///
+ /// Set IOBP register 0xE5007F14[20:19] to 11b.
+ ///
+ Data32And = (UINT32)~(0);
+ Data32Or = (UINT32) (BIT20 | BIT19);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5007F14,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5007F14,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Set IOBP register 0xE5007F02[23:22] to 00b for LPT-LP
+ ///
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(BIT23 | BIT22);
+ Data32Or = (UINT32) (0);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5007F02,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5007F02,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ return EFI_SUCCESS;
+}
+
+/**
+ Performs basic configuration of PCH USB3 (xHCI) controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of xHCI Controller
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+CommonXhciHcInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINTN XhciPciMmBase
+ )
+{
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ UINT8 PchSteppingValue;
+ PCH_SERIES PchSeries;
+
+ Data32Or = 0;
+ Data32And = 0;
+ PchSeries = GetPchSeries();
+ PchSteppingValue = PchStepping();
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 13.2.1 xHCI controller setup
+ ///
+ if (PchSeries == PchH) {
+ ///
+ /// For LPT-H Only:
+ /// USB3 ports always start at offset 16 (accounting for 15 USB2 ports) regardless of the number of USB2 ports
+ /// the XHCI spec allows there to be a gap between the highest numbered USB2 port and the lowest numbered USB3 port).
+ /// So the Maxports value is dependent entirely on the number of USB3 ports, and not upon the number of USB2 ports.
+ /// So the appropriate BIOS workaround is to look at the number of USB3 ports in the FUS register - config offset E0h.
+ /// (since there are SKUs with fewer than 6 port).
+ /// * If number of SS ports = 6, maxports = 21 (15h)
+ /// * If number of SS ports = 4, maxports = 19 (13h)
+ /// * If number of SS ports = 2, maxports = 17 (11h)
+ /// * If number of SS ports = 0, maxports = 15 (0Fh)
+ ///
+ switch (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_FUS) & B_PCH_XHCI_FUS_SSPRTCNT) {
+ case V_PCH_XHCI_FUS_SSPRTCNT_11B:
+ // Number of SS ports is 0, Set xHCIBAR + 04h[31:24] = 0Fh
+ Data32Or = 0x0F000000;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_10B:
+ // Number of SS ports is 2, Set xHCIBAR + 04h[31:24] = 11h
+ Data32Or = 0x11000000;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_01B:
+ // Number of SS ports is 4, Set xHCIBAR + 04h[31:24] = 13h
+ Data32Or = 0x13000000;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_00B:
+ default:
+ // Number of SS ports is 6, Set xHCIBAR + 04h[31:24] = 15h
+ Data32Or = 0x15000000;
+ break;
+ }
+ MmioAndThenOr32 (
+ (XhciMmioBase + R_PCH_XHCI_HCSPARAMS1),
+ (UINT32) 0x00FFFFFF,
+ (UINT32) Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + R_PCH_XHCI_HCSPARAMS1),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + R_PCH_XHCI_HCSPARAMS1)
+ );
+ }
+ ///
+ /// Set xHCIBAR + 0Ch[7:0] = 0Ah and [31:16] = 200h
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + R_PCH_XHCI_HCSPARAMS3),
+ (UINT32) 0x0000FF00,
+ (UINT32) 0x0200000A
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + R_PCH_XHCI_HCSPARAMS3),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + R_PCH_XHCI_HCSPARAMS3)
+ );
+ ///
+ /// Set xHCIBAR + 10h[10,9,5] to 1b, 1b, 0b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + R_PCH_XHCI_HCCPARAMS),
+ (UINT32)~(BIT5),
+ (UINT32) (BIT10 | BIT9)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + R_PCH_XHCI_HCCPARAMS),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + R_PCH_XHCI_HCCPARAMS)
+ );
+ if (PchSeries == PchH) {
+ ///
+ /// For LPT-H, Set xHCIBAR + 8008h[19] to 0b
+ ///
+ MmioAnd32 (
+ (XhciMmioBase + 0x8008),
+ (UINT32)~(BIT19)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8008),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8008)
+ );
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set xHCIBAR + 8058h[16,8] to 1b, 0b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8058),
+ (UINT32)~(BIT8),
+ (UINT32) (BIT16)
+ );
+ } else if (PchSeries == PchH) {
+ ///
+ /// Set xHCIBAR + 8058h[20,16,8] to 1b, 1b, 0b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8058),
+ (UINT32)~(BIT8),
+ (UINT32) (BIT20 | BIT16)
+ );
+ }
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8058),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8058)
+ );
+ ///
+ /// Set xHCIBAR + 8060h[25, 18] to 1b, 1b
+ ///
+ MmioOr32 (
+ (XhciMmioBase + 0x8060),
+ (UINT32) (BIT25 | BIT18)
+ );
+
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8060),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8060)
+ );
+ ///
+ /// Set xHCIBAR + 8090h[14,8] to 1b, 1b
+ ///
+ MmioOr32 (XhciMmioBase + 0x8090, (UINT32) (BIT14 | BIT8));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8090),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8090)
+ );
+ ///
+ /// Set xHCIBAR + 8094h[23, 21, 14] to 1b, 1b, 1b
+ ///
+ MmioOr32 (XhciMmioBase + 0x8094, (UINT32) (BIT23 | BIT21 | BIT14));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8094),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8094)
+ );
+ ///
+ /// Set xHCIBAR + 80E0h[16, 6] to 0b, 1b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x80E0),
+ (UINT32)~(BIT16),
+ (UINT32) (BIT6)
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x80E0),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x80E0)
+ );
+#endif // SUS_WELL_RESTORE
+ ///
+ /// Set xHCIBAR + 80ECh[14:12] to 00h
+ /// Set xHCIBAR + 80ECh[11:9] to 06h
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x80EC),
+ (UINT32)~(BIT14 | BIT13 | BIT12 | BIT9),
+ (UINT32) (BIT11 | BIT10)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x80EC),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x80EC)
+ );
+ ///
+ /// Set xHCIBAR + 80F0h[20] to 0b
+ ///
+ MmioAnd32 (
+ (XhciMmioBase + 0x80F0),
+ (UINT32)~(BIT20)
+ );
+#ifdef SUS_WELL_RESTORE
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x80F0),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x80F0)
+ );
+#endif // SUS_WELL_RESTORE
+ ///
+ /// For LPT-LP, Set xHCIBAR + 80FCh[25] to 1b (Note: In document it is written as bit 121 of 80F0h.)
+ ///
+ if (PchSeries == PchLp) {
+ MmioOr32 (XhciMmioBase + 0x80FC, (UINT32) (BIT25));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x80FC),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x80FC)
+ );
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Set xHCIBAR + 8110h[20,11, 8, 2] to 1b, 1b, 0b, 0b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8110),
+ (UINT32)~(BIT2 | BIT8),
+ (UINT32) (BIT20 | BIT11)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8110),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8110)
+ );
+ } else if (PchSeries == PchH) {
+ ///
+ /// Set xHCIBAR + 8110h[20,11,2] to 1b, 1b, 0b
+ ///
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8110),
+ (UINT32)~(BIT2),
+ (UINT32) (BIT20 | BIT11)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8110),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8110)
+ );
+ }
+ ///
+ /// For LPT-H , Set xHCIBAR + 8140h[31:0] to FF03C132h
+ /// For LPT-LP, Set xHCIBAR + 8140h[31:0] to FF00F03Ch
+ ///
+ if (PchSeries == PchH) {
+ Data32And = (UINT32)~(0xFFFFFFFF);
+ Data32Or = (UINT32) (0xFF03C132);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8140),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8140),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8140)
+ );
+ }
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(0xFFFFFFFF);
+ Data32Or = (UINT32) (0xFF00F03C);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8140),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8140),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8140)
+ );
+ }
+
+ ///
+ /// For LPT-LP Set xHCIBAR + 8154h[21, 13] to 0b, 1b
+ /// For LPT-H Set xHCIBAR + 8154h[21, 13] to 0b, 0b
+ ///
+ if (PchSeries == PchH) {
+ Data32And = BIT21 | BIT13;
+ Data32Or = 0;
+ } else if (PchSeries == PchLp) {
+ Data32And = BIT21;
+ Data32Or = BIT13;
+ }
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8154),
+ (UINT32)~(Data32And),
+ (UINT32) (Data32Or)
+ );
+ ///
+ /// Clear xHCIBAR + 8154h[3] to 0b
+ ///
+ MmioAnd32 (
+ (XhciMmioBase + 0x8154),
+ (UINT32)~(BIT3)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8154),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8154)
+ );
+
+ ///
+ /// For LPT-LP, Set xHCIBAR + 8164h[0,1] to 1b
+ ///
+ if (PchSeries == PchLp) {
+ MmioOr32 (XhciMmioBase + 0x8164, (UINT32) (BIT1 | BIT0));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8164),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8164)
+ );
+ }
+
+ ///
+ /// For LPT-LP, Set xHCIBAR + 8174h = 0x01400C0A
+ ///
+ if (PchSeries == PchLp) {
+ MmioWrite32 (XhciMmioBase + 0x8174, 0x01400c0a);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8174),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8174)
+ );
+ }
+ ///
+ /// For LPT-LP, Set xHCIBAR + 817Ch[31:0] to 033200A3h
+ ///
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(0xFFFFFFFF);
+ Data32Or = (UINT32) (0x033200A3);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x817C),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x817C),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x817C)
+ );
+ }
+ ///
+ /// For LPT-LP, Set xHCIBAR + 8180h[31:0] to 00CB0028h
+ ///
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(0xFFFFFFFF);
+ Data32Or = (UINT32) (0x00CB0028);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8180),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8180),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8180)
+ );
+ }
+ ///
+ /// For LPT-LP, Set xHCIBAR + 8184h[31:0] to 0064001Eh
+ ///
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(0xFFFFFFFF);
+ Data32Or = (UINT32) (0x0064001E);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x8184),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8184),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8184)
+ );
+ }
+
+ ///
+ /// Set D20:F0:44h[15,14,10,0] to 1b
+ /// Note: Only update D20:F0:44h by word since D20:F0:44h[31] is write-once bit
+ ///
+ MmioOr16 (XhciPciMmBase + 0x44, (UINT16) (BIT15 | BIT14 | BIT10 | BIT0));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + 0x44),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0x44)
+ );
+
+ ///
+ /// Set D20:F0:44h[19:16] to 1111b
+ /// Note: Update D20:F0:44h by byte to 46h since D20:F0:44h[31] is write-once bit
+ ///
+ MmioOr8 (XhciPciMmBase + 0x46, (UINT8) (BIT3 | BIT2 | BIT1 | BIT0));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (XhciPciMmBase + 0x46),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0x46)
+ );
+
+ ///
+ /// LPT-LP >= B0: BIOS must set XhciMmioBase + 0x8188[26, 24] to 1b, 1b
+ /// LPT-H >= C0: BIOS must set XhciMmioBase + 0x8188[ 24] to 1b
+ ///
+ if(((PchSeries == PchLp) && (PchSteppingValue >= LptLpB0))) {
+ MmioOr32 (XhciMmioBase + 0x8188, (UINT32) (BIT26 | BIT24));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8188),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8188)
+ );
+ } else if(((PchSeries == PchH) && (PchSteppingValue >= LptHC0))){
+ MmioOr32 (XhciMmioBase + 0x8188, (UINT32) (BIT24));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8188),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8188)
+ );
+ }
+}
+
+/**
+ Initialization XHCI Clock Gating registers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval None
+**/
+VOID
+ConfigureXhciClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT32 XhccCfg;
+ UINTN XhciPciMmBase;
+ UINT8 Data8;
+ UINT16 Data16;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+ XhciPciMmBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+ ///
+ /// Set IOBP register 0xE5004001[7:6] to 11b
+ ///
+ Data32And = (UINT32)~(0);
+ Data32Or = (UINT32) (BIT7 | BIT6);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5004001,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5004001,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// For LPT-H : Set D20:F0:40h[21,20,18,17,8] to 1b
+ /// For LPT-LP:
+ /// Set D20:F0:40h[18,17,8] to 1b.
+ /// Set D20:F0:40h[21,20,19] to 000b to disable XHCI Idle L1.
+ /// Set D20:F0:40h[21,20,19] to 110b to enable XHCI Idle L1.
+ /// Note for LPT-LP Ax stepping,
+ /// USB3 hot plug will fail after 1 hot plug removal.
+ /// BIOS implement a Setup Option to disable XHCI Idle L1 as workaround.
+ /// Option should default to enable XHCI Idle L1 to allow PCH PM testing.
+ /// User need to put the system to G3 when changing from Enable to Disable state.
+ ///
+ XhccCfg = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_XHCC1);
+ XhccCfg &= (UINT32) ~(B_PCH_XHCI_XHCC1_URD);
+ if (PchSeries == PchH) {
+ XhccCfg |= (UINT32) (BIT21 | BIT20 | BIT18 | BIT17 | BIT8);
+ } else if (PchSeries == PchLp) {
+ XhccCfg |= (UINT32) (BIT18 | BIT17 | BIT8);
+ if (PchPlatformPolicy->UsbConfig->Usb30Settings.XhciIdleL1 == PCH_DEVICE_DISABLE) {
+ XhccCfg &= (UINT32)~(BIT21 | BIT20 | BIT19);
+ } else {
+ XhccCfg |= (UINT32) (BIT21 | BIT20);
+ XhccCfg &= (UINT32)~(BIT19);
+ }
+ }
+ Data16 = (UINT16)XhccCfg;
+ Data8 = (UINT8)(XhccCfg >> 16);
+ MmioWrite16 (XhciPciMmBase + R_PCH_XHCI_XHCC1, Data16);
+ MmioWrite8 (XhciPciMmBase + R_PCH_XHCI_XHCC1 + 2, Data8);
+ ///
+ /// Set D20:F0:44h[9, 7, 3] to 1b
+ ///
+ MmioOr16 (XhciPciMmBase + 0x44, (UINT16) (BIT9 | BIT7 | BIT3));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + 0x44),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0x44)
+ );
+
+ ///
+ /// For LPT-LP, Set D20:F0:A0h[18] to 1b
+ /// For LPT-H, Set D20:F0:A0h[6] to 1b
+ ///
+ if (PchSeries == PchH) {
+ Data32Or = BIT6;
+ } else if (PchSeries == PchLp) {
+ Data32Or = BIT18;
+ }
+ MmioOr32 (XhciPciMmBase + 0xA0, (UINT32) Data32Or);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + 0xA0),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0xA0)
+ );
+ ///
+ /// Set D20:F0:A4h[13] to 0b
+ ///
+ MmioAnd32 (XhciPciMmBase + 0xA4, (UINT32)~(BIT13));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + 0xA4),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0xA4)
+ );
+}
+
+/**
+ Performs basic configuration of PCH USB3 (xHCI) controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[in] PciD31F0RegBase LPC PCI Base Address
+
+ @retval None
+**/
+VOID
+PerformXhciEhciPortSwitchingFlow (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINTN XhciPciMmBase,
+ IN UINTN PciD31F0RegBase
+ )
+{
+ UINT32 UsbPort;
+ UINTN PortResetTimeout;
+ UINTN HsPortCount;
+ UINTN HsUsbrPortCount;
+ UINTN SsPortCount;
+ UINT32 PortMask;
+ UINT8 UsbPortRouting;
+ PCH_SERIES PchSeries;
+ UINTN *PORTSCxUSB2Ptr;
+ UINTN *PORTSCxUSB3Ptr;
+ UINT32 Data32;
+
+ PchSeries = GetPchSeries();
+ PORTSCxUSB2Ptr = NULL;
+ PORTSCxUSB3Ptr = NULL;
+ switch (PchSeries) {
+ case PchLp:
+ PORTSCxUSB2Ptr = &PCH_LP_PORTSCxUSB2[0];
+ PORTSCxUSB3Ptr = &PCH_LP_PORTSCxUSB3[0];
+ break;
+
+ case PchH:
+ PORTSCxUSB2Ptr = &PCH_H_PORTSCxUSB2[0];
+ PORTSCxUSB3Ptr = &PCH_H_PORTSCxUSB3[0];
+ break;
+
+ default:
+ break;
+ }
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// Retrieves information about number of implemented xHCI ports and sets
+ /// appropriate port mask registers
+ /// Get the xHCI port number and program xHCI Port Routing Mask register
+ ///
+ GetXhciPortCountAndSetPortRoutingMask (
+ XhciPciMmBase,
+ &HsPortCount,
+ &HsUsbrPortCount,
+ &SsPortCount
+ );
+ ///
+ /// Workaround for USB2PR / USB3PR value not surviving warm reset.
+ ///
+ /// Check if Warm Reset
+ ///
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ if (USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ if (MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2) & B_PCH_LPC_GEN_PMCON_MEM_SR) {
+ ///
+ /// Restore USB Port Routing registers if OS HC Switch driver has been executed
+ ///
+ if (MmioRead32 (PciD31F0RegBase + 0xAC) & BIT16) {
+ ///
+ /// Program D20:F0:D8h[5:0] to the value of xHCI D20:F0:DCh[5:0]
+ ///
+ PortMask = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB3PRM) & (UINT32) B_PCH_XHCI_USB3PR_USB3SSENM;
+
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB3PR,
+ (UINT32)~B_PCH_XHCI_USB3PR_USB3SSEN,
+ PortMask
+ );
+ ///
+ /// Step 3
+ /// Program D20:F0:D0h[14:0] to the value of xHCI D20:F0:D4h[14:0]
+ ///
+ PortMask = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB2PRM) & (UINT32) B_PCH_XHCI_USB2PR_USB2HCSELM;
+
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB2PR,
+ (UINT32)~B_PCH_XHCI_USB2PR_USB2HCSEL,
+ PortMask
+ );
+ }
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Only clear this bit after DXE phase has finished using it.
+ /// because if we clear it too early in PEI phase
+ /// then we cannot determine if OS HC Switch driver has been executed in DXE phase.
+ ///
+ if (USB_RUN_IN_DXE || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Clear B0:D31:F0 ACh[16] to indicate finish using this bit and begin of BIOS phase of USB port routing
+ ///
+ MmioAnd32 (PciD31F0RegBase + 0xAC, (UINT32) ~BIT16);
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Do nothing for this case
+ ///
+ UsbPortRouting = USB_PR_CASE_0;
+
+ if ((UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_DISABLE) ||
+ ((UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_ENABLE) &&
+ (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_AUTO))) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0
+ /// When the BIOS does not have xHCI pre-boot software available:
+ /// Section 13.1.1.2 xHCI Enabled mode
+ /// BIOS should route the Ports to the EHCI controller and prior to OS boot
+ /// it should route the ports to the xHCI controller.
+ /// Section 13.1.1.3 xHCI Auto mode
+ /// BIOS should route the Ports to the EHCI controller
+ ///
+ /// When the BIOS has xHCI pre-boot software available:
+ /// Section 13.1.2.3 xHCI Auto mode
+ /// BIOS should route the Ports to the EHCI controller
+ ///
+ /// For above cases, BIOS should follow Section 13.2.5 to route the
+ /// USB Ports to EHCI Controller.
+ ///
+ UsbPortRouting = USB_PR_CASE_1;
+ }
+
+ if ((UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_ENABLE) &&
+ (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_ON)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0
+ /// When the BIOS has xHCI pre-boot software available:
+ /// Section 13.1.2.2 xHCI Enabled mode
+ /// BIOS should route the Ports to the xHCI controller
+ ///
+ /// For the above case, BIOS should follow Section 13.2.6 to route the
+ /// USB Ports to xHCI Controller.
+ ///
+ UsbPortRouting = USB_PR_CASE_2;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Execute if runnin in PEI phase or USB precondition feature is not enabled
+ /// If the precondition is enabled and running in DXE phase, the workaround is done already
+ ///
+ if (USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ if (MmioRead16(PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2) & B_PCH_LPC_GEN_PMCON_MEM_SR) {
+ ///
+ /// Step 3
+ /// Initiate warm reset to all USB3 ports
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_WPR
+ );
+ }
+ ///
+ /// 3.c. Poll for warm reset bit at steps #a to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB3Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB3_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Execute if runnin in PEI phase or USB precondition feature is not enabled
+ /// If the precondition is enabled and running in DXE phase, the workaround is done already
+ ///
+ if (USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ if ((SsPortCount != 0) &&
+ (UsbPortRouting == USB_PR_CASE_1) &&
+ ((MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB2PR) != 0) ||
+ (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB3PR) != 0))) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.2.5 Routing of switchable USB Ports to
+ /// EHCI Controller
+ /// Step 1
+ /// Retrieve information about the number of implemented xHCI ports and set appropriate
+ /// port mask registers
+ /// Done in GetXhciPortCountAndSetPortRoutingMask()
+ /// Step 2
+ /// Based on available number of ports (from step 1) initiate port reset to enabled ports
+ /// where USB 2.0 device is connected
+ ///
+ /// 2.a. For Port #1, if xHCIBAR + 480h [0] is sets then
+ /// 2.b. Issue port reset by sets xHCIBAR + 480h [4] to 1b
+ /// 2.f. Repeat steps #a to #e for all the USB2.0 ports.
+ ///
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ if (MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]) & B_PCH_XHCI_PORTSCXUSB2_CCS) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ (UINT32)~(B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_PR
+ );
+ }
+ }
+ ///
+ /// 2.c. Poll for port reset bit at steps #b to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB2_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ ///
+ /// 2.d. Program D20:F0:D0h[14:0] to 0
+ ///
+ MmioAnd32 (
+ XhciPciMmBase + R_PCH_XHCI_USB2PR,
+ (UINT32)~B_PCH_XHCI_USB2PR_USB2HCSEL
+ );
+ ///
+ /// 2.e. Clear all the port's status by program xHCIBAR + 480h [23:17] to 1111111b
+ ///
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_CEC |
+ B_PCH_XHCI_PORTSCXUSB2_PLC |
+ B_PCH_XHCI_PORTSCXUSB2_PRC |
+ B_PCH_XHCI_PORTSCXUSB2_OCC |
+ B_PCH_XHCI_PORTSCXUSB2_WRC |
+ B_PCH_XHCI_PORTSCXUSB2_PEC |
+ B_PCH_XHCI_PORTSCXUSB2_CSC
+ );
+ }
+ if (HsUsbrPortCount > 0) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[HsPortCount],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_CEC |
+ B_PCH_XHCI_PORTSCXUSB2_PLC |
+ B_PCH_XHCI_PORTSCXUSB2_PRC |
+ B_PCH_XHCI_PORTSCXUSB2_OCC |
+ B_PCH_XHCI_PORTSCXUSB2_WRC |
+ B_PCH_XHCI_PORTSCXUSB2_PEC |
+ B_PCH_XHCI_PORTSCXUSB2_CSC
+ );
+ }
+ ///
+ /// Step 3
+ /// Initiate warm reset to all USB 3.0 ports
+ ///
+ /// 3.a. For Port #1, sets xHCIBAR + 570h [31]
+ /// 3.e. Repeat steps #a to #e for all the USB3.0 ports.
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_WPR
+ );
+ }
+ ///
+ /// 3.b. Program D20:F0:D8h[5:0] to 0h.
+ ///
+ MmioAnd32 (
+ XhciPciMmBase + R_PCH_XHCI_USB3PR,
+ (UINT32)~B_PCH_XHCI_USB3PR_USB3SSEN
+ );
+ ///
+ /// 3.c. Poll for warm reset bit at steps #a to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB3Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB3_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ ///
+ /// 3.d. Clear all the port's status by program xHCIBAR + 570h [23:17] to 1111111b.
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_CEC |
+ B_PCH_XHCI_PORTSCXUSB3_PLC |
+ B_PCH_XHCI_PORTSCXUSB3_PRC |
+ B_PCH_XHCI_PORTSCXUSB3_OCC |
+ B_PCH_XHCI_PORTSCXUSB3_WRC |
+ B_PCH_XHCI_PORTSCXUSB3_PEC |
+ B_PCH_XHCI_PORTSCXUSB3_CSC
+ );
+ }
+ ///
+ /// Step 4
+ /// Set the Run bit of xHCI controller, xHCIBAR +80h[0] to 1b
+ ///
+ MmioOr32 (
+ XhciMmioBase + R_PCH_XHCI_USBCMD,
+ B_PCH_XHCI_USBCMD_RS
+ );
+ ///
+ /// Step 5
+ /// Then clear the Run bit of xHCI controller, xHCIBAR +80h[0] to 0b
+ ///
+ MmioAnd32 (
+ XhciMmioBase + R_PCH_XHCI_USBCMD,
+ (UINT32)~B_PCH_XHCI_USBCMD_RS
+ );
+ } else if ((SsPortCount != 0) && (UsbPortRouting == USB_PR_CASE_2)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.2.6 Routing of switchable USB Ports to
+ /// xHCI Controller
+ /// Step 1
+ /// Retrieve information about the number of implemented xHCI ports and set appropriate
+ /// port mask registers
+ /// Done in GetXhciPortCountAndSetPortRoutingMask()
+ /// Step 2
+ /// Program D20:F0:D8h[5:0] to the value of xHCI D20:F0:DCh[5:0]
+ ///
+ PortMask = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB3PRM) & (UINT32) B_PCH_XHCI_USB3PR_USB3SSENM;
+
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB3PR,
+ (UINT32)~B_PCH_XHCI_USB3PR_USB3SSEN,
+ PortMask
+ );
+ ///
+ /// Step 3
+ /// Program D20:F0:D0h[14:0] to the value of xHCI D20:F0:D4h[14:0]
+ ///
+ PortMask = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB2PRM) & (UINT32) B_PCH_XHCI_USB2PR_USB2HCSELM;
+
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB2PR,
+ (UINT32)~B_PCH_XHCI_USB2PR_USB2HCSEL,
+ PortMask
+ );
+ } else if (SsPortCount != 0) {
+ //
+ // Check if Warm Reset
+ //
+ if (MmioRead16(PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2) & B_PCH_LPC_GEN_PMCON_MEM_SR) {
+ ///
+ /// Step 3
+ /// Initiate warm reset to all USB3 ports
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_WPR
+ );
+ }
+ ///
+ /// 3.c. Poll for warm reset bit at steps #a to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB3Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB3_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ }
+ }
+ if (UsbConfig->Usb30Settings.ManualMode == PCH_DEVICE_ENABLE) {
+ ///
+ /// Using the similar method as
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.2.5 Routing of switchable USB Ports to
+ /// EHCI Controller
+ /// Step 1
+ /// Retrieve information about the number of implemented xHCI ports and set appropriate
+ /// port mask registers
+ /// Done in GetXhciPortCountAndSetPortRoutingMask()
+ /// Step 2
+ /// Based on available number of ports (from step 1) initiate port reset to enabled ports
+ /// where USB 2.0 device is connected
+ ///
+ /// 2.a. For Port #1, if xHCIBAR + 480h [0] is sets then
+ /// 2.b. Issue port reset by sets xHCIBAR + 480h [4] to 1b
+ /// 2.f. Repeat steps #a to #e for all the USB2.0 ports.
+ ///
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ if (MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]) & B_PCH_XHCI_PORTSCXUSB2_CCS) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ (UINT32)~(B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_PR
+ );
+ }
+ }
+ ///
+ /// 2.c. Poll for port reset bit at steps #b to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB2_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ ///
+ /// 2.d. Program D20:F0:D0h[14:0] manually
+ ///
+ PortMask = 0;
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ if (UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[UsbPort]==1) { // 0: EHCI; 1 :XHCI;
+ PortMask |= 1 << UsbPort;
+ }
+ }
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB2PR,
+ (UINT32)~B_PCH_XHCI_USB2PR_USB2HCSEL,
+ PortMask
+ );
+ ///
+ /// 2.e. Clear all the port's status by program xHCIBAR + 480h [23:17] to 1111111b
+ ///
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_CEC |
+ B_PCH_XHCI_PORTSCXUSB2_PLC |
+ B_PCH_XHCI_PORTSCXUSB2_PRC |
+ B_PCH_XHCI_PORTSCXUSB2_OCC |
+ B_PCH_XHCI_PORTSCXUSB2_WRC |
+ B_PCH_XHCI_PORTSCXUSB2_PEC |
+ B_PCH_XHCI_PORTSCXUSB2_CSC
+ );
+ }
+ if (HsUsbrPortCount > 0) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[HsPortCount],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB2_PED),
+ B_PCH_XHCI_PORTSCXUSB2_CEC |
+ B_PCH_XHCI_PORTSCXUSB2_PLC |
+ B_PCH_XHCI_PORTSCXUSB2_PRC |
+ B_PCH_XHCI_PORTSCXUSB2_OCC |
+ B_PCH_XHCI_PORTSCXUSB2_WRC |
+ B_PCH_XHCI_PORTSCXUSB2_PEC |
+ B_PCH_XHCI_PORTSCXUSB2_CSC
+ );
+ }
+ ///
+ /// Step 3
+ /// Initiate warm reset to all USB 3.0 ports
+ ///
+ /// 3.a. For Port #1, sets xHCIBAR + 570h [31]
+ /// 3.e. Repeat steps #a to #e for all the USB3.0 ports.
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_WPR
+ );
+ }
+ ///
+ /// 3.b. Program D20:F0:D8h[5:0] manually.
+ ///
+ PortMask = 0;
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ if (UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[UsbPort]==1) { // 0: Disable; 1:Enable;
+ PortMask |= 1 << UsbPort;
+ }
+ }
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB3PR,
+ (UINT32)~B_PCH_XHCI_USB3PR_USB3SSEN,
+ PortMask
+ );
+ ///
+ /// 3.c. Poll for warm reset bit at steps #a to be cleared or timeout at 100ms
+ ///
+ PortResetTimeout = 0;
+ do {
+ Data32 = 0;
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ Data32 |= MmioRead32 (XhciMmioBase + PORTSCxUSB3Ptr[UsbPort]);
+ }
+ PchPmTimerStall (TEN_MS_TIMEOUT);
+ PortResetTimeout++;
+ } while ((Data32 & B_PCH_XHCI_PORTSCXUSB3_PR) &&
+ (PortResetTimeout < PORT_RESET_TIMEOUT));
+ ///
+ /// 3.d. Clear all the port's status by program xHCIBAR + 570h [23:17] to 1111111b.
+ ///
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_PED),
+ B_PCH_XHCI_PORTSCXUSB3_CEC |
+ B_PCH_XHCI_PORTSCXUSB3_PLC |
+ B_PCH_XHCI_PORTSCXUSB3_PRC |
+ B_PCH_XHCI_PORTSCXUSB3_OCC |
+ B_PCH_XHCI_PORTSCXUSB3_WRC |
+ B_PCH_XHCI_PORTSCXUSB3_PEC |
+ B_PCH_XHCI_PORTSCXUSB3_CSC
+ );
+ }
+ ///
+ /// Step 4
+ /// Set the Run bit of xHCI controller, xHCIBAR + 80h[0] to 1b
+ ///
+ MmioOr32 (
+ XhciMmioBase + R_PCH_XHCI_USBCMD,
+ (UINT32) B_PCH_XHCI_USBCMD_RS
+ );
+ ///
+ /// Step 5
+ /// Then clear the Run bit of xHCI controller, xHCIBAR + 80h[0] to 0b
+ ///
+ MmioAnd32 (
+ XhciMmioBase + R_PCH_XHCI_USBCMD,
+ (UINT32) ~B_PCH_XHCI_USBCMD_RS
+ );
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, XHCI USB3 PR resume well registers
+ /// get save into S3 Script table only when not running in Auto/Smart Auto mode.
+ ///
+ if (((UsbConfig->Usb30Settings.ManualMode == PCH_DEVICE_ENABLE)) ||
+ ((UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_ENABLE) &&
+ (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_ON))) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PR),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PR)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PR),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PR)
+ );
+ }
+#endif
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Check if XHCI disabled or auto even no preboot support, exit function directly
+ ///
+ if ((UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) ||
+ (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_AUTO) ||
+ (UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_DISABLE)
+ ) {
+ return;
+ }
+ ///
+ /// If precondition is enabled, execute USB precondition function by each phase call
+ ///
+ if (USB_PRECONDITION_POLICY_SUPPORT (UsbConfig)) {
+ XHCI_PRECONDITION (
+ (UINT8) ((XhciPciMmBase >> 20) &0xFF),
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ XhciMmioBase,
+ PORTSCxUSB2Ptr,
+ HsPortCount,
+ PORTSCxUSB3Ptr,
+ SsPortCount
+ );
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+}
+
+/**
+ Retrieves information about number of implemented xHCI ports
+ and sets appropriate port mask registers.
+
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[out] HsPortCount Count of High Speed Ports
+ @param[out] HsUsbrPortCount Count of USBr Port
+ @param[out] SsPortCount Count of Super Speed Ports
+
+ @retval None
+**/
+VOID
+GetXhciPortCountAndSetPortRoutingMask (
+ IN UINTN XhciPciMmBase,
+ OUT UINTN *HsPortCount,
+ OUT UINTN *HsUsbrPortCount,
+ OUT UINTN *SsPortCount
+ )
+{
+ UINT32 HsPortEnableMask;
+ UINT32 SsPortEnableMask;
+ PCH_SERIES PchSeries;
+
+ HsPortEnableMask = 0;
+ SsPortEnableMask = 0;
+ PchSeries = GetPchSeries();
+ ///
+ /// PCH BIOS Spec Rev 0.5.0
+ /// Section 13.2.5 Routing of switchable USB Ports to EHCI Controller
+ /// Section 13.2.6 Routing of switchable USB Ports to xHCI Controller
+ ///
+ if (PchSeries == PchH) {
+ ///
+ /// Step 1.a Check xHCI D20:F0:E0h[2:1] to get HS Port Count.
+ ///
+ switch (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_FUS) & B_PCH_XHCI_FUS_HSPRTCNT) {
+ case V_PCH_XHCI_FUS_HSPRTCNT_11B:
+ ///
+ /// If the value is 11b: Set xHCI D20:F0:D4h[13:0] to 00FFh. Number of HS ports is 8.
+ ///
+ *HsPortCount = V_PCH_H_XHCI_FUS_HSPRTCNT_11B_CNT;
+ HsPortEnableMask = V_PCH_H_XHCI_FUS_HSPRTCNT_11B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_HSPRTCNT_10B:
+ ///
+ /// If the value is 10b: Set xHCI D20:F0:D4h[13:0] to 0FFFh. Number of HS ports is 10.
+ /// It is work around. Bit 6 and 7 have to be set to 1 to enable USB2 ports.
+ ///
+ *HsPortCount = V_PCH_H_XHCI_FUS_HSPRTCNT_10B_CNT;
+ HsPortEnableMask = V_PCH_H_XHCI_FUS_HSPRTCNT_10B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_HSPRTCNT_01B:
+ ///
+ /// If the value is 01b: Set xHCI D20:F0:D4h[13:0] to 3FFFh. Number of HS ports is 12.
+ /// It is work around. Bit 6 and 7 have to be set to 1 to enable USB2 ports.
+ ///
+ *HsPortCount = V_PCH_H_XHCI_FUS_HSPRTCNT_01B_CNT;
+ HsPortEnableMask = V_PCH_H_XHCI_FUS_HSPRTCNT_01B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_HSPRTCNT_00B:
+ ///
+ /// If the value is 00b: Set xHCI D20:F0:D4h[13:0] to 3FFFh. Number of HS ports is 14
+ ///
+ default:
+ *HsPortCount = V_PCH_H_XHCI_FUS_HSPRTCNT_00B_CNT;
+ HsPortEnableMask = V_PCH_H_XHCI_FUS_HSPRTCNT_00B_MASK;
+ break;
+ }
+ ///
+ /// Step 1.b Check xHCI D20:F0:E0h[4:3] to get SS Port Count.
+ ///
+ switch (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_FUS) & B_PCH_XHCI_FUS_SSPRTCNT) {
+ case V_PCH_XHCI_FUS_SSPRTCNT_11B:
+ ///
+ /// If the value is 11b: Set xHCI D20:F0:DCh[5:0] to 000000b. Number of SS ports is 0.
+ ///
+ *SsPortCount = V_PCH_H_XHCI_FUS_SSPRTCNT_11B_CNT;
+ SsPortEnableMask = V_PCH_H_XHCI_FUS_SSPRTCNT_11B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_10B:
+ ///
+ /// If the value is 10b: Set xHCI D20:F0:DCh[5:0] to 000011b. Number of SS ports is 2.
+ ///
+ *SsPortCount = V_PCH_H_XHCI_FUS_SSPRTCNT_10B_CNT;
+ SsPortEnableMask = V_PCH_H_XHCI_FUS_SSPRTCNT_10B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_01B:
+ ///
+ /// If the value is 01b: Set xHCI D20:F0:DCh[5:0] to 001111b. Number of SS ports is 4.
+ ///
+ *SsPortCount = V_PCH_H_XHCI_FUS_SSPRTCNT_01B_CNT;
+ SsPortEnableMask = V_PCH_H_XHCI_FUS_SSPRTCNT_01B_MASK;
+ break;
+
+ case V_PCH_XHCI_FUS_SSPRTCNT_00B:
+ ///
+ /// If the value is 00b: Set xHCI D20:F0:DCh[5:0] to 111111b. Number of SS ports is 6.
+ ///
+ default:
+ *SsPortCount = V_PCH_H_XHCI_FUS_SSPRTCNT_00B_CNT;
+ SsPortEnableMask = V_PCH_H_XHCI_FUS_SSPRTCNT_00B_MASK;
+ break;
+ }
+ ///
+ /// Step 1.c Check xHCI D20:F0:E0h[5] to know if USBr is enabled.
+ /// @todo Need more comments to understand this
+ ///
+ switch (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_FUS) & B_PCH_XHCI_FUS_USBR) {
+ case V_PCH_XHCI_FUS_USBR_EN:
+ ///
+ /// If 0b: Set xHCI D20:F0:D4[14] to 1b. USBr port is enabled.
+ ///
+ *HsUsbrPortCount = 1;
+ HsPortEnableMask |= BIT14;
+ break;
+
+ case V_PCH_XHCI_FUS_USBR_DIS:
+ ///
+ /// If 1b: Set xHCI D20:F0:D4[14] to 0b. USBr port is disabled.
+ ///
+ *HsUsbrPortCount = 0;
+ HsPortEnableMask &= (~BIT14);
+ break;
+ }
+ } else if (PchSeries == PchLp) {
+ ///
+ /// Step 1.a LPT-LP has a fixed number of 8 HS ports. Set xHCI D20:F0:D4h[13:0] to 00FFh.
+ ///
+ *HsPortCount = V_PCH_LP_XHCI_FIXED_HSPRTCNT;
+ HsPortEnableMask = V_PCH_LP_XHCI_FIXED_HSPRTCNT_MASK;
+ ///
+ /// Step 1.b LPT-LP has a fixed number of 4 SS ports. Set xHCI D20:F0:DCh[3:0] to 0Fh.
+ ///
+ *SsPortCount = V_PCH_LP_XHCI_FIXED_SSPRTCNT;
+ SsPortEnableMask = V_PCH_LP_XHCI_FIXED_SSPRTCNT_MASK;
+ ///
+ /// Step 1.c Check xHCI D20:F0:E0h[5] to know if USBr is enabled.
+ /// @todo Need more comments to understand this
+ ///
+ switch (MmioRead32 (XhciPciMmBase + R_PCH_XHCI_FUS) & B_PCH_XHCI_FUS_USBR) {
+ case V_PCH_XHCI_FUS_USBR_EN:
+ ///
+ /// If 0b: Set xHCI D20:F0:D4[8] to 1b. USBr port is enabled.
+ ///
+ *HsUsbrPortCount = 1;
+ HsPortEnableMask |= BIT8;
+ break;
+
+ case V_PCH_XHCI_FUS_USBR_DIS:
+ ///
+ /// If 1b: Set xHCI D20:F0:D4[8] to 0b. USBr port is disabled.
+ ///
+ *HsUsbrPortCount = 0;
+ HsPortEnableMask &= (~BIT8);
+ break;
+ }
+ }
+
+ //Routing the USB ports 12, 8, and 5 to EHCI to avoid OC detection when wakening up from S3
+
+ #ifdef UPSERVER_SUPPORT
+ HsPortEnableMask &=~(BIT12|BIT8|BIT5);
+ #endif
+
+ ///
+ /// Set xHCI USB2 Port Routing Mask register (D20:F0:D4h[14:0])
+ /// per HS Port Enable Mask value
+ ///
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB2PRM,
+ ~ (UINT32) B_PCH_XHCI_USB2PR_USB2HCSELM,
+ HsPortEnableMask
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PRM),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PRM)
+ );
+ ///
+ /// Set xHCI USB3 Port Routing Mask register (D20:F0:DCh[5:0])
+ /// per SS Port Enable Mask value
+ ///
+ MmioAndThenOr32 (
+ XhciPciMmBase + R_PCH_XHCI_USB3PRM,
+ ~ (UINT32) B_PCH_XHCI_USB3PR_USB3SSENM,
+ SsPortEnableMask
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PRM),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PRM)
+ );
+}
+
+/**
+ Setup XHCI Over-Current Mapping
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciOverCurrentMapping (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN XhciPciMmBase
+ )
+{
+ ///
+ /// BIOS responsibility on Overcurrent protection.
+ /// ----------------------------------------------
+ /// There are 8 total overcurrent pins
+ /// which can be map to 14 USB2 ports and 6 USB3 ports.
+ /// On a given physical connector,
+ /// one OC pin is shared between the USB2 (HS) pins and USB3 (SS) pins.
+ /// USB2 (HS) pins are programmable to be owned by either XHCI or EHCI.
+ /// OC pins are associated to the current owner.
+ /// USB2 (HS) ports 1-8 use OC pins 1-4, ports 9-14 use OC pins 4-8
+ /// USB3 (SS) ports has the flexibility in pairing with any of the OC pins.
+ /// It is ok to map multiple ports to a single pin.
+ /// It is not ok to map a single ports to a multiple pins.
+ /// All USB ports routed out of the package must have Overcurrent protection.
+ /// USB Ports not routed out from the package should not be assigned OC pins.
+ ///
+ UINT32 Index;
+ UINT32 CurrentIndex;
+ UINT32 XhciHsOcm1;
+ UINT32 XhciHsOcm2;
+ UINT32 XhciSsOcm1;
+ UINT32 XhciSsOcm2;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// Find the corresponding register and set the bits
+ ///
+ XhciHsOcm1 = 0;
+ XhciHsOcm2 = 0;
+ XhciSsOcm1 = 0;
+ XhciSsOcm2 = 0;
+
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ if (UsbConfig->Usb20OverCurrentPins[Index] == PchUsbOverCurrentPinSkip) {
+ ///
+ /// No OC pin assigned, skip this port
+ ///
+ } else {
+ if (Index < 8) {
+ ///
+ /// Port 0-7: OC0 - OC3
+ ///
+ if (UsbConfig->Usb20OverCurrentPins[Index] > PchUsbOverCurrentPin3) {
+ ASSERT (FALSE);
+ continue;
+ }
+
+ CurrentIndex = UsbConfig->Usb20OverCurrentPins[Index] * 8 + Index;
+ XhciHsOcm1 |= (UINT32) (BIT0 << CurrentIndex);
+ } else {
+ ///
+ /// Port 8-13: OC4 - OC7
+ ///
+ if ((UsbConfig->Usb20OverCurrentPins[Index] < PchUsbOverCurrentPin4) ||
+ (UsbConfig->Usb20OverCurrentPins[Index] > PchUsbOverCurrentPin7)) {
+ ASSERT (FALSE);
+ continue;
+ }
+
+ CurrentIndex = (UsbConfig->Usb20OverCurrentPins[Index] - 4) * 8 + (Index - 8);
+ XhciHsOcm2 |= (UINT32) (BIT0 << CurrentIndex);
+ }
+ }
+ }
+
+ for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) {
+ if (UsbConfig->Usb30OverCurrentPins[Index] == PchUsbOverCurrentPinSkip) {
+ ///
+ /// No OC pin assigned, skip this port
+ ///
+ } else {
+ ///
+ /// Port 0-5: OC0 - OC7
+ ///
+ if (UsbConfig->Usb30OverCurrentPins[Index] < PchUsbOverCurrentPin4) {
+ CurrentIndex = UsbConfig->Usb30OverCurrentPins[Index] * 8 + Index;
+ XhciSsOcm1 |= (UINT32) (BIT0 << CurrentIndex);
+ } else {
+ CurrentIndex = (UsbConfig->Usb30OverCurrentPins[Index] - 4) * 8 + Index;
+ XhciSsOcm2 |= (UINT32) (BIT0 << CurrentIndex);
+ }
+ }
+ }
+ ///
+ /// OCM registers are in the suspend well.
+ ///
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_U2OCM1, XhciHsOcm1);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_U3OCM1, XhciSsOcm1);
+ if (PchSeries == PchH) {
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_U2OCM2, XhciHsOcm2);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_U3OCM2, XhciSsOcm2);
+ }
+
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_U2OCM1),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_U2OCM1)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_U3OCM1),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_U3OCM1)
+ );
+ if (PchSeries == PchH) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_U2OCM2),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_U2OCM2)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_U3OCM2),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_U3OCM2)
+ );
+ }
+#endif // SUS_WELL_RESTORE
+}
+
+/**
+ Setup EHCI Over-Current Mapping
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] Ehci1PciMmBase EHCI 1 PCI Base Address
+ @param[in] Ehci2PciMmBase EHCI 2 PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciOverCurrentMapping (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN Ehci1PciMmBase,
+ IN UINTN Ehci2PciMmBase
+ )
+{
+ UINT32 Index;
+ UINT32 CurrentIndex;
+ UINT32 Ehci1Ocm;
+ UINT32 Ehci2Ocm;
+ PCH_SERIES PchSeries;
+
+ Ehci1Ocm = 0;
+ Ehci2Ocm = 0;
+ PchSeries = GetPchSeries();
+
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ if (UsbConfig->Usb20OverCurrentPins[Index] == PchUsbOverCurrentPinSkip) {
+ ///
+ /// No OC pin assigned, skip this port
+ ///
+ } else {
+ if (Index < 8) {
+ ///
+ /// Port 0~7 -> OC0~3
+ ///
+ if (UsbConfig->Usb20OverCurrentPins[Index] > PchUsbOverCurrentPin3) {
+ ASSERT (FALSE);
+ continue;
+ }
+
+ CurrentIndex = UsbConfig->Usb20OverCurrentPins[Index] * 8 + Index;
+ Ehci1Ocm |= (UINT32) (BIT0 << CurrentIndex);
+ } else {
+ if (PchSeries == PchH) {
+ ///
+ /// Port 8~13 -> OC4~7
+ ///
+ if ((UsbConfig->Usb20OverCurrentPins[Index] < PchUsbOverCurrentPin4) ||
+ (UsbConfig->Usb20OverCurrentPins[Index] > PchUsbOverCurrentPin7)) {
+ ASSERT (FALSE);
+ continue;
+ }
+ CurrentIndex = (UsbConfig->Usb20OverCurrentPins[Index] - 4) * 8 + (Index - 8);
+ Ehci2Ocm |= (UINT32) (BIT0 << CurrentIndex);
+ }
+ }
+ }
+ }
+ ///
+ /// EHCI1OCM and EHCI2OCM are in the suspend well.
+ ///
+ if (UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) {
+ MmioWrite32 (Ehci1PciMmBase + R_PCH_EHCI_OCMAP, Ehci1Ocm);
+ }
+
+ if (PchSeries == PchH) {
+ if (UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) {
+ MmioWrite32 (Ehci2PciMmBase + R_PCH_EHCI_OCMAP, Ehci2Ocm);
+ }
+ }
+
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ if (UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (Ehci1PciMmBase + R_PCH_EHCI_OCMAP),
+ 1,
+ (VOID *) (UINTN) (Ehci1PciMmBase + R_PCH_EHCI_OCMAP)
+ );
+ }
+
+ if (PchSeries == PchH) {
+ if (UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (Ehci2PciMmBase + R_PCH_EHCI_OCMAP),
+ 1,
+ (VOID *) (UINTN) (Ehci2PciMmBase + R_PCH_EHCI_OCMAP)
+ );
+ }
+ }
+#endif
+}
+
+/**
+ Program Ehci Port Disable Override
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] Ehci1PciMmBase EHCI 1 PCI Base Address
+ @param[in] Ehci2PciMmBase EHCI 2 PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciPortDisableOverride (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN Ehci1PciMmBase,
+ IN UINTN Ehci2PciMmBase
+ )
+{
+ UINT32 Index;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 12.2 Disabling USB Ports
+ /// System BIOS may choose to disable individual USB ports to save power or for security
+ /// purposes. Each of the USB ports has a corresponding bit within the PCH USB Port
+ /// Disable Override Register (D26/29:F0 + 64h). The PCH USB Port Disable Override
+ /// Register can be locked by setting the Write Enable bit of the PCH USB Per-Port Register
+ /// Write Control Register, PMBASE + 3Ch[1]. Refer to the PCH EDS for more details on
+ /// these registers.
+ ///
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ if ((Index < 8) && (UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE)) {
+ ///
+ /// EHCI1 PDO for Port 0 to 7
+ ///
+ if (UsbConfig->PortSettings[Index].Enable == PCH_DEVICE_DISABLE) {
+ MmioOr8 (Ehci1PciMmBase + R_PCH_EHCI_PDO, (UINT8) (B_PCH_EHCI_PDO_DIS_PORT0 << Index));
+ } else {
+ MmioAnd8 (Ehci1PciMmBase + R_PCH_EHCI_PDO, (UINT8) ~(B_PCH_EHCI_PDO_DIS_PORT0 << Index));
+ }
+ }
+ if (PchSeries == PchH) {
+ if ((Index < 14) && (UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE)) {
+ ///
+ /// EHCI2 PDO for Port 8 to 13
+ ///
+ if (UsbConfig->PortSettings[Index].Enable == PCH_DEVICE_DISABLE) {
+ MmioOr8 (Ehci2PciMmBase + R_PCH_EHCI_PDO, (UINT8) (B_PCH_EHCI_PDO_DIS_PORT0 << (Index - 8)));
+ } else {
+ MmioAnd8 (Ehci2PciMmBase + R_PCH_EHCI_PDO, (UINT8) ~(B_PCH_EHCI_PDO_DIS_PORT0 << (Index - 8)));
+ }
+ }
+ }
+ }
+
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ if (UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (Ehci1PciMmBase + R_PCH_EHCI_PDO),
+ 1,
+ (VOID *) (UINTN) (Ehci1PciMmBase + R_PCH_EHCI_PDO)
+ );
+ }
+
+ if (PchSeries == PchH) {
+ if (UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) {
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (Ehci2PciMmBase + R_PCH_EHCI_PDO),
+ 1,
+ (VOID *) (UINTN) (Ehci2PciMmBase + R_PCH_EHCI_PDO)
+ );
+ }
+ }
+#endif // SUS_WELL_RESTORE
+}
+
+/**
+ Program Xhci Port Disable Override
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[in] Revision Platform policy revision
+
+ @retval None
+**/
+VOID
+XhciPortDisableOverride (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN XhciPciMmBase,
+ IN UINT8 Revision
+ )
+{
+ UINT32 Index;
+ UINT32 XhciUsb2Pdo;
+ UINT32 XhciUsb3Pdo;
+ UINT32 XhciIndex;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.2.2 Port Disable Override
+ /// In LynxPoint PCH, Port disable override on xHCI ports is implemented by mapping the
+ /// appropriate ports to the EHCI controller and then setting the port disable override in
+ /// the EHCI function. Please refer to section 12.2.
+ /// Please note that there is a corresponding disable bit on D20:F0:E4h[14:0] for USB 2.0
+ /// ports and D20:F0:E8h[5:0] for USB 3.0 ports. BIOS needs to program them accordingly.
+ ///
+ /// XHCI PDO for HS
+ ///
+ XhciUsb2Pdo = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB2PDO) & B_PCH_XHCI_USB2PDO_MASK;
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ XhciIndex = Index;
+ if (PchSeries == PchH) {
+ ///
+ /// Translate physical pins to internal ports numbering
+ ///
+ XhciIndex = XhciUsb2InternalPortNumberLookUpTable[Index];
+ }
+ if (UsbConfig->PortSettings[Index].Enable == PCH_DEVICE_DISABLE) {
+ XhciUsb2Pdo |= (UINT32) (B_PCH_XHCI_USB2PDO_DIS_PORT0 << XhciIndex);
+ } else {
+ XhciUsb2Pdo &= (UINT32)~(B_PCH_XHCI_USB2PDO_DIS_PORT0 << XhciIndex);
+ }
+ }
+ ///
+ /// XHCI PDO for SS
+ ///
+ XhciUsb3Pdo = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_USB3PDO) & B_PCH_XHCI_USB3PDO_MASK;
+ for (Index = 0; Index < GetPchXhciMaxUsb3PortNum (); Index++) {
+
+ if (USB3PORT_SETTING_POLICY_SUPPORT(Revision)){
+ if (UsbConfig->Port30Settings[Index].Enable == PCH_DEVICE_DISABLE) {
+ XhciUsb3Pdo |= (UINT32) (B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index);
+ } else {
+ XhciUsb3Pdo &= (UINT32)~(B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index);
+ }
+ } else {
+ if (UsbConfig->PortSettings[Index].Enable == PCH_DEVICE_DISABLE) {
+ XhciUsb3Pdo |= (UINT32) (B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index);
+ } else {
+ XhciUsb3Pdo &= (UINT32)~(B_PCH_XHCI_USB3PDO_DIS_PORT0 << Index);
+ }
+ }
+ }
+ ///
+ /// USB2PDO and USB3PDO are Write-Once registers and bits in them are in the SUS Well.
+ ///
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_USB2PDO, XhciUsb2Pdo);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_USB3PDO, XhciUsb3Pdo);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PDO),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB2PDO)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PDO),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_USB3PDO)
+ );
+#endif
+}
+
+/**
+ Enable EHCI USBR device
+
+ @param[in] EhciPciMmBase Ehci PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciUsbrEnable (
+ IN UINTN EhciPciMmBase
+ )
+{
+ ///
+ /// NOTE: EHCI USBR Enable
+ /// EHCI1_USBr_en and EHCI2_USBr_en are mutually exclusive. Both cannot be set to 1 at any one time.
+ /// SW must ensure at any one time, only 1 EHCI should have the bit set.
+ ///
+ MmioOr16 (EhciPciMmBase + 0x7A, (UINT16) BIT8);
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (EhciPciMmBase + 0x7A),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x7A)
+ );
+#endif
+}
+
+/**
+ Program and enable XHCI Memory Space
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciMemorySpaceOpen (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINTN XhciPciMmBase
+ )
+{
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// Assign memory resources
+ ///
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE, XhciMmioBase);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE)
+ );
+
+ MmioOr16 (
+ XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER,
+ (UINT16) (B_PCH_XHCI_COMMAND_MSE | B_PCH_XHCI_COMMAND_BME)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER)
+ );
+}
+
+/**
+ Clear and disable XHCI Memory Space
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciMemorySpaceClose (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINTN XhciPciMmBase
+ )
+{
+ ///
+ /// Check if XHCI disabled, Exit function.
+ ///
+ if (UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+ ///
+ /// Clear memory resources
+ ///
+ MmioAnd16 (
+ XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER,
+ (UINT16)~(B_PCH_XHCI_COMMAND_MSE | B_PCH_XHCI_COMMAND_BME)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER)
+ );
+
+ MmioWrite32 ((XhciPciMmBase + R_PCH_XHCI_MEM_BASE), 0);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE)
+ );
+}
+
+/**
+ Tune the USB 2.0 high-speed signals quality.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_DEVICE_ERROR Programming is failed
+**/
+VOID
+Usb2PortLengthProgramming (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT16 LpcDeviceId,
+ IN UINT32 RootComplexBar
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+ ///
+ /// Execute the code if running in PEI phase when USB precondition feature is enabled
+ /// or in DXE phase when USB precondition feature disabled
+ /// If the precondition is enabled and running in DXE phase,
+ /// the code has already run once in PEI but the save S3 script need to run again in DXE phase
+ /// but only run if and only if both EHCI is not disabled
+ ///
+ if ((USB_RUN_IN_PEI || (!USB_PRECONDITION_POLICY_SUPPORT (UsbConfig))) ||
+ ((USB_RUN_IN_DXE) && ((UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_ENABLE) ||
+ ((UsbConfig->Usb20Settings[PchEhci2].Enable == PCH_DEVICE_ENABLE) && (PchSeries == PchH)))))
+ {
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+ //
+ // Set EHCI AFE USB2 PER PORT register
+ // IOBP registers 0xE5004000 + ((PortNumber+1) * 0x100)
+ //
+ for (Index = 0; Index < GetPchUsbMaxPhysicalPortNum (); Index++) {
+ Data32And = (UINT32)~(0x00007F00);
+ Data32Or = (UINT32) (0x00000000); // BIT[14] (PERPORTTXPEHALF) = 0
+ ASSERT (UsbConfig->PortSettings[Index].Usb20EyeDiagramTuningParam2 < 8);
+ Data32Or |= (UsbConfig->PortSettings[Index].Usb20EyeDiagramTuningParam2 & 0x07) << 11; // BIT[13:11] (PERPORTPETXISET) = Usb20EyeDiagramTuningParam2
+ ASSERT (UsbConfig->PortSettings[Index].Usb20EyeDiagramTuningParam1 < 8);
+ Data32Or |= (UsbConfig->PortSettings[Index].Usb20EyeDiagramTuningParam1 & 0x07) << 8; // BIT[10:08] (PERPORTTXISET) = Usb20EyeDiagramTuningParam1
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5004000 + ((Index + 1) * 0x100),
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5004000 + ((Index + 1) * 0x100),
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+}
+
+VOID
+ConfigureUsbClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+)
+{
+ ConfigureEhciClockGating(PchPlatformPolicy,RootComplexBar);
+ ConfigureXhciClockGating(PchPlatformPolicy,RootComplexBar);
+}
+
+VOID
+ConfigureEhciClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+)
+{
+ UINTN EhciPciMmBase;
+ UINT8 Index;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+ //
+ // Enable EHCI Clock Gating
+ //
+
+ ///
+ /// If LPT-LP when EHCI disabled, Set RCBA + Offset 3A84[2,0] = 1b, 1b
+ ///
+ if (PchSeries == PchLp) {
+ if (PchPlatformPolicy->UsbConfig->Usb20Settings[PchEhci1].Enable == PCH_DEVICE_DISABLE) {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84),
+ (UINT32) (BIT2 | BIT0)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84)
+ );
+ }
+ }
+
+ ///
+ /// Set IOBP register 0xE5004001[7:6] to 11b.
+ ///
+ Data32And = (UINT32)~(0);
+ Data32Or = (UINT32) (BIT7 | BIT6);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xE5004001,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xE5004001,
+ Data32And,
+ Data32Or
+ );
+ ///
+ /// For each EHCI's PCI Config space registers
+ ///
+ for (Index = 0; Index < GetPchEhciMaxControllerNum (); Index++) {
+ EhciPciMmBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ EhciControllersMap[Index].Device,
+ EhciControllersMap[Index].Function,
+ 0
+ );
+ ///
+ /// Set D29/D26:F0 + DCh[5,2,1] to 1b
+ /// Set D29/D26:F0 + DCh[0] to 1b when EHCI controller is disable
+ ///
+ Data32Or = (UINT32) (BIT5 | BIT2 | BIT1);
+ if (PchPlatformPolicy->UsbConfig->Usb20Settings[Index].Enable == PCH_DEVICE_DISABLE) {
+ Data32Or |= (UINT32) (BIT0);
+ }
+ MmioOr32 (EhciPciMmBase + 0xDC, Data32Or);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + 0xDC),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0xDC)
+ );
+ ///
+ /// Set D29/D26:F0 + 78h[1:0] to 11b
+ ///
+ Data32Or = (UINT32) (BIT1 | BIT0);
+ MmioOr32 (EhciPciMmBase + 0x78, Data32Or);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (EhciPciMmBase + 0x78),
+ 1,
+ (VOID *) (UINTN) (EhciPciMmBase + 0x78)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.h
new file mode 100644
index 0000000..a4b3a32
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommon.h
@@ -0,0 +1,360 @@
+/** @file
+
+ Header file for the PCH USB Common Driver.
+
+@copyright
+ Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#ifndef _USB_COMMON_H_
+#define _USB_COMMON_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchInitCommon.h"
+#endif
+
+#define USB_PR_CASE_0 0
+#define USB_PR_CASE_1 1
+#define USB_PR_CASE_2 2
+#define TEN_MS_TIMEOUT 10000
+#define PORT_RESET_TIMEOUT 10 ///< 100 ms timeout for xHCI port reset
+
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+} USB_CONTROLLER;
+
+/**
+ Configures PCH USB controller
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] BusNumber PCI Bus Number of the PCH device
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[out] FuncDisableReg Function Disable Register
+ @param[in] Revision The policy revision used for backward compatible check
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+CommonUsbInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMmioBase,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 BusNumber,
+ IN UINT32 RootComplexBar,
+ OUT UINT32 *FuncDisableReg,
+ IN UINT8 Revision
+ );
+
+/**
+ Performs basic configuration of PCH EHCI controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+ @param[in] BusNumber PCI Bus Number of the PCH device
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+CommonEhciHcsInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMmioBase,
+ IN UINT8 BusNumber,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Performs basic configuration of PCH USB3 (xHCI) controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of xHCI Controller
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+CommonXhciHcInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINTN XhciPciMmBase
+ );
+
+/**
+ Performs basic configuration of PCH USB3 (xHCI) controller.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] Revision The policy revision used for backward compatible check
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[in] PciD31F0RegBase LPC PCI Base Address
+
+ @retval None
+**/
+VOID
+PerformXhciEhciPortSwitchingFlow (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINT8 Revision,
+ IN UINT16 LpcDeviceId,
+ IN UINTN XhciPciMmBase,
+ IN UINTN PciD31F0RegBase
+ );
+
+/**
+ Retrieves information about number of implemented xHCI ports
+ and sets appropriate port mask registers.
+
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[out] HsPortCount Count of High Speed Ports
+ @param[out] HsUsbrPortCount Count of USBr Port
+ @param[out] SsPortCount Count of Super Speed Ports
+
+ @retval None
+**/
+VOID
+GetXhciPortCountAndSetPortRoutingMask (
+ IN UINTN XhciPciMmBase,
+ OUT UINTN *HsPortCount,
+ OUT UINTN *HsUsbrPortCount,
+ OUT UINTN *SsPortCount
+ );
+
+/**
+ Setup XHCI Over-Current Mapping
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciOverCurrentMapping (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN XhciPciMmBase
+ );
+
+/**
+ Setup EHCI Over-Current Mapping
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] Ehci1PciMmBase EHCI 1 PCI Base Address
+ @param[in] Ehci2PciMmBase EHCI 2 PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciOverCurrentMapping (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN Ehci1PciMmBase,
+ IN UINTN Ehci2PciMmBase
+ );
+
+/**
+ Program Ehci Port Disable Override
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] Ehci1PciMmBase EHCI 1 PCI Base Address
+ @param[in] Ehci2PciMmBase EHCI 2 PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciPortDisableOverride (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN Ehci1PciMmBase,
+ IN UINTN Ehci2PciMmBase
+ );
+
+/**
+ Program Xhci Port Disable Override
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+ @param[in] Revision Platform policy revision
+
+ @retval None
+**/
+VOID
+XhciPortDisableOverride (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINTN XhciPciMmBase,
+ IN UINT8 Revision
+ );
+
+/**
+ Enable EHCI USBR device
+
+ @param[in] EhciPciMmBase Ehci PCI Base Address
+
+ @retval None
+**/
+VOID
+EhciUsbrEnable (
+ IN UINTN EhciPciMmBase
+ );
+
+/**
+ Program and enable XHCI Memory Space
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciMemorySpaceOpen (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINTN XhciPciMmBase
+ );
+
+/**
+ Clear and disable XHCI Memory Space
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciPciMmBase XHCI PCI Base Address
+
+ @retval None
+**/
+VOID
+XhciMemorySpaceClose (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 XhciMmioBase,
+ IN UINTN XhciPciMmBase
+ );
+
+/**
+ Tune the USB 2.0 high-speed signals quality.
+
+ @param[in] UsbConfig The PCH Platform Policy for USB configuration
+ @param[in] LpcDeviceId The device ID of LPC
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval None
+**/
+VOID
+Usb2PortLengthProgramming (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT16 LpcDeviceId,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Initialization USB Clock Gating registers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval None
+**/
+VOID
+ConfigureUsbClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Initialization EHCI Clock Gating registers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval None
+**/
+VOID
+ConfigureEhciClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Initialization XHCI Clock Gating registers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval None
+**/
+VOID
+ConfigureXhciClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+/**
+ Perform USB precondition on EHCI, it is the HC on USB HC in PEI phase;
+ it is the root port reset on installed USB device in DXE phase
+
+ @param[in] Device The device number of the EHCI
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+
+ @retval None
+**/
+VOID
+EhciPrecondition (
+ IN UINT8 Device,
+ IN UINT32 EhciMmioBase
+ );
+
+/**
+ Perform USB precondition on XHCI, it is the HC on USB HC in PEI phase;
+ it is the root port reset on installed USB device in DXE phase
+
+ @param[in] BusNumber The Bus number of the XHCI
+ @param[in] Device The device number of the XHCI
+ @param[in] Function The function number of the XHCI
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciUSB2Ptr Pointer to USB2 protocol port register
+ @param[in] HsPortCount The number of USB2 protocol port supported by this XHCI
+
+ @retval None
+**/
+VOID
+XhciPrecondition (
+ IN UINT8 BusNumber,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 XhciMmioBase,
+ IN UINTN *XhciUSB2Ptr,
+ IN UINTN HsPortCount,
+ IN UINTN *XhciUSB3Ptr,
+ IN UINTN SsPortCount
+ );
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.cif
new file mode 100644
index 0000000..8b9628f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "PchUsbCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchInit\Common"
+ RefName = "PchUsbCommonLib"
+[files]
+"PchUsbCommonLib.sdl"
+"PchUsbCommonLib.mak"
+"PchUsbCommon.h"
+"PchUsbCommon.c"
+"PchHSIO.c"
+"PchHSIO.h"
+"PchHSIOLptHB0.c"
+"PchHSIOLptHB0.h"
+"PchInitVar.c"
+"PchInitVar.h"
+"PchHsioLptLpBx.h"
+"PchHsioLptHCx.c"
+"PchHsioLptHCx.h"
+"PchHsioLptLpBx.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.mak
new file mode 100644
index 0000000..6abbf99
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.mak
@@ -0,0 +1,127 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsbCommonLib/PchUsbCommonLib.mak 2 8/13/12 9:08a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 8/13/12 9:08a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsbCommonLib/PchUsbCommonLib.mak $
+#
+# 2 8/13/12 9:08a Victortu
+#
+# 1 2/08/12 9:29a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchUsbCommonLib
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+PchUsbCommonLib : PchUsbCommonPeiLib
+!ENDIF
+
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+PchUsbCommonLib : PchUsbCommonDxeLib
+!ENDIF
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+PchUsbCommonLib : PchUsbCommonDxeLib PchUsbCommonPeiLib
+!ENDIF
+!ENDIF
+
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+$(PchUsbCommonDxeLib_LIB) : PchUsbCommonDxeLib
+!ENDIF
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+$(PchUsbCommonPeiLib_LIB) : PchUsbCommonPeiLib
+!ENDIF
+
+PchUsbCommonDxeLib : $(BUILD_DIR)\PchUsbCommonLib.mak PchUsbCommonLibDxeBin
+
+PchUsbCommonPeiLib : $(BUILD_DIR)\PchUsbCommonLib.mak PchUsbCommonLibPeiBin
+
+$(BUILD_DIR)\PchUsbCommonLib.mak : $(PchUsbCommonLib_DIR)\$(@B).cif $(PchUsbCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchUsbCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchUsbCommonLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(INTEL_PCH_DIR)\Protocol\PchInfo\
+
+PchUsbCommonLibDxe_INCLUDES=\
+ $(PchUsbCommonLib_INCLUDES) $(PCH_INITDXE_INCLUDES)
+
+PchUsbCommonLibPeim_INCLUDES=\
+ $(PchUsbCommonLib_INCLUDES) $(PCH_INITPEI_INCLUDES)
+
+PchUsbCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+PchUsbCommonLibPeim_DEFINES = \
+ $(PchUsbCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+PchUsbCommonLibDxe_DEFINES = \
+ $(PchUsbCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+PchUsbCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchUsbCommonLib.mak all\
+ "MY_INCLUDES=$(PchUsbCommonLibDxe_INCLUDES)" \
+ "CFLAGS=$(PchUsbCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(PchUsbCommonDxeLib_LIB)
+
+PchUsbCommonLibPeiBin : $(EFISCRIPTLIB) $(EDKFRAMEWORKPROTOCOLLIB)
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\PchUsbCommonLib.mak all\
+ "MY_INCLUDES=$(PchUsbCommonLibPeim_INCLUDES)" \
+ "CFLAGS=$(PchUsbCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(PchUsbCommonPeiLib_LIB)
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.sdl
new file mode 100644
index 0000000..6d78a0b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Common/PchUsbCommonLib.sdl
@@ -0,0 +1,81 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsbCommonLib/PchUsbCommonLib.sdl 1 2/08/12 9:29a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:29a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsbCommonLib/PchUsbCommonLib.sdl $
+#
+# 1 2/08/12 9:29a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchUsbCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchUsbCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchUsbCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchUsbCommonLib.mak to Project"
+ File = "PchUsbCommonLib.mak"
+End
+
+ELINK
+ Name = "PchUsbCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$$(LIB_BUILD_DIR)\PchUsbCommonDxeLib.lib"
+ Parent = "PchUsbCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchUsbCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$$(LIB_BUILD_DIR)\PchUsbCommonPeiLib.lib"
+ Parent = "PchUsbCommonPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c
new file mode 100644
index 0000000..0045460
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAudioDsp.c
@@ -0,0 +1,602 @@
+/** @file
+ Configures Audio DSP device
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+#ifdef ADSP_FLAG
+#include "PchAslUpdateLib.h"
+
+//
+// AUDIO DSP Memory space definitions
+//
+#define V_PCH_ADSP_MEM_BASE_ADDRESS 0xFE000000
+#define S_PCH_ADSP_ADBAR_LENGTH 0x100000
+#define S_PCH_ADSP_SPCBAR_LENGTH 0x1000
+#define N_PCH_ADSP_ADBAR_ALIGN 16
+#define N_PCH_ADSP_SPCBAR_ALIGN 12
+
+/**
+ Configure AudioDSP SSP lines ownership
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_SUCCESS ADSP owns all I/O Buffers
+**/
+EFI_STATUS
+ConfigureAudioDspSsp(
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+ UINTN PciAzaliaRegBase;
+
+ ///
+ /// Retrieve Azalia PCI Config base
+ ///
+ PciAzaliaRegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_AZALIA,
+ PCI_FUNCTION_NUMBER_PCH_AZALIA,
+ 0
+ );
+
+ DEBUG ((EFI_D_INFO, "Audio DSP: Switch HDA pins to ADSP\n"));
+
+ ///
+ /// BIOS is required to set Ownership select of I/O Buffer to Audio DSP.
+ /// Set D27:F0:42h[7:6] = 11b - Audio DSP subsystem owns all the I/O buffers.
+ ///
+ MmioOr8 ((UINTN)(PciAzaliaRegBase + R_PCH_HDA_AZIOBC), (UINT8)B_PCH_HDA_AZIOBC_OSEL);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciAzaliaRegBase + R_PCH_HDA_AZIOBC),
+ 1,
+ (VOID *) (UINTN) (PciAzaliaRegBase + R_PCH_HDA_AZIOBC)
+ );
+
+ PchPlatformPolicy->DeviceEnabling->Azalia = PCH_DEVICE_DISABLE;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Allocates static memory pool for Audio DSP BAR and Shadowed PCI Configuration Space.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_ERROR Error occured on initialization
+**/
+EFI_STATUS
+AllocateAudioDspBar (
+)
+{
+ EFI_PHYSICAL_ADDRESS AdspMemBaseAddress;
+ EFI_PHYSICAL_ADDRESS AdspBar;
+ EFI_PHYSICAL_ADDRESS AdspShadowedPciBar;
+ UINT32 PciAdspRegBase;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "Audio DSP: Allocate fixed memory space\n"));
+
+ AdspMemBaseAddress = V_PCH_ADSP_MEM_BASE_ADDRESS;
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ AdspMemBaseAddress,
+ S_PCH_ADSP_ADBAR_LENGTH + S_PCH_ADSP_SPCBAR_LENGTH,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ AdspBar = AdspMemBaseAddress;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ N_PCH_ADSP_ADBAR_ALIGN,
+ S_PCH_ADSP_ADBAR_LENGTH,
+ &AdspBar,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ ASSERT(AdspBar == V_PCH_ADSP_MEM_BASE_ADDRESS);
+
+ AdspShadowedPciBar = AdspMemBaseAddress + S_PCH_ADSP_ADBAR_LENGTH;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ N_PCH_ADSP_SPCBAR_ALIGN,
+ S_PCH_ADSP_SPCBAR_LENGTH,
+ &AdspShadowedPciBar,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ ASSERT(AdspShadowedPciBar == V_PCH_ADSP_MEM_BASE_ADDRESS + S_PCH_ADSP_ADBAR_LENGTH);
+
+ PciAdspRegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_ADSP, PCI_FUNCTION_NUMBER_PCH_ADSP, 0);
+
+ DEBUG ((EFI_D_INFO, "Audio DSP: Base Address (ADBA) = 0x%04x; Length = 0x%x\n", AdspBar, S_PCH_ADSP_ADBAR_LENGTH));
+
+ MmioWrite32 ((UINTN)(PciAdspRegBase + R_PCH_ADSP_ADBA), (UINT32)AdspBar);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciAdspRegBase + R_PCH_ADSP_ADBA),
+ 1,
+ (VOID *)(UINTN) (PciAdspRegBase + R_PCH_ADSP_ADBA)
+ );
+
+ DEBUG ((EFI_D_INFO, "Audio DSP: Shadowed PCI Configuration Base Address (SPCBA) = 0x%04x; Length = 0x%x\n", AdspShadowedPciBar, S_PCH_ADSP_SPCBAR_LENGTH));
+
+ MmioWrite32 ((UINTN)(PciAdspRegBase + R_PCH_ADSP_SPCBA), (UINT32)AdspShadowedPciBar);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciAdspRegBase + R_PCH_ADSP_SPCBA),
+ 1,
+ (VOID *)(UINTN) (PciAdspRegBase + R_PCH_ADSP_SPCBA)
+ );
+
+ ///
+ /// Enable memory space access
+ /// Program D19:F0:04h[2:1] = 11b
+ ///
+ MmioOr32 ((UINTN)(PciAdspRegBase + R_PCH_ADSP_COMMAND), (B_PCH_ADSP_COMMAND_BME | B_PCH_ADSP_COMMAND_MSE));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciAdspRegBase + R_PCH_ADSP_COMMAND),
+ 1,
+ (VOID *) (UINTN) (PciAdspRegBase + R_PCH_ADSP_COMMAND)
+ );
+
+ return Status;
+}
+
+/**
+ Disables/hides or enables/unhides Audio DSP PCI Configuration Space
+
+ @param[in] PciConfigurationDisable If TRUE, PCI Config Space will be disabled.
+ If FALSE, PCI Config Space will be enabled.
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+DisableAudioDspPciConfigSpace(
+ IN BOOLEAN PciConfigurationDisable,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT32 Data32Or;
+ EFI_STATUS Status;
+
+ if (PciConfigurationDisable) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Hiding PCI Config Space\n"));
+ Data32Or = B_PCH_ADSP_PCICFGCTL_PCICD;
+ } else {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Unhiding PCI Config Space\n"));
+ Data32Or = 0;
+ }
+
+ Status = ProgramIobp (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PCICFGCTL),
+ (UINT32)~(B_PCH_ADSP_PCICFGCTL_PCICD),
+ (UINT32) Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PCICFGCTL),
+ (UINT32)~(B_PCH_ADSP_PCICFGCTL_PCICD),
+ (UINT32) Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Finalize Audio DSP initialization after PCI enumeration.
+ In particular configure ADSP in ACPI or PCI mode:
+ ACPI - patches ACPI table, sets ACPI IRQ and hides PCI config space.
+ PCI - sets PCI IRQ, does not hide PCI config space.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_UNSUPPORTED Audio DSP not found or not enabled
+**/
+EFI_STATUS
+ConfigureAudioDspBeforeBoot(
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 Data8;
+ UINT32 Data32;
+ UINT32 PciAdspRegBase;
+ UINT16 AdspDeviceId;
+ EFI_STATUS Status;
+ EFI_STATUS AcpiTablePresent;
+
+ Status = EFI_SUCCESS;
+ AcpiTablePresent = EFI_NOT_FOUND;
+
+ DEBUG ((EFI_D_INFO, "ConfigureAudioDspBeforeBoot() Start\n"));
+
+ if (PchPlatformPolicy->DeviceEnabling->AudioDsp == PCH_DEVICE_ENABLE) {
+
+ PciAdspRegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_ADSP,
+ PCI_FUNCTION_NUMBER_PCH_ADSP,
+ 0
+ );
+
+ // Unhide ADSP PCI Config Space to do the final initialization
+ Status = DisableAudioDspPciConfigSpace (FALSE, RootComplexBar);
+
+ AdspDeviceId = MmioRead16 (PciAdspRegBase + R_PCH_LPTLP_ADSP_DEVICE_ID);
+
+ if (AdspDeviceId == V_PCH_LPTLP_ADSP_DEVICE_ID) {
+
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspAcpiMode) {
+ //
+ // Locate ACPI table
+ //
+ AcpiTablePresent = InitializePchAslUpdateLib();
+
+ ///
+ /// Assign DSP BARs for ACPI use
+ ///
+ if(!EFI_ERROR(AcpiTablePresent)) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Updating ACPI tables\n"));
+ Data32 = (MmioRead32(PciAdspRegBase + R_PCH_ADSP_ADBA) & MMIO_ADDR_MASK);
+ UpdateResourceTemplateAslCode((EFI_SIGNATURE_32 ('A', 'D', 'S', 'P')),
+ (EFI_SIGNATURE_32 ('R', 'B', 'U', 'F')),
+ AML_MEMORY32_FIXED_OP,
+ 1,
+ 0x04,
+ &Data32,
+ sizeof(Data32)
+ );
+
+ Data32 = (MmioRead32(PciAdspRegBase + R_PCH_ADSP_SPCBA) & MMIO_ADDR_MASK);
+ UpdateResourceTemplateAslCode((EFI_SIGNATURE_32 ('A', 'D', 'S', 'P')),
+ (EFI_SIGNATURE_32 ('R', 'B', 'U', 'F')),
+ AML_MEMORY32_FIXED_OP,
+ 2,
+ 0x04,
+ &Data32,
+ sizeof(Data32)
+ );
+
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspBluetoothSupport) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Bluetooth support enabled\n"));
+ Data8 = PCH_DEVICE_ENABLE;
+ UpdateNameAslCode(EFI_SIGNATURE_32('A','B','T','H'), &Data8, sizeof(Data8));
+ }
+
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspAcpiInterruptMode == PCH_DEVICE_DISABLE) {
+ Data8 = 23; // PCI IRQ 23
+ UpdateResourceTemplateAslCode((EFI_SIGNATURE_32 ('A', 'D', 'S', 'P')),
+ (EFI_SIGNATURE_32 ('R', 'B', 'U', 'F')),
+ AML_INTERRUPT_DESC_OP,
+ 1,
+ 0x05,
+ &Data8,
+ sizeof(Data8)
+ );
+ }
+ }
+ }
+
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspAcpiInterruptMode) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: ACPI Interrupt mode\n"));
+
+ ///
+ /// Set Interrupt De-assert/Assert Opcode Override to IRQ3
+ ///
+ Data32 = V_PCH_ADSP_VDLDAT2_IRQ3;
+ Status = ProgramIobp (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_VDLDAT2),
+ (UINT32)~(V_PCH_ADSP_VDLDAT2_MASK),
+ (UINT32) (Data32)
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_VDLDAT2),
+ (UINT32)~(V_PCH_ADSP_VDLDAT2_MASK),
+ (UINT32) (Data32)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Enable IRQ3 in RCRB
+ MmioOr32 ((UINTN)(RootComplexBar + R_PCH_RCRB_INT_ACPIIRQEN), B_PCH_RCRB_INT_ACPIIRQEN_A3E);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_INT_ACPIIRQEN),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_INT_ACPIIRQEN)
+ );
+
+ // Set ACPI Interrupt Enable bit
+ Data32 = B_PCH_ADSP_PCICFGCTL_ACPIIE;
+
+ } else {
+ DEBUG ((EFI_D_INFO, "Audio DSP: PCI Interrupt mode\n"));
+
+ /// Program D19:F0:3Ch = 23 - INTLN (Interrupt Line) to IRQ23
+ DEBUG ((EFI_D_INFO, "Audio DSP: Set INTLN to IRQ23\n"));
+ MmioWrite32 ((UINTN)(PciAdspRegBase + 0x3C), (UINT32)(0x17));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciAdspRegBase + 0x3C),
+ 1,
+ (VOID *)(UINTN) (PciAdspRegBase + 0x3C)
+ );
+
+ // Do not set ACPI Interrupt Enable bit
+ Data32 = 0;
+ }
+
+ ///
+ /// Configure ADSP in ACPI or PCI interrupt mode
+ /// Update ACPI Interrupt Enable (bit 1) in PCICFGCTL (offset 0x500) accordingly
+ ///
+ Status = ProgramIobp (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PCICFGCTL),
+ (UINT32)~(B_PCH_ADSP_PCICFGCTL_ACPIIE | B_PCH_ADSP_PCICFGCTL_SPCBAD),
+ (UINT32) (Data32)
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PCICFGCTL),
+ (UINT32)~(B_PCH_ADSP_PCICFGCTL_ACPIIE | B_PCH_ADSP_PCICFGCTL_SPCBAD),
+ (UINT32) (Data32)
+ );
+
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspAcpiMode) {
+ ///
+ /// Configure ADSP in ACPI mode
+ /// Set PCI Configuration Disable (bit 0) in PCICFGCTL (offset 0x500)
+ ///
+ DEBUG ((EFI_D_INFO, "Audio DSP: ACPI mode\n"));
+ Status = DisableAudioDspPciConfigSpace(TRUE, RootComplexBar);
+ }
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureAudioDspBeforeBoot() End\n"));
+
+ return Status;
+}
+
+/**
+ Initialize Audio DSP subsystem
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS Codec is detected and initialized
+ @retval EFI_UNSUPPORTED Audio DSP disabled
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to initialize the codec
+**/
+EFI_STATUS
+ConfigureAudioDsp (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINT32 Data32;
+ UINT32 PciAdspRegBase;
+ UINT32 AdspBar;
+ UINT16 AdspDeviceId;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "ConfigureAudioDsp() Start\n"));
+
+ if (PchPlatformPolicy->DeviceEnabling->AudioDsp == PCH_DEVICE_ENABLE) {
+
+ PciAdspRegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_ADSP,
+ PCI_FUNCTION_NUMBER_PCH_ADSP,
+ 0
+ );
+
+ AdspDeviceId = MmioRead16 (PciAdspRegBase + R_PCH_LPTLP_ADSP_DEVICE_ID);
+
+ if (AdspDeviceId == V_PCH_LPTLP_ADSP_DEVICE_ID) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Found and Enabled\n"));
+
+ Status = AllocateAudioDspBar();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ AdspBar = MmioRead32 (PciAdspRegBase + R_PCH_ADSP_ADBA);
+
+ ///
+ /// Set LTR value in DSP Shim LTR Control register to 3ms
+ /// SNOOP_REQ[13] = 1b, SNOOP_SCALE[12:10] = 100b (1ms), SNOOP_VAL[9:0] = 3h
+ ///
+ MmioWrite32 ((UINTN)(AdspBar + (R_PCH_ADSP_SHIM_BASE + R_PCH_ADSP_SHIM_LTRC)), (UINT32)V_PCH_ADSP_SHIM_LTRC);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AdspBar + (R_PCH_ADSP_SHIM_BASE + R_PCH_ADSP_SHIM_LTRC)),
+ 1,
+ (VOID *)(UINTN) (AdspBar + (R_PCH_ADSP_SHIM_BASE + R_PCH_ADSP_SHIM_LTRC))
+ );
+
+ ///
+ /// Program VDRTCTL2 D19:F0:A8h[31:0] = FFFh
+ ///
+ MmioWrite32 (PciAdspRegBase + R_PCH_ADSP_VDRTCTL2, (UINT32)V_PCH_ADSP_VDRTCTL2);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciAdspRegBase + R_PCH_ADSP_VDRTCTL2),
+ 1,
+ (VOID *)(UINTN) (PciAdspRegBase + R_PCH_ADSP_VDRTCTL2)
+ );
+
+ ///
+ /// Set DSP IOBP register VDLDAT1 (0x624) to 0x040100
+ ///
+ Status = ProgramIobp (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_VDLDAT1),
+ (UINT32)~(V_PCH_ADSP_VDLDAT1_CCO),
+ (UINT32) (V_PCH_ADSP_VDLDAT1_CCO)
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_VDLDAT1),
+ (UINT32)~(V_PCH_ADSP_VDLDAT1_CCO),
+ (UINT32) (V_PCH_ADSP_VDLDAT1_CCO)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Set D3 Power Gating Enable
+ /// Program D19:F0:A0h[2:1] = 00b
+ ///
+ Data32 = MmioRead32 (PciAdspRegBase + R_PCH_ADSP_VDRTCTL0);
+ if (PchPlatformPolicy->AudioDspConfig->AudioDspD3PowerGating) {
+ DEBUG ((EFI_D_INFO, "Audio DSP: D3 Power Gating Enabled\n"));
+ Data32 &= ~(B_PCH_ADSP_VDRTCTL0_D3PGD | B_PCH_ADSP_VDRTCTL0_D3SRAMPGD);
+ } else {
+ DEBUG ((EFI_D_INFO, "Audio DSP: D3 Power Gating Disabled\n"));
+ Data32 |= B_PCH_ADSP_VDRTCTL0_D3PGD | B_PCH_ADSP_VDRTCTL0_D3SRAMPGD;
+ }
+
+ MmioWrite32 ((UINTN)(PciAdspRegBase + R_PCH_ADSP_VDRTCTL0), Data32);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciAdspRegBase + R_PCH_ADSP_VDRTCTL0),
+ 1,
+ &Data32
+ );
+
+ ///
+ /// Set PSF Snoop to SA
+ /// Program RCBA + 0x3350[10] = 1b
+ ///
+ MmioOr32 ((UINTN)(RootComplexBar + R_PCH_RCRB_CIR3350), (UINT32) BIT10);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3350),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3350)
+ );
+
+ ///
+ /// Switch I/O Buffers ownership to ADSP
+ ///
+ ConfigureAudioDspSsp (PchPlatformPolicy);
+
+ ///
+ /// Disable ADSP PCI Configuration Space in order
+ /// to avoid Base Adresses override on PCI enumeration
+ ///
+ DisableAudioDspPciConfigSpace (TRUE, RootComplexBar);
+
+ }
+
+ Status = EFI_SUCCESS;
+ }
+ else {
+ DEBUG ((EFI_D_INFO, "Audio DSP: Disabled\n"));
+ ///
+ /// Set RCBA + 2B1Ch[29] = 1b
+ ///
+ MmioOr32 ((UINTN)(RootComplexBar + 0x2B1C), (UINT32)BIT29);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B1C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B1C)
+ );
+
+ ///
+ /// Set Audio DSP function disable by programming RCBA + 3418h[1] = 1b
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_ADSP;
+ Status = EFI_SUCCESS;
+ }
+
+ ///
+ /// Set DSP IOBP register PMCTL (0x1E0) to 0x3F
+ /// This should be set for both: ADSP enabled and disabled
+ ///
+ Status = ProgramIobp (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PMCTL),
+ (UINT32)~(V_PCH_ADSP_PMCTL),
+ (UINT32) (V_PCH_ADSP_PMCTL)
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ (UINT32) (R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP + R_PCH_ADSP_PMCTL),
+ (UINT32)~(V_PCH_ADSP_PMCTL),
+ (UINT32) (V_PCH_ADSP_PMCTL)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "ConfigureAudioDsp() End\n"));
+
+ return Status;
+}
+
+#endif // ADSP_FLAG
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c
new file mode 100644
index 0000000..a0c7535
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchAzalia.c
@@ -0,0 +1,915 @@
+/** @file
+ Initializes the PCH Azalia codec.
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+/**
+ Polling the Status bit
+
+ @param[in] StatusReg The regsiter address to read the status
+ @param[in] PollingBitMap The bit mapping for polling
+ @param[in] PollingData The Data for polling
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_TIMEOUT Polling the bit map time out
+**/
+EFI_STATUS
+StatusPolling (
+ IN UINT32 StatusReg,
+ IN UINT16 PollingBitMap,
+ IN UINT16 PollingData
+ )
+{
+ UINT32 LoopTime;
+
+ for (LoopTime = 0; LoopTime < AZALIA_MAX_LOOP_TIME; LoopTime++) {
+ if ((MmioRead16 (StatusReg) & PollingBitMap) == PollingData) {
+ break;
+ } else {
+ PchPmTimerStall (AZALIA_WAIT_PERIOD);
+ }
+ }
+
+ if (LoopTime >= AZALIA_MAX_LOOP_TIME) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Send the command to the codec via the Immediate Command mechanism is written
+ to the IC register
+
+ @param[in] HdaBar Base address of Intel HD Audio memory mapped configuration registers
+ @param[in, out] CodecCommandData The Codec Command to be sent to the codec
+ @param[in] ReadBack Whether to get the response received from the codec
+
+ @retval EFI_DEVICE_ERROR Device status error, operation failed
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SendCodecCommand (
+ IN UINT32 HdaBar,
+ IN OUT UINT32 *CodecCommandData,
+ IN BOOLEAN ReadBack
+ )
+{
+ EFI_STATUS Status;
+
+ Status = StatusPolling (HdaBar + R_HDA_IRS, (UINT16) B_HDA_IRS_ICB, (UINT16) 0);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "ICB bit is not zero before SendCodecCommand! \n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ MmioWrite32 (HdaBar + R_HDA_IC, *CodecCommandData);
+ MmioOr16 ((UINTN) (HdaBar + R_HDA_IRS), (UINT16) ((B_HDA_IRS_IRV | B_HDA_IRS_ICB)));
+
+ Status = StatusPolling (HdaBar + R_HDA_IRS, (UINT16) B_HDA_IRS_ICB, (UINT16) 0);
+ if (EFI_ERROR (Status)) {
+ MmioAnd16 ((UINTN) (HdaBar + R_HDA_IRS), (UINT16)~(B_HDA_IRS_ICB));
+ return Status;
+ }
+
+ if (ReadBack == TRUE) {
+ if ((MmioRead16 (HdaBar + R_HDA_IRS) & B_HDA_IRS_IRV) != 0) {
+ *CodecCommandData = MmioRead32 (HdaBar + R_HDA_IR);
+ } else {
+ DEBUG ((EFI_D_ERROR, "SendCodecCommand: ReadBack fail! \n"));
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set a "Send Codec Command" S3 dispatch item
+
+ @param[in] HdaBar Base address of Intel HD Audio memory mapped configuration registers
+ @param[in, out] CodecCommandData The Codec Command to be sent to the codec
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SendCodecCommandS3Item (
+ IN UINT32 HdaBar,
+ IN OUT UINT32 CodecCommandData
+ )
+{
+ EFI_STATUS Status;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+ STATIC EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND S3ParameterSendCodecCommand;
+ STATIC EFI_PCH_S3_DISPATCH_ITEM S3DispatchItem = {
+ PchS3ItemTypeSendCodecCommand,
+ &S3ParameterSendCodecCommand
+ };
+ EFI_PHYSICAL_ADDRESS S3DispatchEntryPoint;
+
+ if (!PchS3Support) {
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ S3ParameterSendCodecCommand.HdaBar = HdaBar;
+ S3ParameterSendCodecCommand.CodecCmdData = CodecCommandData;
+ Status = PchS3Support->SetDispatchItem (
+ PchS3Support,
+ &S3DispatchItem,
+ &S3DispatchEntryPoint
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Save the script dispatch item in the Boot Script
+ ///
+ SCRIPT_DISPATCH (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, S3DispatchEntryPoint);
+#else
+ Status = EFI_SUCCESS;
+#endif
+ return Status;
+}
+
+/**
+ Initialize the Intel High Definition Audio Codec(s) present in the system.
+ For each codec, a predefined codec verb table should be programmed.
+ The list contains 32-bit verbs to be sent to the corresponding codec.
+ If it is not programmed, the codec uses the default verb table, which may or may not
+ correspond to the platform jack information.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+ @param[in, out] AzaliaStarted Whether Azalia is successfully started
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_INVALID_PARAMETER Provided VerbTableData is null
+**/
+EFI_STATUS
+DetectAndInitializeAzalia (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT BOOLEAN *AzaliaStarted
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINT32 VendorDeviceId;
+ UINT32 RevisionId;
+ UINT8 ByteReg;
+ UINTN AzaliaBase;
+ UINT8 AzaliaSDINo;
+ UINT32 HdaBar;
+ UINT32 *VerbTable;
+ UINT32 LoopTime;
+ PCH_AZALIA_VERB_TABLE_HEADER *VerbHeaderTable;
+ EFI_PHYSICAL_ADDRESS BaseAddressBarMem;
+ UINT8 VerbTableNum;
+ PCH_AZALIA_CONFIG *AzaliaConfig;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT8 Data8And;
+ UINT8 Data8Or;
+ UINT32 CodecCmdData;
+ UINTN PciD31F0RegBase;
+ UINT16 LpcDeviceId;
+ UINT16 Data16;
+ UINT16 BitMask;
+ UINT16 BitValue;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ AzaliaConfig = PchPlatformPolicy->AzaliaConfig;
+ AzaliaBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_AZALIA,
+ PCI_FUNCTION_NUMBER_PCH_AZALIA,
+ 0
+ );
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+
+ Data32And = 0xF8FFFF01;
+ if ((MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CIR2030)) & (UINT32) BIT31) != 0) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.4.2 High Definition Audio VCi Configuration
+ /// For Sever
+ /// Step 1
+ /// Configure and enable Vcp on DMI, done on PchDmiPeim.c
+ /// Step 2
+ /// Assign a Vcp ID value of 2 to High Definition Audio VCi ID field of VCi Resource Control register
+ /// D27:F0:Reg 120h[26:24] = 2
+ /// Step 3
+ /// Map Tcp to VCP. Set bit 2 of TC/VCi Map field of High Definition Audio VCi Resource Control register
+ /// D27:F0:Reg 120h[7:1]
+ ///
+ Data32Or = BIT25;
+ Data32Or |= MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CIR2030)) & V_PCH_RCRB_V1CTL_TVM_MASK;
+ MmioAndThenOr32 (
+ (UINTN) (AzaliaBase + R_PCH_HDA_VCICTL),
+ Data32And, // Data to be ANDed
+ Data32Or // Data to be ORed
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_VCICTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 4
+ /// Avoid isochronous transfers to use VC1, Clear No Snoop Enable of Device Control Register
+ /// D27:F0:Reg 78h[11] = 0b
+ ///
+ if (PchSeries == PchH) {
+ MmioAnd16 (
+ (UINTN) (AzaliaBase + R_PCH_HDA_DEVC),
+ (UINT16) (~B_PCH_HDA_DEVC_NSNPEN)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (AzaliaBase + R_PCH_HDA_DEVC),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_DEVC)
+ );
+ }
+ }
+ if ((MmioRead32 ((UINTN) (AzaliaBase + R_PCH_HDA_VCICTL)) & B_PCH_HDA_VCICTL_ID) != 0) {
+ ///
+ /// Step 5
+ /// Clear the TC/VC0 Map field of VC0 Resource Control register
+ /// D27:F0:Reg 114h[7:1] = 0
+ ///
+ MmioAnd32 (
+ (UINTN) (AzaliaBase + R_PCH_HDA_VC0CTL),
+ (UINT32) (~B_PCH_HDA_VC0CTL_TCVC0_MAP)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_VC0CTL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_VC0CTL)
+ );
+ ///
+ /// Step 6
+ /// For LPT-H, Set VCi Enable bit of VCi Resource Control register
+ /// D27:F0:Reg 120h[31] = 1
+ /// For LPT-LP, Clear VCi Enable bit of VCi Resource Control register
+ /// D27:F0:Reg 120h[31] = 0
+ ///
+ if (PchSeries == PchH) {
+ MmioOr32 ((UINTN) (AzaliaBase + R_PCH_HDA_VCICTL), (UINT32) (B_PCH_HDA_VCICTL_EN));
+ }
+ if (PchSeries == PchLp) {
+ MmioAnd32 ((UINTN) (AzaliaBase + R_PCH_HDA_VCICTL), (UINT32)~(B_PCH_HDA_VCICTL_EN));
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_VCICTL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_VCICTL)
+ );
+ }
+ ///
+ /// Firstly Initialize Azalia to be not started.
+ ///
+ *AzaliaStarted = FALSE;
+
+ ///
+ /// Allocate resource for HDBAR
+ ///
+ BaseAddressBarMem = 0x0FFFFFFFF;
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 14,
+ V_PCH_HDA_HDBAR_SIZE,
+ &BaseAddressBarMem,
+ mImageHandle,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// System BIOS should ensure that the High Definition Audio HDBAR D27:F0:Reg 10-17h contains a valid address value
+ /// and is enabled by setting D27:F0:Reg 04h[1].
+ ///
+ HdaBar = (UINT32) BaseAddressBarMem;
+ MmioWrite32 (AzaliaBase + R_PCH_HDA_HDBARL, HdaBar);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDBARL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDBARL)
+ );
+
+ MmioWrite32 (AzaliaBase + R_PCH_HDA_HDBARU, 0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDBARU),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDBARU)
+ );
+
+ MmioOr16 ((UINTN) (AzaliaBase + R_PCH_HDA_COMMAND), (UINT16) B_PCH_HDA_COMMAND_MSE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (AzaliaBase + R_PCH_HDA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_COMMAND)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.5
+ /// Additional High Definition Audio Programming Steps
+ ///
+ if(PchSeries == PchH) {
+ ///
+ /// Step 1
+ /// Set D27:F0:43h[4] = 1b
+ ///
+ Data8And = (UINT8) ~0;
+ Data8Or = BIT4;
+ MmioOr8 ((UINTN) (AzaliaBase + 0x43), Data8Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + 0x43),
+ &Data8Or, // Data to be ORed
+ &Data8And // Data to be ANDed
+ );
+ ///
+ /// Step 2
+ /// Set D27:F0:C0h[17] = 1b
+ ///
+ Data32And = (UINT32) ~0;
+ Data32Or = BIT17;
+ MmioOr32 ((UINTN) (AzaliaBase + 0xC0), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + 0xC0),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ ///
+ /// For LPT-LP, clear D27:F0:43h[6] = 0b
+ ///
+ if(PchSeries == PchLp) {
+ ///
+ /// Step 1
+ /// Set D27:F0:43h[6] = 0b
+ ///
+ MmioAnd8 ((UINTN) (AzaliaBase + 0x43), (UINT8) (~BIT6));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + 0x43),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + 0x43)
+ );
+ }
+
+ ///
+ /// Step 3
+ /// For LPT-H, Set D27:F0:C4h[14] = 1b
+ /// For LPT-LP, Set D27:F0:C4h[24] = 1b
+ ///
+ Data32And = (UINT32) ~0;
+ Data32Or = 0;
+ if (PchSeries == PchH) {
+ Data32Or |= BIT14;
+ }
+ if (PchSeries == PchLp) {
+ Data32Or |= BIT24;
+ }
+ MmioOr32 ((UINTN) (AzaliaBase + 0xC4), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + 0xC4),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ if (PchSeries == PchH) {
+ ///
+ /// Step 4
+ /// Set D27:F0:D0h[31] = 0b
+ ///
+ Data32And = ~BIT31;
+ Data32Or = (UINT32) 0;
+ MmioAnd32 ((UINTN) (AzaliaBase + 0xD0), Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + 0xD0),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ if (AzaliaConfig->DS == PCH_DEVICE_DISABLE) {
+ MmioAnd8 ((UINTN) (AzaliaBase + R_PCH_HDA_DCKSTS), (UINT8) (~B_PCH_HDA_DCKSTS_DS));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + R_PCH_HDA_DCKSTS),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_DCKSTS)
+ );
+ } else if (AzaliaConfig->DA != PCH_DEVICE_DISABLE) {
+ if ((MmioRead8 (AzaliaBase + R_PCH_HDA_DCKSTS) & B_PCH_HDA_DCKSTS_DM) == 0) {
+ MmioOr8 ((UINTN) (AzaliaBase + R_PCH_HDA_DCKCTL), (UINT8) (B_PCH_HDA_DCKCTL_DA));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + R_PCH_HDA_DCKCTL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_DCKCTL)
+ );
+ }
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// @todo: Policy check to bypass for PO
+ /// Set Hdabar + 0x0012h[0] to 1b
+ ///
+ Data16And = (UINT16)~BIT0;
+ Data16Or = (UINT16) (BIT0);
+ MmioOr16 ((UINTN) (HdaBar + 0x0012), Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (HdaBar + 0x0012),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// W/A: Azalia BCLK is not at full swing when operating in high voltage mode
+ /// Set D27:F0:42h[2] = 1b - disabling Auto Voltage Detector.
+ ///
+ MmioOr8 ((UINTN)(AzaliaBase + R_PCH_HDA_AZIOBC), (UINT8)B_PCH_HDA_AZIOBC_AVDDIS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + R_PCH_HDA_AZIOBC),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_AZIOBC)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.1.3 Codec Initialization Programming Sequence
+ /// System BIOS should also ensure that the Controller Reset# bit of Global Control register
+ /// in memory-mapped space (HDBAR+08h[0]) is set to 1 and read back as 1.
+ /// Deassert the HDA controller RESET# to start up the link
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) (B_HDA_GCTL_CRST);
+ MmioOr32 ((UINTN) (HdaBar + R_HDA_GCTL), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (HdaBar + R_HDA_GCTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ BitMask = (UINT16) B_HDA_GCTL_CRST;
+ BitValue = (UINT16) B_HDA_GCTL_CRST;
+ Status = StatusPolling (HdaBar + R_HDA_GCTL, BitMask, BitValue);
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ HdaBar + R_HDA_GCTL,
+ &BitMask,
+ &BitValue,
+ AZALIA_WAIT_PERIOD,
+ AZALIA_MAX_LOOP_TIME
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.1.3 Codec Initialization Programming Sequence
+ /// Read GCAP and write the same value back to the register once after Controller Reset# bit is set
+ ///
+ Data16 = MmioRead16 (HdaBar + R_HDA_GCAP);
+ MmioWrite16 (HdaBar + R_HDA_GCAP, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (HdaBar + R_HDA_GCAP),
+ 1,
+ (VOID *) (UINTN) (HdaBar + R_HDA_GCAP)
+ );
+
+ ///
+ /// Clear the "State Change Status Register" STATESTS bits for
+ /// each of the "SDIN Stat Change Status Flag"
+ ///
+ Data16 = AZALIA_MAX_SID_MASK_PCH_H;
+ if (PchSeries == PchLp) {
+ Data16 = AZALIA_MAX_SID_MASK_PCH_LP;
+ }
+ MmioOr8 ((UINTN) (HdaBar + R_HDA_STATESTS), (UINT8) (Data16));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (HdaBar + R_HDA_STATESTS),
+ 1,
+ (VOID *) (UINTN) (HdaBar + R_HDA_STATESTS)
+ );
+
+ ///
+ /// Turn off the link and poll RESET# bit until it reads back as 0 to get hardware reset report
+ ///
+ Data32And = (UINT32) (~B_HDA_GCTL_CRST);
+ Data32Or = (UINT32) 0;
+ MmioAnd32 ((UINTN) (HdaBar + R_HDA_GCTL), Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (HdaBar + R_HDA_GCTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ BitMask = (UINT16) B_HDA_GCTL_CRST;
+ BitValue = 0;
+ Status = StatusPolling (HdaBar + R_HDA_GCTL, BitMask, BitValue);
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ HdaBar + R_HDA_GCTL,
+ &BitMask,
+ &BitValue,
+ AZALIA_WAIT_PERIOD,
+ AZALIA_MAX_LOOP_TIME
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Reset High Definition Audio (Azalia) Codec Time Out - 1! \n"));
+ goto ExitInitAzalia;
+ }
+ ///
+ /// Turn on the link and poll RESET# bit until it reads back as 1
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) (B_HDA_GCTL_CRST);
+ MmioOr32 ((UINTN) (HdaBar + R_HDA_GCTL), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (HdaBar + R_HDA_GCTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// For some combo card that will need this delay because each codec has different latency to come out from RESET.
+ /// This delay can make sure all codecs be recognized by BIOS after RESET sequence.
+ /// Additional delay might be required to allow codec coming out of reset prior to subsequent operations,
+ /// please contact your codec vendor for detail. When clearing this bit and setting it afterward,
+ /// BIOS must ensure that minimum link timing requirements (minimum RESET# assertion time, etc.) are met..
+ ///
+ PchPmTimerStall (AzaliaConfig->ResetWaitTimer);
+ SCRIPT_STALL (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, AzaliaConfig->ResetWaitTimer);
+
+ BitMask = (UINT16) B_HDA_GCTL_CRST;
+ BitValue = (UINT16) B_HDA_GCTL_CRST;
+ Status = StatusPolling (HdaBar + R_HDA_GCTL, BitMask, BitValue);
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ HdaBar + R_HDA_GCTL,
+ &BitMask,
+ &BitValue,
+ AZALIA_WAIT_PERIOD,
+ AZALIA_MAX_LOOP_TIME
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Reset High Definition Audio (Azalia) Codec Time Out - 2! \n"));
+ goto ExitInitAzalia;
+ }
+ ///
+ /// Read the "State Change Status Register" STATESTS bits twice to find out if any SDIN is connected
+ /// to a codec.
+ ///
+ Data16 = AZALIA_MAX_SID_MASK_PCH_H;
+ if (PchSeries == PchLp) {
+ Data16 = AZALIA_MAX_SID_MASK_PCH_LP;
+ }
+ for (LoopTime = 0, ByteReg = 0, AzaliaSDINo = 0; LoopTime < AZALIA_MAX_LOOP_TIME; LoopTime++) {
+ ByteReg = (UINT8)(MmioRead8 (HdaBar + R_HDA_STATESTS) & Data16);
+ if (ByteReg != 0 && (ByteReg == AzaliaSDINo)) {
+ break;
+ } else {
+ AzaliaSDINo = ByteReg;
+ }
+
+ PchPmTimerStall (AZALIA_WAIT_PERIOD);
+ }
+ ///
+ /// BIT3(1000) -- SDI3
+ /// BIT2(0100) -- SDI2
+ /// BIT1(0010) -- SDI1
+ /// BIT0(0001) -- SDI0
+ ///
+ if (ByteReg == 0) {
+ ///
+ /// No Azalia Detected
+ ///
+ ///
+ /// Turn off the link
+ ///
+ DEBUG ((EFI_D_ERROR, "No Azalia device is detected.\n"));
+ Data32And = (UINT32) (~B_HDA_GCTL_CRST);
+ Data32Or = (UINT32) 0;
+ MmioAnd32 ((UINTN) (HdaBar + R_HDA_GCTL), Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (HdaBar + R_HDA_GCTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ Status = EFI_DEVICE_ERROR;
+ goto ExitInitAzalia;
+ }
+ ///
+ /// PME Enable for Audio controller, this bit is in the resume well
+ ///
+ if (AzaliaConfig->Pme == PCH_DEVICE_ENABLE) {
+ MmioOr32 ((UINTN) (AzaliaBase + R_PCH_HDA_PCS), (UINT32) (B_PCH_HDA_PCS_PMEE));
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_PCS),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_PCS)
+ );
+#endif
+ }
+
+ Data16 = AZALIA_MAX_SID_NUMBER_PCH_H;
+ if (PchSeries == PchLp) {
+ Data16 = AZALIA_MAX_SID_NUMBER_PCH_LP;
+ }
+ for (AzaliaSDINo = 0; AzaliaSDINo < Data16; AzaliaSDINo++, ByteReg >>= 1) {
+ if ((ByteReg & 0x1) == 0) {
+ ///
+ /// SDIx has no Azalia Device
+ ///
+ DEBUG ((EFI_D_ERROR, "SDI%d has no Azalia device.\n", AzaliaSDINo));
+ continue;
+ }
+ ///
+ /// PME Enable for each existing codec, these bits are in the resume well
+ ///
+ if (AzaliaConfig->Pme != PCH_DEVICE_DISABLE) {
+ MmioOr16 (
+ (UINTN) (HdaBar + R_HDA_WAKEEN),
+ (UINT16) ((B_HDA_WAKEEN_SDI_0 << AzaliaSDINo))
+ );
+#ifdef SUS_WELL_RESTORE
+ ///
+ /// To support RapidStart resume from G3 state, all resume well registers need to be saved
+ /// into S3 Script table.
+ ///
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (HdaBar + R_HDA_WAKEEN),
+ 1,
+ (VOID *) (UINTN) (HdaBar + R_HDA_WAKEEN)
+ );
+#endif
+ }
+ ///
+ /// Verb: 31~28 27 26~20 19~0
+ /// CAd 1 NID Verb Command and data
+ /// 0/1/2
+ ///
+ /// Read the Vendor ID/Device ID pair from the attached codec
+ ///
+ VendorDeviceId = 0x000F0000 | (AzaliaSDINo << 28);
+ Status = SendCodecCommand (HdaBar, &VendorDeviceId, TRUE);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Read the Codec Vendor ID/Device ID fail! \n"));
+ goto ExitInitAzalia;
+ }
+ ///
+ /// Read the Revision ID from the attached codec
+ ///
+ RevisionId = 0x000F0002 | (AzaliaSDINo << 28);
+ Status = SendCodecCommand (HdaBar, &RevisionId, TRUE);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Read the Codec Revision ID fail! \n"));
+ goto ExitInitAzalia;
+ }
+
+ RevisionId = (RevisionId >> 8) & 0xFF;
+
+ ///
+ /// Get the match codec verb table, RevID of 0xFF applies to all steppings.
+ ///
+ for (VerbTableNum = 0, VerbHeaderTable = NULL, VerbTable = NULL;
+ VerbTableNum < AzaliaConfig->AzaliaVerbTableNum;
+ VerbTableNum++) {
+ if ((VendorDeviceId == AzaliaConfig->AzaliaVerbTable[VerbTableNum].VerbTableHeader.VendorDeviceId) &&
+ ((AzaliaConfig->AzaliaVerbTable[VerbTableNum].VerbTableHeader.RevisionId == 0xFF) ||
+ ( RevisionId == AzaliaConfig->AzaliaVerbTable[VerbTableNum].VerbTableHeader.RevisionId))) {
+ VerbHeaderTable = &(AzaliaConfig->AzaliaVerbTable[VerbTableNum].VerbTableHeader);
+ VerbTable = AzaliaConfig->AzaliaVerbTable[VerbTableNum].VerbTableData;
+ if (VerbTable == 0) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "VerbTableData of VendorID:0x%X is null.\n", VendorDeviceId));
+ Status = EFI_INVALID_PARAMETER;
+ goto ExitInitAzalia;
+ }
+ DEBUG ((EFI_D_INFO, "Detected Azalia Codec with verb table, VendorID = 0x%X", VendorDeviceId));
+ DEBUG ((EFI_D_INFO, " on SDI%d, revision = 0x%0x.\n", AzaliaSDINo, RevisionId));
+ ///
+ /// Send the entire list of verbs in the matching verb table one by one to the codec
+ ///
+ for (Index = 0;
+ Index < (UINT32) ((VerbHeaderTable->NumberOfFrontJacks + VerbHeaderTable->NumberOfRearJacks) * 4);
+ Index++) {
+ ///
+ /// Clear CAd Field
+ ///
+ CodecCmdData = VerbTable[Index] & (UINT32) ~(BIT31 | BIT30 | BIT29 | BIT28);
+ ///
+ /// Program CAd Field per the SDI number got during codec detection
+ ///
+ CodecCmdData |= (UINT32) (AzaliaSDINo << 28);
+ Status = SendCodecCommand (HdaBar, &CodecCmdData, FALSE);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// Skip the Azalia verb table loading when find the verb table content is not
+ /// properly matched with the HDA hardware, though IDs match.
+ ///
+ DEBUG (
+ (EFI_D_ERROR | EFI_D_INFO,
+ "Detected Azalia Codec of VendorID:0x%X, error occurs during loading verb table.\n",
+ VendorDeviceId)
+ );
+ goto ExitInitAzalia;
+ }
+ SendCodecCommandS3Item (HdaBar, CodecCmdData);
+ }
+ break;
+ }
+ }
+
+ if (VerbTableNum >= AzaliaConfig->AzaliaVerbTableNum) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "Detected High Definition Audio (Azalia) Codec, VendorID = 0x%08x on SDI%d,",
+ VendorDeviceId,
+ AzaliaSDINo)
+ );
+ DEBUG ((EFI_D_ERROR, " but no matching verb table found.\n"));
+ }
+ }
+ ///
+ /// end of for
+ ///
+ *AzaliaStarted = TRUE;
+ Status = EFI_SUCCESS;
+
+ExitInitAzalia:
+ ///
+ /// Clear AZBAR and disable memory map access
+ ///
+ MmioAnd16 ((UINTN) (AzaliaBase + R_PCH_HDA_COMMAND), (UINT16) (~B_PCH_HDA_COMMAND_MSE));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (AzaliaBase + R_PCH_HDA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_COMMAND)
+ );
+
+ MmioWrite32 (AzaliaBase + R_PCH_HDA_HDBARL, 0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDBARL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDBARL)
+ );
+
+ MmioWrite32 (AzaliaBase + R_PCH_HDA_HDBARU, 0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDBARU),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDBARU)
+ );
+
+ gDS->FreeMemorySpace (
+ BaseAddressBarMem,
+ V_PCH_HDA_HDBAR_SIZE
+ );
+
+ return Status;
+}
+
+/**
+ Detect and initialize the type of codec (AC'97 and HDA) present in the system.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] AzaliaEnable Returned with TRUE if Azalia High Definition Audio codec
+ is detected and initialized.
+
+ @retval EFI_SUCCESS Codec is detected and initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to initialize the codec.
+**/
+EFI_STATUS
+ConfigureAzalia (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT BOOLEAN *AzaliaEnable
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "ConfigureAzalia() Start\n"));
+
+ *AzaliaEnable = FALSE;
+
+ ///
+ /// If all codec devices are to be disabled, skip the detection code
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Azalia == PCH_DEVICE_DISABLE) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Skip Azalia Codec detection.\n"));
+ return EFI_SUCCESS;
+ }
+
+ Status = DetectAndInitializeAzalia (PchPlatformPolicy, RootComplexBar, AzaliaEnable);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Azalia detection / initialization failure!\n"));
+
+ if (PchPlatformPolicy->DeviceEnabling->Azalia == PCH_DEVICE_ENABLE) {
+ *AzaliaEnable = TRUE;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureAzalia() End\n"));
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c
new file mode 100644
index 0000000..f588686
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchDebugDump.c
@@ -0,0 +1,330 @@
+/** @file
+ Dump whole DXE_PCH_PLATFORM_POLICY_PROTOCOL and serial out.
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+/**
+ Dump whole DXE_PCH_PLATFORM_POLICY_PROTOCOL and serial out.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval None
+**/
+VOID
+PchDumpPlatformProtocol (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+#ifdef EFI_DEBUG
+ UINT8 i;
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH Dump platform protocol Start -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH PLATFORM POLICY Revision= %x\n", PchPlatformPolicy->Revision));
+ DEBUG ((EFI_D_INFO, " PCH PLATFORM POLICY BusNumber= %x\n", PchPlatformPolicy->BusNumber));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_DEVICE_ENABLE -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Lan= %x\n", PchPlatformPolicy->DeviceEnabling->Lan));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Azalia= %x\n", PchPlatformPolicy->DeviceEnabling->Azalia));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Sata= %x\n", PchPlatformPolicy->DeviceEnabling->Sata));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Smbus= %x\n", PchPlatformPolicy->DeviceEnabling->Smbus));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE PciClockRun= %x\n", PchPlatformPolicy->DeviceEnabling->PciClockRun));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Display= %x\n", PchPlatformPolicy->DeviceEnabling->Display));
+ DEBUG ((EFI_D_INFO, " PCH_DEVICE_ENABLE Crid%x\n", PchPlatformPolicy->DeviceEnabling->Crid));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_USB_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG UsbPerPortCtl= %x\n", PchPlatformPolicy->UsbConfig->UsbPerPortCtl));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Ehci1Usbr= %x\n", PchPlatformPolicy->UsbConfig->Ehci1Usbr));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Ehci2Usbr= %x\n", PchPlatformPolicy->UsbConfig->Ehci2Usbr));
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG PortSettings[%d] Enabled= %x\n", i, PchPlatformPolicy->UsbConfig->PortSettings[i].Enable));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG PortSettings[%d] Location= %x\n", i, PchPlatformPolicy->UsbConfig->PortSettings[i].Location));
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Port30Settings[%d] Enabled= %x\n", i, PchPlatformPolicy->UsbConfig->Port30Settings[i].Enable));
+ }
+
+ for (i = 0; i < GetPchEhciMaxControllerNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20Settings[%d] Enabled= %x\n", i, PchPlatformPolicy->UsbConfig->Usb20Settings[i].Enable));
+ }
+
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.Mode= %x\n", PchPlatformPolicy->UsbConfig->Usb30Settings.Mode));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.PreBootSupport= %x\n", PchPlatformPolicy->UsbConfig->Usb30Settings.PreBootSupport));
+ DEBUG ((EFI_D_INFO, " XhciStreams is obsoleted, it doesn't effect any setting change since Revision 2.\n"));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualMode= %x\n", PchPlatformPolicy->UsbConfig->Usb30Settings.ManualMode));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.XhciIdleL1= %x\n", PchPlatformPolicy->UsbConfig->Usb30Settings.XhciIdleL1));
+
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ if (PchPlatformPolicy->UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[i] == 0) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualModeUsb20PerPinRoute[%d]= EHCI\n", i));
+ } else {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualModeUsb20PerPinRoute[%d]= XHCI\n", i));
+ }
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO,
+ "PCH_USB_CONFIG Usb30Settings.ManualModeUsb30PerPinEnable[%d]= %x\n",
+ i,
+ PchPlatformPolicy->UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[i]));
+ }
+
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20OverCurrentPins[%d]= OC%x\n", i, PchPlatformPolicy->UsbConfig->Usb20OverCurrentPins[i]));
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30OverCurrentPins[%d]= OC%x\n", i, PchPlatformPolicy->UsbConfig->Usb30OverCurrentPins[i]));
+ }
+
+ for (i = 0; i < GetPchEhciMaxUsbPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20PortLength[%d]= %x.%0x\n", i, PchPlatformPolicy->UsbConfig->PortSettings[i].Usb20PortLength >> 4, PchPlatformPolicy->UsbConfig->PortSettings[i].Usb20PortLength & 0xF));
+ }
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_PCI_EXPRESS_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG TempRootPortBusNumMin= %x\n", PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG TempRootPortBusNumMax= %x\n", PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax));
+ for (i = 0; i < GetPchMaxPciePortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] Enabled= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].Enable));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] Hide= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].Hide));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] SlotImplemented= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].SlotImplemented));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] HotPlug= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].HotPlug));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] PmSci= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].PmSci));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] ExtSync= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].ExtSync));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] UnsupportedRequestReport= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].UnsupportedRequestReport));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] FatalErrorReport= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].FatalErrorReport));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] NoFatalErrorReport= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].NoFatalErrorReport));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] CorrectableErrorReport= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].CorrectableErrorReport));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] PmeInterrupt= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].PmeInterrupt));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] SystemErrorOnFatalError= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].SystemErrorOnFatalError));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] SystemErrorOnNonFatalError= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].SystemErrorOnNonFatalError));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] SystemErrorOnCorrectableError= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].SystemErrorOnCorrectableError));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] AdvancedErrorReporting= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].AdvancedErrorReporting));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] TransmitterHalfSwing= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].TransmitterHalfSwing));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] FunctionNumber= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].FunctionNumber));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] PhysicalSlotNumber= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].PhysicalSlotNumber));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] CompletionTimeout= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].CompletionTimeout));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] Aspm= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].Aspm));
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPort[%d] L1Substates= %x\n", i, PchPlatformPolicy->PciExpressConfig->RootPort[i].L1Substates));
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG NumOfDevAspmOverride= %x\n", PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride VendorId= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->VendorId));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride DeviceId= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->DeviceId));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride RevId= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->RevId));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride BaseClassCode= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->BaseClassCode));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride SubClassCode= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->SubClassCode));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG DevAspmOverride EndPointAspm= %x\n", PchPlatformPolicy->PciExpressConfig->DevAspmOverride->EndPointAspm));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG PchPcieSbdePort= %x\n", PchPlatformPolicy->PciExpressConfig->PchPcieSbdePort));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG RootPortClockGating= %x\n", PchPlatformPolicy->PciExpressConfig->RootPortClockGating));
+ DEBUG ((EFI_D_INFO, " PCH_PCI_EXPRESS_CONFIG EnableSubDecode= %x\n", PchPlatformPolicy->PciExpressConfig->EnableSubDecode));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_SATA_CONFIG -----------------\n"));
+ for (i = 0; i < GetPchMaxSataPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] Enabled= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].Enable));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] HotPlug= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].HotPlug));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] InterlockSw= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].InterlockSw));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] External= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].External));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] SpinUp= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].SpinUp));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] SolidStateDrive= %x\n", i, PchPlatformPolicy->SataConfig->PortSettings[i].SolidStateDrive));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] EnableDitoConfig= %x\n", PchPlatformPolicy->SataConfig->PortSettings[i].EnableDitoConfig));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] DmVal= %x\n", PchPlatformPolicy->SataConfig->PortSettings[i].DmVal));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG PortSettings[%d] DitoVal= %x\n", PchPlatformPolicy->SataConfig->PortSettings[i].DitoVal));
+ }
+
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG RaidAlternateId= %x\n", PchPlatformPolicy->SataConfig->RaidAlternateId));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG Raid0= %x\n", PchPlatformPolicy->SataConfig->Raid0));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG Raid1= %x\n", PchPlatformPolicy->SataConfig->Raid1));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG Raid10= %x\n", PchPlatformPolicy->SataConfig->Raid10));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG Raid5= %x\n", PchPlatformPolicy->SataConfig->Raid5));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG Irrt= %x\n", PchPlatformPolicy->SataConfig->Irrt));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG OromUiBanner= %x\n", PchPlatformPolicy->SataConfig->OromUiBanner));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG HddUnlock= %x\n", PchPlatformPolicy->SataConfig->HddUnlock));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG LedLocate= %x\n", PchPlatformPolicy->SataConfig->LedLocate));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG IrrtOnly= %x\n", PchPlatformPolicy->SataConfig->IrrtOnly));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG TestMode= %x\n", PchPlatformPolicy->SataConfig->TestMode));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG SalpSupport= %x\n", PchPlatformPolicy->SataConfig->SalpSupport));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG LegacyMode= %x\n", PchPlatformPolicy->SataConfig->LegacyMode));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG SmartStorage= %x\n", PchPlatformPolicy->SataConfig->SmartStorage));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG OromUiDelay= %x\n", PchPlatformPolicy->SataConfig->OromUiDelay));
+ DEBUG ((EFI_D_INFO, " PCH_SATA_CONFIG SpeedSupport= %x\n", PchPlatformPolicy->SataConfig->SpeedSupport));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_AZALIA_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG Pme= %x\n", PchPlatformPolicy->AzaliaConfig->Pme));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG DS= %x\n", PchPlatformPolicy->AzaliaConfig->DS));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG DA= %x\n", PchPlatformPolicy->AzaliaConfig->DA));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTableNum= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTableNum));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header VendorDeviceId= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.VendorDeviceId));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header SubSystemId= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.SubSystemId));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header RevisionId= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.RevisionId));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header FrontPanelSupport= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.FrontPanelSupport));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header NumberOfRearJacks= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.NumberOfRearJacks));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable Header NumberOfFrontJacks= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableHeader.NumberOfFrontJacks));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG AzaliaVerbTable VerbTableData= %x\n", PchPlatformPolicy->AzaliaConfig->AzaliaVerbTable->VerbTableData));
+ DEBUG ((EFI_D_INFO, " PCH_AZALIA_CONFIG ResetWaitTimer= %x\n", PchPlatformPolicy->AzaliaConfig->ResetWaitTimer));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_SMBUS_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_SMBUS_CONFIG NumRsvdSmbusAddresses= %x\n", PchPlatformPolicy->SmbusConfig->NumRsvdSmbusAddresses));
+ DEBUG ((EFI_D_INFO, " PCH_SMBUS_CONFIG RsvdSmbusAddressTable= %x\n", PchPlatformPolicy->SmbusConfig->RsvdSmbusAddressTable));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_MISC_PM_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PowerResetStatusClear MeWakeSts= %x\n", PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeWakeSts));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PowerResetStatusClear MeHrstColdSts= %x\n", PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstColdSts));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PowerResetStatusClear MeHrstWarmSts= %x\n", PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstWarmSts));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PowerResetStatusClear MeHostPowerDn= %x\n", PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHostPowerDn));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PowerResetStatusClear WolOvrWkSts= %x\n", PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.WolOvrWkSts));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG WakeConfig PmeB0S5Dis= %x\n", PchPlatformPolicy->MiscPmConfig->WakeConfig.PmeB0S5Dis));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG WakeConfig WolEnableOverride= %x\n", PchPlatformPolicy->MiscPmConfig->WakeConfig.WolEnableOverride));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG WakeConfig Gp27WakeFromDeepSx= %x\n", PchPlatformPolicy->MiscPmConfig->WakeConfig.Gp27WakeFromDeepSx));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchDeepSxPol= %x\n", PchPlatformPolicy->MiscPmConfig->PchDeepSxPol));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchSlpS3MinAssert= %x\n", PchPlatformPolicy->MiscPmConfig->PchSlpS3MinAssert));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchSlpS4MinAssert= %x\n", PchPlatformPolicy->MiscPmConfig->PchSlpS4MinAssert));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchSlpSusMinAssert= %x\n", PchPlatformPolicy->MiscPmConfig->PchSlpSusMinAssert));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchSlpAMinAssert= %x\n", PchPlatformPolicy->MiscPmConfig->PchSlpAMinAssert));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG SlpStrchSusUp= %x\n", PchPlatformPolicy->MiscPmConfig->SlpStrchSusUp));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG SlpLanLowDc= %x\n", PchPlatformPolicy->MiscPmConfig->SlpLanLowDc));
+ DEBUG ((EFI_D_INFO, " PCH_MISC_PM_CONFIG PchPwrCycDur= %x\n", PchPlatformPolicy->MiscPmConfig->PchPwrCycDur));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_IO_APIC_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_IO_APIC_CONFIG BdfValid= %x\n", PchPlatformPolicy->IoApicConfig->BdfValid));
+ DEBUG ((EFI_D_INFO, " PCH_IO_APIC_CONFIG BusNumber= %x\n", PchPlatformPolicy->IoApicConfig->BusNumber));
+ DEBUG ((EFI_D_INFO, " PCH_IO_APIC_CONFIG DeviceNumber= %x\n", PchPlatformPolicy->IoApicConfig->DeviceNumber));
+ DEBUG ((EFI_D_INFO, " PCH_IO_APIC_CONFIG FunctionNumber= %x\n", PchPlatformPolicy->IoApicConfig->FunctionNumber));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_DEFAULT_SVID_SID -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_DEFAULT_SVID_SID SubSystemVendorId= %x\n", PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId));
+ DEBUG ((EFI_D_INFO, " PCH_DEFAULT_SVID_SID SubSystemId= %x\n", PchPlatformPolicy->DefaultSvidSid->SubSystemId));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_LOCK_DOWN_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG GlobalSmi= %x\n", PchPlatformPolicy->LockDownConfig->GlobalSmi));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG BiosInterface= %x\n", PchPlatformPolicy->LockDownConfig->BiosInterface));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG GpioLockDown= %x\n", PchPlatformPolicy->LockDownConfig->GpioLockDown));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG RtcLock= %x\n", PchPlatformPolicy->LockDownConfig->RtcLock));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG BiosLock= %x\n", PchPlatformPolicy->LockDownConfig->BiosLock));
+ DEBUG ((EFI_D_INFO, " PCH_LOCK_DOWN_CONFIG PchBiosLockIoTrapAddress= %x\n", PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_THERMAL_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG ThermalAlertEnable TselLock %x\n", PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TselLock));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG ThermalAlertEnable TscLock %x\n", PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TscLock));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG ThermalAlertEnable TsmicLock= %x\n", PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TsmicLock));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG ThermalAlertEnable PhlcLock= %x\n", PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.PhlcLock));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG ThermalDeviceEnable (D31:F6) %x\n", PchPlatformPolicy->ThermalConfig->ThermalDeviceEnable));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS T0Level %x centigrade degree\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T0Level));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS T1Level %x centigrade degree\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T1Level));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS T2Level %x centigrade degree\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T2Level));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS TTEnable %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTEnable));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS TTState13Enable %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTState13Enable));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS TTLock %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTLock));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING THERMAL_THROTTLE_LEVELS SuggestedSetting %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL DmiTsawEn %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.DmiTsawEn));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL TS0TW %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS0TW));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL TS1TW %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS1TW));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL TS2TW %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS2TW));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL TS3TW %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS3TW));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING DMI_HW_WIDTH_CONTROL SuggestedSetting %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.SuggestedSetting));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0T1M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T1M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0T2M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T2M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0T3M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T3M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0TDisp %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0TDisp));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0Tinact %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0Tinact));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P0TDispFinit %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0TDispFinit));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1T1M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T1M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1T2M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T2M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1T3M %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T3M));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1TDisp %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1TDisp));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1Tinact %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1Tinact));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE P1TDispFinit %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1TDispFinit));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PCH_THERMAL_THROTTLING SATA_THERMAL_THROTTLE SuggestedSetting %x\n", PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.SuggestedSetting));
+ DEBUG ((EFI_D_INFO, " PCH_THERMAL_CONFIG PchHotLevel = %x\n", PchPlatformPolicy->ThermalConfig->PchHotLevel));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_LPC_HPET_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_HPET_CONFIG HpetConfig %x\n", PchPlatformPolicy->HpetConfig->BdfValid));
+ for (i = 0; i < PCH_HPET_BDF_MAX; i++) {
+ DEBUG ((EFI_D_INFO, " PCH_LPC_HPET_CONFIG Hpet[%d] BusNumber %x\n", i, PchPlatformPolicy->HpetConfig->Hpet[i].BusNumber));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_HPET_CONFIG Hpet[%d] DeviceNumber %x\n", i, PchPlatformPolicy->HpetConfig->Hpet[i].DeviceNumber));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_HPET_CONFIG Hpet[%d] FunctionNumber %x\n", i, PchPlatformPolicy->HpetConfig->Hpet[i].FunctionNumber));
+ }
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_LPC_SIRQ_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_SIRQ_CONFIG SirqEnable= %x\n", PchPlatformPolicy->SerialIrqConfig->SirqEnable));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_SIRQ_CONFIG SirqMode= %x\n", PchPlatformPolicy->SerialIrqConfig->SirqMode));
+ DEBUG ((EFI_D_INFO, " PCH_LPC_SIRQ_CONFIG StartFramePulse= %x\n", PchPlatformPolicy->SerialIrqConfig->StartFramePulse));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_DMI_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_DMI_CONFIG DmiAspm= %x\n", PchPlatformPolicy->DmiConfig->DmiAspm));
+ DEBUG ((EFI_D_INFO, " PCH_DMI_CONFIG DmiExtSync= %x\n", PchPlatformPolicy->DmiConfig->DmiExtSync));
+ DEBUG ((EFI_D_INFO, " PCH_DMI_CONFIG DmiIot= %x\n", PchPlatformPolicy->DmiConfig->DmiIot));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_PWR_OPT_CONFIG -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG PchPwrOptDmi= %x\n", PchPlatformPolicy->PwrOptConfig->PchPwrOptDmi));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG PchPwrOptGbe= %x\n", PchPlatformPolicy->PwrOptConfig->PchPwrOptGbe));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG PchPwrOptXhci= %x\n", PchPlatformPolicy->PwrOptConfig->PchPwrOptXhci));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG PchPwrOptEhci= %x\n", PchPlatformPolicy->PwrOptConfig->PchPwrOptEhci));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG PchPwrOptSata= %x\n", PchPlatformPolicy->PwrOptConfig->PchPwrOptSata));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG MemCloseStateEn= %x\n", PchPlatformPolicy->PwrOptConfig->MemCloseStateEn));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG InternalObffEn= %x\n", PchPlatformPolicy->PwrOptConfig->InternalObffEn));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG ExternalObffEn= %x\n", PchPlatformPolicy->PwrOptConfig->ExternalObffEn));
+ for (i = 0; i < GetPchMaxPciePortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] LtrEnable= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].LtrEnable));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] ObffEnable= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].ObffEnable));
+ }
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG NumOfDevLtrOverride= %x\n", PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG DevLtrOverride VendorId= %x\n", PchPlatformPolicy->PwrOptConfig->DevLtrOverride->VendorId));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG DevLtrOverride DeviceId= %x\n", PchPlatformPolicy->PwrOptConfig->DevLtrOverride->DeviceId));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG DevLtrOverride RevId= %x\n", PchPlatformPolicy->PwrOptConfig->DevLtrOverride->RevId));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG DevLtrOverride SnoopLatency= %x\n", PchPlatformPolicy->PwrOptConfig->DevLtrOverride->SnoopLatency));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG DevLtrOverride NonSnoopLatency= %x\n", PchPlatformPolicy->PwrOptConfig->DevLtrOverride->NonSnoopLatency));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG LegacyDmaDisable= %x\n", PchPlatformPolicy->PwrOptConfig->LegacyDmaDisable));
+
+ for (i = 0; i < GetPchMaxPciePortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] LtrConfigLock= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].LtrConfigLock));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] LtrMaxSnoopLatency = %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i]. LtrMaxSnoopLatency));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] LtrMaxNoSnoopLatency = %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].LtrMaxNoSnoopLatency));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] SnoopLatencyOverrideMode= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].SnoopLatencyOverrideMode));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] SnoopLatencyOverrideMultiplier= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].SnoopLatencyOverrideMultiplier));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] SnoopLatencyOverrideValue= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].SnoopLatencyOverrideValue));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] NonSnoopLatencyOverrideMode= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].NonSnoopLatencyOverrideMode));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] NonSnoopLatencyOverrideMultiplier= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].NonSnoopLatencyOverrideMultiplier));
+ DEBUG ((EFI_D_INFO, " PCH_PWR_OPT_CONFIG RootPort[%d] NonSnoopLatencyOverrideValue= %x\n", i, PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[i].NonSnoopLatencyOverrideValue));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH Dump platform protocol End -----------------\n"));
+ DEBUG ((EFI_D_INFO, "\n"));
+#endif
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchFvi.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchFvi.c
new file mode 100644
index 0000000..a4f89cc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchFvi.c
@@ -0,0 +1,137 @@
+/** @file
+ PCH Firmware Version Info implementation.
+
+@copyright
+ Copyright (c) 2011 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchInit.h"
+
+FVI_ELEMENT_AND_FUNCTION mPchFviElementsData[] = {
+ {
+ DEFAULT_FVI_ELEMENT_DATA (PCH),
+ NULL
+ },
+ {
+ {
+ 1,
+ 2,
+ PCH_CRID_VERSION,
+ PCH_CRID_STATUS,
+ PCH_CRID_DISABLED,
+ },
+ NULL
+ },
+ {
+ {
+ 1,
+ 0,
+ PCH_CRID_VERSION,
+ PCH_CRID_ORIGINAL_VALUE,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+ {
+ {
+ 1,
+ 0,
+ PCH_CRID_VERSION,
+ PCH_CRID_NEW_VALUE,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+ {
+ {
+ 1,
+ 0,
+ RAID_RC_VERSION,
+ RAID_FVI_STRING,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+#ifdef ULT_FLAG
+ {
+ {
+ 1,
+ 0,
+ {
+ PCH_LPTLP_HSIO_VER_BX,
+ 0,
+ 0,
+ 0,
+ },
+ PCH_LPTLPBX_HSIO_STRING,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+#endif //ULT_FLAG
+#ifdef TRAD_FLAG
+ {
+ {
+ 1,
+ 0,
+ {
+ PCH_LPTH_HSIO_VER_B0,
+ 0,
+ 0,
+ 0,
+ },
+ PCH_LPTHB0_HSIO_STRING,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+ {
+ {
+ 1,
+ 0,
+ {
+ PCH_LPTH_HSIO_VER_CX,
+ 0,
+ 0,
+ 0,
+ },
+ PCH_LPTHCX_HSIO_STRING,
+ {
+ 0
+ },
+ },
+ NULL
+ },
+#endif //TRAD_FLAG
+};
+
+FVI_DATA_HUB_CALLBACK_CONTEXT mPchFviVersionData = {
+ MISC_SUBCLASS_FVI_HEADER_ENTRY (PCH),
+ mPchFviElementsData,
+};
+
+UINTN mPchFviElements = sizeof (mPchFviElementsData)/ sizeof (FVI_ELEMENT_AND_FUNCTION);
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c
new file mode 100644
index 0000000..df7f05b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.c
@@ -0,0 +1,2469 @@
+/** @file
+ This is the driver that initializes the Intel PCH.
+
+@copyright
+ Copyright (c) 1999 - 2015 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+#include "HeciMsgLib.h"
+#include "ChipsetInitHob.h"
+
+// [ EIP357393 ]+>>>
+#define AMI_PCI_BUS_EXT_PROTOCOL_GUID \
+{ 0xf42a009d, 0x977f, 0x4f08, 0x94, 0x40, 0xbc, 0xa5, 0xa3, 0xbe, 0xd9, 0xaf };
+
+static EFI_GUID gAmiExtPciBusProtocolGuid = AMI_PCI_BUS_EXT_PROTOCOL_GUID;
+// [ EIP357393 ]+<<<
+
+//
+// Global Variables
+//
+EFI_HANDLE mImageHandle;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+extern EFI_USB_HC_PORT_PRECONDITION *mPrivatePreConditionList;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+//
+// GUID Definitions
+//
+EFI_GUID gChipsetInitHobGuid = CHIPSET_INIT_INFO_HOB_GUID;
+EFI_GUID gEfiHeciProtocolGuid = HECI_PROTOCOL_GUID;
+
+//
+// EFI_EVENT
+//
+EFI_EVENT mHeciEvent;
+
+//
+// Local function prototypes
+//
+EFI_STATUS
+InitializePchDevice (
+ IN OUT PCH_INSTANCE_PRIVATE_DATA *PchInstance,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN UINT16 GpioBase
+ );
+
+EFI_STATUS
+ProgramSvidSid (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+VOID
+EFIAPI
+PchExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+VOID
+EFIAPI
+PchInitBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+// [ EIP357393 ]+>>>
+EFI_STATUS
+EFIAPI
+PchSpiLockBeforeEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+// [ EIP357393 ]+<<<
+
+EFI_STATUS
+ChipsetInitSettingsCheck (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+/**
+ Configures PCH IOBP and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+ProgramIobpWithScript (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ EFI_STATUS Status;
+
+ Status = ProgramIobp (RootComplexBar, Address, AndMask, OrMask);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ Address,
+ AndMask,
+ OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Configures 32-bit MMIO register and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+MmioAndThenOr32WithScript (
+ IN UINTN Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ MmioAndThenOr32 (Address, AndMask, OrMask);
+
+ PCH_INIT_COMMON_SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ Address,
+ &OrMask,
+ &AndMask
+ );
+}
+
+/**
+ This is the standard EFI driver point that detects
+ whether there is an PCH southbridge in the system
+ and if so, initializes the chip.
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchInitEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 BusNumber;
+ UINT32 RootComplexBar;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINT32 Index;
+ PCH_INSTANCE_PRIVATE_DATA *PchInstance;
+ UINT16 PmBase;
+ UINT16 GpioBase;
+ UINTN PciD31F0RegBase;
+
+ DEBUG ((EFI_D_INFO, "PchInitEntryPoint() Start\n"));
+
+ PchInstance = NULL;
+ PchPlatformPolicy = NULL;
+
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+ mImageHandle = ImageHandle;
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate and install the PCH Info protocol
+ ///
+ BusNumber = PchPlatformPolicy->BusNumber;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ RootComplexBar = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_RCBA) & B_PCH_LPC_RCBA_BAR;
+ PmBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ GpioBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR;
+
+ ASSERT (RootComplexBar != 0);
+ ASSERT (PmBase != 0);
+ ASSERT (GpioBase != 0);
+
+ DEBUG ((EFI_D_INFO, "PCH Device:\n-------------\n"));
+ DEBUG ((EFI_D_INFO, " RCBA 0x%X\n", RootComplexBar));
+ DEBUG ((EFI_D_INFO, " PmBase 0x%X\n", PmBase));
+ DEBUG ((EFI_D_INFO, " GpioBase 0x%X\n", GpioBase));
+ DEBUG ((EFI_D_INFO, "-------------\n"));
+
+ ///
+ /// Dump whole DXE_PCH_PLATFORM_POLICY_PROTOCOL and serial out.
+ ///
+ PchDumpPlatformProtocol (PchPlatformPolicy);
+ ///
+ /// Initialize the PCH device
+ ///
+ InitializePchDevice (PchInstance, PchPlatformPolicy, RootComplexBar, PmBase, GpioBase);
+
+ PchInstance = AllocateZeroPool (sizeof (PCH_INSTANCE_PRIVATE_DATA));
+ if (PchInstance == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PchInstance->PchInfo.Revision = PCH_INFO_PROTOCOL_REVISION_2;
+ PchInstance->PchInfo.BusNumber = BusNumber;
+ PchInstance->PchInfo.RCVersion = PCH_RC_VERSION;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ PchInstance->PchInfo.Preconditioned = mPrivatePreConditionList;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(HandleBuffer[Index]),
+ &gEfiPchInfoProtocolGuid,
+ &(PchInstance->PchInfo),
+ NULL
+ );
+ }
+
+ (gBS->FreePool) (HandleBuffer);
+
+ DEBUG ((EFI_D_INFO, "PchInitEntryPoint() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the PCH device according to the PCH Platform Policy protocol
+
+ @param[in, out] PchInstance PCH instance private data. May get updated by this function
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] PmBase Power Management IO base address of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+InitializePchDevice (
+ IN OUT PCH_INSTANCE_PRIVATE_DATA *PchInstance,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ BOOLEAN AzaliaEnable;
+ UINT32 FuncDisableReg;
+ VOID *Registration;
+ VOID *Registration1; // [ EIP357393 ]
+ EFI_EVENT LegacyBootEvent;
+ EFI_EVENT ExitBootServicesEvent;
+ UINT16 LpcDeviceId;
+
+ DEBUG ((EFI_D_INFO, "InitializePchDevice() Start\n"));
+
+ FuncDisableReg = MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ ) + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// Take care of any ChipsetInit settings before going any further.
+ ///
+ Status = ChipsetInitSettingsCheck(PchPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Miscellaneous power management handling
+ ///
+ Status = ConfigureMiscPm (PchPlatformPolicy, RootComplexBar, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Additional power management setting
+ ///
+ Status = ConfigureAdditionalPm (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Configures PCH DMI power management configuration
+ ///
+ Status = ConfigureDmiPm (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Deep Sx Enabling
+ ///
+ Status = ProgramDeepSx (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Perform PCH initialization sequence
+ ///
+ Status = ConfigureMiscItems (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+#ifdef ADSP_FLAG
+ ///
+ /// Configure AudioDSP
+ ///
+ if(IS_PCH_LPTLP_LPC_DEVICE_ID(LpcDeviceId)) {
+ Status = ConfigureAudioDsp (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // ADSP_FLAG
+
+ ///
+ /// Detect and initialize the type of codec present in the system
+ ///
+ Status = ConfigureAzalia (PchPlatformPolicy, RootComplexBar, &AzaliaEnable);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Check to disable Azalia controller
+ ///
+ if (!AzaliaEnable) {
+ FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_AZALIA;
+ }
+ ///
+ /// Initialize LAN
+ ///
+ Status = ConfigureLan (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Configure USB
+ ///
+ Status = ConfigureUsb (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize PCIE root ports
+ ///
+ Status = PchInitRootPorts (PchPlatformPolicy, RootComplexBar, PmBase, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Thermal controller already enabled in PEI
+ ///
+
+ ///
+ /// Sata Controllers
+ ///
+ Status = ConfigureSata (PchPlatformPolicy, RootComplexBar, &FuncDisableReg, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Display link
+ ///
+ Status = ConfigureDisplay (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Set the PCH Function Disable Register
+ ///
+ MmioWrite32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS), (UINT32) (FuncDisableReg));
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ 1,
+ &FuncDisableReg
+ );
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &FuncDisableReg, // BitMask
+ &FuncDisableReg, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ ///
+ /// Perform clock gating register settings
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10 Enabling Clock Gating
+ ///
+ Status = ConfigureClockGating (PchPlatformPolicy, RootComplexBar, FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = ConfigureIoApic (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = ProgramSvidSid (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+
+#ifdef SERIAL_IO_FLAG
+ ///
+ /// Configure Serial IO Controllers
+ ///
+ if(IS_PCH_LPTLP_LPC_DEVICE_ID(LpcDeviceId)) {
+ Status = ConfigureSerialIo (PchPlatformPolicy, RootComplexBar);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // SERIAL_IO_FLAG
+
+// [ EIP357393 ]+>>>
+ // Create an AMI ExtPciBus protocol call back event.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gAmiExtPciBusProtocolGuid,
+ EFI_TPL_CALLBACK,
+ PchSpiLockBeforeEndOfDxe,
+ NULL,
+ &Registration1
+ );
+// [ EIP357393 ]+<<<
+
+ ///
+ /// Create an ExitPmAuth protocol call back event.
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gExitPmAuthProtocolGuid,
+ EFI_TPL_CALLBACK,
+ PchInitBeforeBoot,
+ NULL,
+ &Registration
+ );
+
+ ///
+ /// Create events for PCH to do the task before ExitBootServices/LegacyBoot.
+ /// It is guaranteed that only one of two events below will be signalled
+ ///
+ Status = gBS->CreateEvent (
+ EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_CALLBACK,
+ PchExitBootServicesEvent,
+ NULL,
+ &ExitBootServicesEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EfiCreateEventLegacyBootEx (
+ EFI_TPL_CALLBACK,
+ PchExitBootServicesEvent,
+ NULL,
+ &LegacyBootEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchDevice() End\n"));
+
+ return Status;
+}
+
+/**
+ Program Pch devices Subsystem Vendor Identifier (SVID) and Subsystem Identifier (SID).
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ProgramSvidSid (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 Index;
+ UINT16 EhciAccessCntl;
+ UINT8 BusNumber;
+ UINTN PciEAddressBase;
+ UINT8 DeviceNumber;
+ UINT8 FunctionNumber;
+ UINT8 SvidRegOffset;
+ BOOLEAN IsPchEhci;
+ STATIC PCH_SVID_SID_INIT_ENTRY SvidSidInitTable[] = {
+ {
+ 31,
+ 0,
+ R_PCH_LPC_SS
+ },
+ {
+ 31,
+ 2,
+ R_PCH_SATA_AHCI_SVID
+ },
+ {
+ 31,
+ 5,
+ R_PCH_SATA_AHCI_SVID
+ },
+ {
+ 31,
+ 3,
+ R_PCH_SMBUS_SVID
+ },
+ {
+ 31,
+ 6,
+ R_PCH_THERMAL_SVID
+ },
+ {
+ 29,
+ 0,
+ R_PCH_EHCI_SVID
+ },
+ {
+ 26,
+ 0,
+ R_PCH_EHCI_SVID
+ },
+ {
+ 20,
+ 0,
+ R_PCH_XHCI_SVID
+ },
+ {
+ 27,
+ 0,
+ R_PCH_HDA_SVID
+ },
+ {
+ 28,
+ 0,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 1,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 2,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 3,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 4,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 5,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 6,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 28,
+ 7,
+ R_PCH_PCIE_SVID
+ },
+ {
+ 25,
+ 0,
+ R_PCH_LAN_SVID
+ },
+ /* HECI */
+ {
+ 22,
+ 0,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 1,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 2,
+ PCI_SVID_OFFSET
+ },
+ {
+ 22,
+ 3,
+ PCI_SVID_OFFSET
+ }
+ };
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ProgramSvidSid() Start\n"));
+
+ PchSeries = GetPchSeries();
+ EhciAccessCntl = 0;
+ BusNumber = PchPlatformPolicy->BusNumber;
+
+ if ((PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId != 0) ||
+ (PchPlatformPolicy->DefaultSvidSid->SubSystemId != 0)) {
+ for (Index = 0; Index < (sizeof (SvidSidInitTable) / sizeof (PCH_SVID_SID_INIT_ENTRY)); Index++) {
+ DeviceNumber = SvidSidInitTable[Index].DeviceNumber;
+ FunctionNumber = SvidSidInitTable[Index].FunctionNumber;
+ SvidRegOffset = SvidSidInitTable[Index].SvidRegOffset;
+ PciEAddressBase = MmPciAddress (
+ 0,
+ BusNumber,
+ DeviceNumber,
+ FunctionNumber,
+ 0
+ );
+ ///
+ /// Skip if the device is disabled
+ ///
+ if (MmioRead16 (PciEAddressBase) != V_PCH_INTEL_VENDOR_ID) {
+ continue;
+ }
+
+ IsPchEhci = FALSE;
+ if (PchSeries == PchH) {
+ IsPchEhci = IS_PCH_H_EHCI (DeviceNumber, FunctionNumber);
+ } else if (PchSeries == PchLp) {
+ IsPchEhci = IS_PCH_LP_EHCI (DeviceNumber, FunctionNumber);
+ }
+
+ ///
+ /// Set EHCI devices WRT_RDONLY bit (D29:F0,D26:F0:80h, bit 0) to 1, to make SVID and SID registers are writable
+ ///
+ if (IsPchEhci) {
+ EhciAccessCntl = MmioRead16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL));
+ MmioOr16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL), B_PCH_EHCI_ACCESS_CNTL_ENABLE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL)
+ );
+ }
+
+ if ((DeviceNumber == 22 && FunctionNumber == 2) || (DeviceNumber == 22 && FunctionNumber == 3)) {
+ ///
+ /// Sub System Identifiers register of D22:F2&F3 is 32bit access and write once
+ ///
+ MmioWrite32 (
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ (UINT32) (PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId |
+ (PchPlatformPolicy->DefaultSvidSid->SubSystemId << 16))
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + SvidRegOffset)
+ );
+ } else {
+ ///
+ /// Program Pch devices Subsystem Vendor Identifier (SVID)
+ ///
+ MmioWrite16 (
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ PchPlatformPolicy->DefaultSvidSid->SubSystemVendorId
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + SvidRegOffset),
+ 1,
+ (VOID *) (UINTN) (PciEAddressBase + SvidRegOffset)
+ );
+
+ ///
+ /// Program Pch devices Subsystem Identifier (SID)
+ ///
+ MmioWrite16 (
+ (UINTN) (PciEAddressBase + SvidRegOffset + 2),
+ PchPlatformPolicy->DefaultSvidSid->SubSystemId
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + SvidRegOffset + 2),
+ 1,
+ (VOID *) (PciEAddressBase + SvidRegOffset + 2)
+ );
+ }
+ ///
+ /// Restore the EHCI devices WRT_RDONLY bit (D29:F0,D26:F0:80h, bit 0) value
+ ///
+ if (IsPchEhci) {
+ MmioWrite16 ((UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL), EhciAccessCntl);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciEAddressBase + R_PCH_EHCI_ACCESS_CNTL),
+ 1,
+ &EhciAccessCntl
+ );
+ }
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ProgramSvidSid() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize R/WO Registers that described in PCH BIOS Spec
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PciERWORegInit (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINTN Index;
+ UINTN PciD31F5RegBase;
+ UINT8 BusNumber;
+ UINT8 RootPortFunction;
+ UINTN RPBase;
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT8 Data8;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "PciERWORegInit() Start\n"));
+
+ PchSeries = GetPchSeries();
+ BusNumber = PchPlatformPolicy->BusNumber;
+ PciD31F5RegBase = 0;
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, BusNumber, 31, 5, 0);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.12 R/WO Registers, Table 5-4
+ /// System BIOS must read the register and write the same value back to the register
+ /// before passing control to the operating system.
+ /// Dev:Func/Type Register Offset Register Name Bits
+ /// D28:F0-F7 034h Capabilities Pointer 7:0
+ /// D28:F0-F7 040h Capabilities List 15:8
+ /// D28:F0-F7 042h PCI Express Capabilities 8
+ /// D28:F0~F7 044h Device Capabilities 2:0
+ /// D28:F0-F7 04Ch Link Capabilities 11:10, 17:15
+ /// D28:F0-F7 050h Link Control 3
+ /// D28:F0-F7 054h Slot Capabilities 31:19, 16:5
+ /// D28:F0-F7 064h Device Capabilities 2 11
+ /// D28:F0-F7 080h Message Signaled Interrupt Capability ID 15:8
+ /// D28:F0-F7 090h Port Mapping Regster 15:8
+ /// D28:F0-F7 094h Subsystem Vendor ID 31:0
+ /// D28:F0-F7 0D8h Miscellaneous Port Configuration 23, 2
+ /// D28:F0-F7 404h Latency Tolerance Reporting Override 2 2
+ /// RCBA 21A4h Link Capabilities 17:15 For PCH H
+ /// D31:F5 0A8h Next Capabilities Pointer 15:8
+ /// D31:F5 0B2h Capabilities List 9:8
+ ///
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ if (((*FuncDisableReg) & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << Index)) == 0) {
+ RootPortFunction = GetPchPcieRpfn(RootComplexBar, (UINT8)Index);
+ RPBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, RootPortFunction, 0);
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_LCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_LCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_LCAP),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_SVID);
+ MmioWrite32 (RPBase + R_PCH_PCIE_SVID, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_SVID),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_SLCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_SLCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_SLCAP),
+ 1,
+ &Data32
+ );
+ ///
+ /// Added PCIe register to be lockdown
+ ///
+ Data8 = MmioRead8 (RPBase + R_PCH_PCIE_CAPP);
+ MmioWrite8 (RPBase + R_PCH_PCIE_CAPP, Data8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_CAPP),
+ 1,
+ &Data8
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_CLIST);
+ MmioWrite16 (RPBase + R_PCH_PCIE_CLIST, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_CLIST),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_DCAP);
+ MmioWrite16 (RPBase + R_PCH_PCIE_DCAP, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_DCAP),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_MID);
+ MmioWrite16 (RPBase + R_PCH_PCIE_MID, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_MID),
+ 1,
+ &Data16
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_SVCAP);
+ MmioWrite16 (RPBase + R_PCH_PCIE_SVCAP, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_SVCAP),
+ 1,
+ &Data16
+ );
+
+ if (PchSeries == PchLp) {
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_L1SECH);
+ Data32 |= V_PCH_PCIE_L1SECH_L1SUBST_CAP_ID;
+ MmioWrite32 (RPBase + R_PCH_PCIE_L1SECH, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_L1SECH),
+ 1,
+ &Data32
+ );
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_L1SCAP);
+ MmioWrite32 (RPBase + R_PCH_PCIE_L1SCAP, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_L1SCAP),
+ 1,
+ &Data32
+ );
+ }
+ }
+ }
+
+ if (PchSeries == PchH) {
+ ///
+ /// D31:F5:A8h[15:8]
+ ///
+ Data16 = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_CR0);
+ MmioWrite16 (PciD31F5RegBase + R_PCH_SATA_CR0, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_CR0),
+ 1,
+ &Data16
+ );
+ ///
+ /// D31:F5:B2h[9:8]
+ ///
+ Data16 = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_FLR_CLV);
+ MmioWrite16 (PciD31F5RegBase + R_PCH_SATA_FLR_CLV, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_FLR_CLV),
+ 1,
+ &Data16
+ );
+ }
+
+ ///
+ /// D28:F0-F7:42h[8] (PCI Express Capabilities) has been done in PchInitRootPorts().
+ /// D28:F0-F7:4Ch[17:15] (Link Capabilities) has been done in PchInitSingleRootPort().
+ /// D28:F0-F7:404h[2] (Latency Tolerance Reporting Override 2) has been done in PchInitSingleRootPort().
+ /// RCBA + 21A4h[17:15] (Link Capabilities) has been done in ConfigureDmiPm() for PCH H.
+ ///
+
+ DEBUG ((EFI_D_INFO, "PciERWORegInit() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set a Root Port Downstream devices ASPM and LTR S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] RootPortAspm Root port Aspm configuration
+ @param[in] NumOfDevAspmOverride Number of Device specific ASPM policy override items
+ @param[in] DevAspmOverride Pointer to array of Device specific ASPM policy override items
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+ @param[in] NumOfDevLtrOverride Number of Device specific LTR override items
+ @param[in] DevLtrOverride Pointer to array of Device specific LTR policy override items
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SetPciePmS3Item (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspm,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN BOOLEAN FirstRPToSetPm,
+ IN BOOLEAN L1SupportedInAllEnabledPorts,
+ IN BOOLEAN ClkreqSupportedInAllEnabledPorts
+ )
+{
+ EFI_STATUS Status;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+ STATIC EFI_PCH_S3_PARAMETER_PCIE_SET_PM S3ParameterSetPm;
+ STATIC EFI_PCH_S3_DISPATCH_ITEM S3DispatchItem = {
+ PchS3ItemTypePcieSetPm,
+ &S3ParameterSetPm
+ };
+ EFI_PHYSICAL_ADDRESS S3DispatchEntryPoint;
+
+ if (!PchS3Support) {
+ DEBUG ((EFI_D_INFO, "Locating the S3 Support Protocol - PCH Init\n"));
+
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Located the S3 Support Protocol - PCH Init: %x\n", (UINTN)PchS3Support));
+ }
+
+ DEBUG ((EFI_D_INFO, "Attempting to set Custom PCH Init Dispatch Item\n"));
+
+ S3ParameterSetPm.RootPortBus = RootPortBus;
+ S3ParameterSetPm.RootPortDevice = RootPortDevice;
+ S3ParameterSetPm.RootPortFunc = RootPortFunc;
+ S3ParameterSetPm.RootPortAspm = RootPortAspm;
+ S3ParameterSetPm.NumOfDevAspmOverride = NumOfDevAspmOverride;
+ S3ParameterSetPm.DevAspmOverrideAddr = (UINT32) (UINTN) DevAspmOverride;
+ S3ParameterSetPm.TempBusNumberMin = TempBusNumberMin;
+ S3ParameterSetPm.TempBusNumberMax = TempBusNumberMax;
+ S3ParameterSetPm.PchPwrOptPcie = (UINT32) (UINTN) PchPwrOptPcie;
+ S3ParameterSetPm.NumOfDevLtrOverride = NumOfDevLtrOverride;
+ S3ParameterSetPm.DevLtrOverrideAddr = (UINT32) (UINTN) DevLtrOverride;
+ S3ParameterSetPm.L1SubstatesConfig = L1SubstatesConfig;
+ S3ParameterSetPm.PolicyRevision = PolicyRevision;
+ S3ParameterSetPm.FirstRPToSetPm = FirstRPToSetPm;
+ S3ParameterSetPm.L1SupportedInAllEnabledPorts = L1SupportedInAllEnabledPorts;
+ S3ParameterSetPm.ClkreqSupportedInAllEnabledPorts = ClkreqSupportedInAllEnabledPorts;
+ Status = PchS3Support->SetDispatchItem (
+ PchS3Support,
+ &S3DispatchItem,
+ &S3DispatchEntryPoint
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Save the script dispatch item in the Boot Script
+ ///
+ SCRIPT_DISPATCH (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, S3DispatchEntryPoint);
+#else
+ Status = EFI_SUCCESS;
+#endif
+ return Status;
+}
+
+/**
+ PCH initialization before ExitBootServices / LegacyBoot events
+ Useful for operations which must happen later than at EndOfPost event
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINTN Index;
+ UINT32 AhciBar;
+ UINTN PciD31F2RegBase;
+ UINT16 SataModeSelect;
+ UINT16 LpcDeviceId;
+ UINT32 PxSctlDet;
+ UINT32 PxCmdSud;
+ UINT16 OrgCmdWord;
+
+ ///
+ /// Closed the event to avoid call twice
+ ///
+ gBS->CloseEvent (Event);
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ ) + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return;
+ }
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return;
+ }
+
+ ConfigureXhciAtBoot (PchPlatformPolicy);
+#ifdef SERIAL_IO_FLAG
+ ConfigureSerialIoAtBoot(PchPlatformPolicy);
+#endif // SERIAL_IO_FLAG
+
+ ///
+ /// eSATA port support only up to Gen2
+ ///
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_SATA, PCI_FUNCTION_NUMBER_PCH_SATA, 0);
+ //
+ // Make sure SATA device exists.
+ //
+ if (MmioRead16 (PciD31F2RegBase + R_PCH_SATA_VENDOR_ID) != 0xFFFF) {
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ if ((SataModeSelect == V_PCH_SATA_MAP_SMS_AHCI) ||
+ (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID)) {
+ AhciBar = MmioRead32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR) & B_PCH_SATA_AHCI_BAR_BA;
+ //
+ // Make sure the AhciBar is valid.
+ //
+ if ((AhciBar != 0x00000000) && (AhciBar != 0xFFFFFFFF)) {
+ ///
+ /// Keep original CMD word, and enable MSE
+ ///
+ OrgCmdWord = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_COMMAND);
+ if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) {
+ MmioOr16 ((PciD31F2RegBase + R_PCH_SATA_COMMAND), B_PCH_SATA_COMMAND_MSE);
+ }
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if (PchPlatformPolicy->SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ PxSctlDet = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))) & B_PCH_SATA_AHCI_PXSCTL_DET;
+ PxCmdSud = MmioRead32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))) & B_PCH_SATA_AHCI_PxCMD_SUD;
+ ///
+ /// Limit speed to Gen2
+ ///
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD),
+ (UINT32) V_PCH_SATA_AHCI_PXSCTL_SPD_2
+ );
+ ///
+ /// If port is not offline, and it's spin up, need to port reset.
+ /// After port reset, clear the SERR.
+ /// - Set DET=1, and then set DET=0.
+ ///
+ if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_0) &&
+ (PxCmdSud == B_PCH_SATA_AHCI_PxCMD_SUD))
+ {
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_1);
+ PchPmTimerStall (1000);
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET));
+ MmioWrite32 (AhciBar + (R_PCH_SATA_AHCI_P0SERR + (0x80 * Index)), (UINT32)~0u);
+ }
+ ///
+ /// If port is offline, and it's not spin up, meets the power bug.
+ /// Need to do the W/A to spin up the port and then spin down.
+ /// Then entering back to offline and listen.
+ /// - Set DET=0, SUD=1, and then set SUD=0, DET=4.
+ ///
+ if ((PxSctlDet == V_PCH_SATA_AHCI_PXSCTL_DET_4) &&
+ (PxCmdSud == 0))
+ {
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PXSCTL_DET));
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), B_PCH_SATA_AHCI_PxCMD_SUD);
+ PchPmTimerStall (1000);
+ MmioAnd32(AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)), (UINT32) ~(B_PCH_SATA_AHCI_PxCMD_SUD));
+ MmioOr32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)), V_PCH_SATA_AHCI_PXSCTL_DET_4);
+ }
+ }
+ }
+ ///
+ /// Restore original CMD word.
+ ///
+ if ((OrgCmdWord & B_PCH_SATA_COMMAND_MSE) == 0) {
+ MmioWrite16 ((PciD31F2RegBase + R_PCH_SATA_COMMAND), OrgCmdWord);
+ }
+ } // AhciBar is vaild
+ } // SATA mode is AHCI or RAID
+ } // if D31F2 is existed
+ }
+
+ return;
+}
+
+/**
+ PCH checkes the HECI protocol and sends ChipsetInitSyncMsg
+
+ @param[in] Event Event objext
+ @param[in] *Context VOID Pointer
+
+ @retval None
+**/
+VOID
+EFIAPI
+ChipsetInitSyncCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ EFI_HECI_PROTOCOL *Heci;
+ CHIPSET_INIT_INFO_HOB *ChipsetInitHob;
+
+ ChipsetInitHob = NULL;
+ Status = EFI_SUCCESS;
+ DEBUG ((EFI_D_INFO, "ChipsetInitSyncCallback() Start\n"));
+
+ //
+ // Get the HECI protocol to make sure HECI is ready.
+ //
+ Status = gBS->LocateProtocol (&gEfiHeciProtocolGuid, NULL, (VOID **) &Heci);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ if (mHeciEvent) {
+ gBS->CloseEvent (mHeciEvent);
+ }
+
+ //
+ // Search for the ChipsetInit Info PEIM GUID HOB.
+ //
+ ChipsetInitHob = GetFirstGuidHob (&gChipsetInitHobGuid);
+ if (ChipsetInitHob == NULL) {
+ DEBUG ((EFI_D_INFO, "ChipsetInitHob not found.\n"));
+ return;
+ }
+
+ //
+ // If ChipsetInitTableUpdReq == 0, settings are already in sync and no furhter work needed
+ //
+ if (ChipsetInitHob->ChipsetInitTableUpdReq == 1) {
+ //
+ // If we do not have the ChipsetInit table that ME FW expects us to have,
+ // we must send the current ChipsetInit table to ME FW via HECI message.
+ //
+ Status = HeciChipsetInitSyncMsg(ChipsetInitHob->ChipsetInitTable, ChipsetInitHob->ChipsetInitTableLen);
+ }
+
+ DEBUG ((EFI_D_INFO, "ChipsetInitSyncCallback() End\n"));
+
+ return;
+}
+
+/**
+ Register the HECI protocol callback function for the ChipsetInit sync message.
+
+ @param[in] *PchPlatformPolicy A pointer to the PchPlatformPolicy.
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+ChipsetInitSettingsCheck (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+ EFI_STATUS Status;
+ VOID *HeciRegistration;
+
+ DEBUG ((EFI_D_INFO, "ChipsetInitSettingsCheck() Start\n"));
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ ChipsetInitSyncCallback,
+ NULL,
+ &mHeciEvent
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBS->RegisterProtocolNotify (
+ &gEfiHeciProtocolGuid,
+ mHeciEvent,
+ &HeciRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ ChipsetInitSyncCallback (NULL, NULL);
+
+ return Status;
+}
+
+/**
+ Update ASL object before Boot
+
+ @param[in] *PchPlatformPolicy A pointer to the PchPlatformPolicy.
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_STATUS
+ @retval EFI_NOT_READY The Acpi protocols are not ready.
+**/
+EFI_STATUS
+PchUpdateAslObjects (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN VariableSize;
+ UINT32 PciMemBase;
+ PCH_LATE_INIT_SMM_VARIABLE SaveRestoreData;
+ UINT32 AslSignature;
+ UINT32 RpFn;
+ UINT32 Data32;
+
+ Status = InitializePchAslUpdateLib();
+ DEBUG ((EFI_D_INFO, "InitializePchAslUpdateLib Status %x\n", Status));
+ ASSERT_EFI_ERROR (Status);
+
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Update SRMB, Save & Restore Memroy Base
+ //
+ VariableSize = sizeof (PCH_LATE_INIT_SMM_VARIABLE);
+ Status = gRT->GetVariable (
+ PCH_INIT_PEI_VARIABLE_NAME,
+ &gPchInitPeiVariableGuid,
+ NULL,
+ &VariableSize,
+ &SaveRestoreData
+ );
+ PciMemBase = SaveRestoreData.PciMemBase;
+ Status = UpdateNameAslCode(EFI_SIGNATURE_32('S','R','M','B'), &PciMemBase, sizeof(PciMemBase));
+
+ RpFn = MmioRead32 (RootComplexBar + R_PCH_RCRB_RPFN);
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ //
+ // Update RPA0, RPA1, RPA2, RPA3, RPA4, RPA5, RPA6, RPA7 for root port function swapping
+ //
+ Data32 = '0' + (UINT32)Index;
+ AslSignature = EFI_SIGNATURE_32('R','P','A',Data32);
+ Data32 = (UINT32)((RpFn >> (Index * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+ Data32 |= (UINT32)(PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16);
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update RPAx %x %x\n", Index, Data32));
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE
+ //
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ AslSignature = EFI_SIGNATURE_32('P','M','L',(UINT32)('1' + Index));
+ Data32 = (UINT32) PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[Index].LtrMaxSnoopLatency;
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update PMLx %x %x\n", Index+1, Data32));
+ ASSERT_EFI_ERROR (Status);
+ AslSignature = EFI_SIGNATURE_32('P','N','L',(UINT32)('1' + Index));
+ Data32 = (UINT32) PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[Index].LtrMaxNoSnoopLatency;
+ Status = UpdateNameAslCode(AslSignature, &Data32, sizeof(UINT32));
+ DEBUG ((EFI_D_INFO, "Update PNLx %x %x\n", Index+1, Data32));
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ //
+ // Update PCHS.
+ //
+ Data32 = (UINT32) GetPchSeries();
+ Status = UpdateNameAslCode(EFI_SIGNATURE_32('P','C','H','S'), &Data32, sizeof(UINT32));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ PCH initialization before Boot Sript Table is closed
+
+ @param[in] Event A pointer to the Event that triggered the callback.
+ @param[in] Context A pointer to private data registered with the callback function.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchInitBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINT32 RootComplexBar;
+ UINT32 FuncDisableReg;
+ UINTN PciD25F0RegBase;
+ UINTN PciD31F2RegBase;
+ UINT32 GbEMemBar;
+ UINTN PciD31F0RegBase;
+ UINTN GbeRootPortNumber;
+ UINT16 PmBase;
+ UINT16 GpioBase;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 Data32;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT8 Data8;
+ VOID *ProtocolPointer;
+ UINTN AzaliaBase;
+ const UINT8 StrEnabled[sizeof (PCH_CRID_ENABLED)] = PCH_CRID_ENABLED;
+ const UINT8 StrDisabled[sizeof (PCH_CRID_DISABLED)] = PCH_CRID_DISABLED;
+ EFI_HANDLE Handle;
+ PCH_SERIES PchSeries;
+ BOOLEAN L1SubstatesSupportedPerPort;
+ PCI_DATA_STRUCTURE *PcirBlockPtr;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_EXPANSION_ROM_HEADER *RomImage;
+ BOOLEAN FoundLegacyRaid;
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2;
+ CHAR16 RstDriverName1[] = L"Intel RST";
+ CHAR16 RstDriverName2[] = L"Intel(R) RST";
+ EFI_DRIVER_SUPPORTED_EFI_VERSION_PROTOCOL *DriverEfiVersion;
+ EFI_STRING DriverName;
+ UINT16 AspmVal;
+ BOOLEAN ClkreqPerPortSupported;
+ BOOLEAN ClkreqSupportedInAllEnabledPorts;
+ BOOLEAN L1SupportedInAllEnabledPorts;
+ BOOLEAN FirstRPToSetPm;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+#endif
+
+ UINTN RPBase;
+ UINT8 PortIndex;
+ PCH_PCIE_DEVICE_ASPM_OVERRIDE *S3DevAspmOverrideTbl;
+ PCH_PCIE_PWR_OPT *S3PchPwrOptPcie;
+ UINT32 DevAspmOverrideTblSize;
+ PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspmVal;
+ UINT8 NumOfDevltrOverride;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *S3DevLtrOverrideTbl;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverrideTbl;
+ UINT32 DevLtrOverrideTblSize;
+ PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubVal;
+ BOOLEAN LtrSupported;
+
+ S3DevLtrOverrideTbl = NULL;
+ DevLtrOverrideTbl = NULL;
+ NumOfDevltrOverride = 0;
+ LtrSupported = TRUE;
+ L1SubstatesSupportedPerPort = FALSE;
+ Handle = NULL;
+ PchSeries = GetPchSeries();
+ AspmVal = 0;
+ ClkreqPerPortSupported = FALSE;
+ ClkreqSupportedInAllEnabledPorts = TRUE;
+ L1SupportedInAllEnabledPorts = TRUE;
+ FirstRPToSetPm = TRUE;
+
+ ///
+ /// Check whether this is real ExitPmAuth notification, or just a SignalEvent
+ ///
+ Status = gBS->LocateProtocol (&gExitPmAuthProtocolGuid, NULL, (VOID **) &ProtocolPointer);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ DEBUG ((EFI_D_INFO, "PchInitBeforeBoot() Start\n"));
+
+ ///
+ /// Closed the event to avoid call twice when launch shell
+ ///
+ gBS->CloseEvent (Event);
+
+ ///
+ /// Retrieve all instances of PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return;
+ }
+ ///
+ /// Find the matching PCH Policy protocol
+ ///
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return;
+ }
+
+ InitFviDataHubCbContext (
+ PchPlatformPolicy->MiscConfig->FviSmbiosType,
+ (UINT8) mPchFviElements,
+ &mPchFviVersionData
+ );
+
+ RootComplexBar = PCH_RCRB_BASE;
+
+ FuncDisableReg = MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ GpioBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR;
+ PmBase = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ Status = PciERWORegInit (PchPlatformPolicy, RootComplexBar, &FuncDisableReg);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locking Thermal Reporting Settings prior to end of POST
+ ///
+ Status = ThermalLockDown (PchPlatformPolicy, GpioBase);
+ ASSERT_EFI_ERROR (Status);
+
+ if ((FuncDisableReg & B_PCH_RCRB_FUNC_DIS_AZALIA) == 0) {
+ AzaliaBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_AZALIA,
+ PCI_FUNCTION_NUMBER_PCH_AZALIA,
+ 0
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 9.5
+ /// Additional High Definition Audio Programming Steps
+ /// Step 5
+ /// Set D27:F0:40h[1] = 1b after all settings done including 19.10.5
+ ///
+ MmioOr8 (AzaliaBase + R_PCH_HDA_HDCTL, B_PCH_HDA_HDCTL_BCLD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AzaliaBase + R_PCH_HDA_HDCTL),
+ 1,
+ (VOID *) (UINTN) (AzaliaBase + R_PCH_HDA_HDCTL)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 19.4
+ /// Step 29
+ /// Set RCBA + Offset 3A6Ch[31:0] = 0x00000001, after step #26 to #28 are done
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C),
+ (UINT32) (0x00000001)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A6C)
+ );
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 19.4 Additional Power Management Programming
+ /// Step 30
+ /// Set RCBA + Offset 2344h[31:24] = 0xFF
+ /// Set RCBA + Offset 2344h[7:0] = 0x0C
+ ///
+ Data32And = (UINT32)~(0xFF00000F);
+ Data32Or = (UINT32) (0xFF00000C);
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + 0x2344),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2344),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ } else if (PchSeries == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.3.0 Section 31.7.2
+ /// Step 5
+ /// Set RCBA + Offset 2618h [25] = 1b.
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x2618),
+ (UINT32) (BIT25)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2618),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2618)
+ );
+ }
+/* // [ EIP357393 ]+>>>
+ ///
+ /// SPI Flash Programming Guide Section 5.5.1 Flash Configuration Lockdown
+ /// It is strongly recommended that BIOS sets the Host and GbE Flash Configuration Lock-Down (FLOCKDN)
+ /// bits (located at SPIBAR + 04h and MBAR + 04h respectively) to 1 on production platforms
+ ///
+ if (PchSeries == PchH) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN + B_PCH_SPI_PRR3PRR4_LOCKDN));
+ } else if (PchSeries == PchLp) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN));
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_SPI_HSFS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_HSFS)
+ );
+*/ // [ EIP357393 ]+<<<
+
+ ///
+ /// Set the GbE Flash Configuration Lock-Down (FLOCKDN) bit (MBAR + 04h[15]) to 1
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_ENABLE) {
+ PciD25F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 25, 0, 0);
+ ///
+ /// Enable memory space decoding in command register
+ ///
+ Data16And = 0xFFFF;
+ Data16Or = (UINT16) B_PCH_LAN_CMD_MSE;
+ MmioOr16 (PciD25F0RegBase + R_PCH_LAN_CMD, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_CMD),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+/* // [ EIP357393 ]+>>>
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MBARB) & B_PCH_LAN_MBARB_BA;
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB)
+ );
+ MmioOr16 (GbEMemBar + 0x04, BIT15);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (GbEMemBar + 0x04),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x04)
+ );
+ }
+*/ // [ EIP357393 ]+<<<
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 10.5 Additional GbE Controller Configurations for WOL Support
+ /// System BIOS requires to program the registers listed below for internal GbE.
+ /// Step 1, Set MBARA + Offset 2Ch [31] = 1b
+ /// Step 2, If WOL is enabled set MBARA + Offset 2Ch [30] = 1b
+ /// else if disabled set MBARA + Offset 2Ch [30] = 0b
+ ///
+ /// Additional Steppings:
+ /// Set MBARA + Offset 10h [31] = 1b
+ ///
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A) & B_PCH_LAN_MBARA_BA;
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A)
+ );
+ MmioOr32 (GbEMemBar + 0x2c, (BIT31));
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.WolEnableOverride) {
+ MmioOr32 (GbEMemBar + 0x2c, (BIT30));
+ } else {
+ MmioAnd32 (GbEMemBar + 0x2c, (UINT32) (~BIT30));
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (GbEMemBar + 0x2c),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x2c)
+ );
+
+ ///
+ /// Set GbEMemBar + 0x10[31] to 1b if Gbe Clkreq is in native mode (0b)
+ ///
+ if (PchSeries == PchLp) {
+ GbeRootPortNumber = PchGetGbePortNumber();
+ Data32 = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + GbeRootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ if (Data32 == 0) {
+ MmioOr32 (GbEMemBar + 0x10, BIT31);
+ } else {
+ MmioAnd32 (GbEMemBar + 0x10, (UINT32) (~BIT31));
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (GbEMemBar + 0x10),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x10)
+ );
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 11
+ /// Program D31:F2:98h [29] to 1b
+ ///
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x98), BIT29);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x98),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x98)
+ );
+ ///
+ /// Step 14
+ /// Program D31:F2:9Ch [31] to 1b
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x9C), BIT31);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x9C),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x9C)
+ );
+ ///
+ /// Do the Pcie ASPM enable prior to the end of POST
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ ///
+ /// Allcoate and Copy the entire Aspm override table pointed by DevAspmOverride to < 4G EfiReservedMemory
+ /// It's for S3 resume used.
+ ///
+ DevAspmOverrideTblSize = PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride *
+ sizeof (PCH_PCIE_DEVICE_ASPM_OVERRIDE);
+ S3DevAspmOverrideTbl = AllocateReservedCopyPool (
+ DevAspmOverrideTblSize,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride
+ );
+ ASSERT_EFI_ERROR (S3DevAspmOverrideTbl != NULL);
+
+ ///
+ /// Allcoate and Copy the entire LTR override table pointed by DevLtrOverride to < 4G EfiReservedMemory
+ /// It's used for S3 resume used.
+ ///
+ DevLtrOverrideTbl = PchPlatformPolicy->PwrOptConfig->DevLtrOverride;
+ NumOfDevltrOverride = PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride;
+ if ((DevLtrOverrideTbl != NULL) && (NumOfDevltrOverride != 0)) {
+ DevLtrOverrideTblSize = NumOfDevltrOverride * sizeof (PCH_PCIE_DEVICE_LTR_OVERRIDE);
+ S3DevLtrOverrideTbl = AllocateReservedCopyPool (
+ DevLtrOverrideTblSize,
+ DevLtrOverrideTbl
+ );
+ ASSERT_EFI_ERROR (S3DevLtrOverrideTbl != NULL);
+ }
+ ///
+ /// Check all the enabled root ports and end point devices if they support Clkreq Per Port, L1 and L1 substates
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ RPBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, GetPchPcieRpfn(RootComplexBar, PortIndex), 0);
+ if (((FuncDisableReg & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex)) == 0) && ((MmioRead16 (RPBase + R_PCH_PCIE_SLSTS) & B_PCH_PCIE_SLSTS_PDS) != 0)) {
+ RootPortAspmVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].Aspm;
+ L1SubVal = PchPcieL1SubstatesL1_1_2;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ L1SubVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].L1Substates;
+ }
+ Status = PcieCheckPmConfig (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ DevLtrOverrideTbl,
+ &(PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]),
+ &L1SubstatesSupportedPerPort,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ &AspmVal,
+ &ClkreqPerPortSupported,
+ &LtrSupported
+ );
+ if ((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) != V_PCH_PCIE_LCTL_APMC_L1) {
+ L1SupportedInAllEnabledPorts = FALSE;
+ }
+ ClkreqSupportedInAllEnabledPorts &= ClkreqPerPortSupported;
+ }
+ }
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ if ((FuncDisableReg & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex)) == 0) {
+ S3PchPwrOptPcie = AllocateReservedCopyPool (
+ sizeof (PCH_PCIE_PWR_OPT),
+ &PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]
+ );
+ ASSERT_EFI_ERROR (S3PchPwrOptPcie != NULL);
+ RootPortAspmVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].Aspm;
+ L1SubVal = PchPcieL1SubstatesL1_1_2;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ L1SubVal = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].L1Substates;
+ }
+ Status = PcieSetPm (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->DevAspmOverride,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ DevLtrOverrideTbl,
+ &(PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex]),
+ &L1SubstatesSupportedPerPort,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ FirstRPToSetPm,
+ L1SupportedInAllEnabledPorts,
+ ClkreqSupportedInAllEnabledPorts,
+ &LtrSupported
+ );
+ Status = SetPciePmS3Item (
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PortIndex),
+ RootPortAspmVal,
+ PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride,
+ S3DevAspmOverrideTbl,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ NumOfDevltrOverride,
+ S3DevLtrOverrideTbl,
+ S3PchPwrOptPcie,
+ L1SubVal,
+ PchPlatformPolicy->Revision,
+ FirstRPToSetPm,
+ L1SupportedInAllEnabledPorts,
+ ClkreqSupportedInAllEnabledPorts
+ );
+ FirstRPToSetPm = FALSE;
+ }
+ }
+ ///
+ /// LPT-LP only: If not all devices support LTR, set RCBA + 0x3320 to 0x00010003
+ ///
+ if (!LtrSupported && (PchSeries == PchLp) ) {
+ MmioAndThenOr32 ( (RootComplexBar + 0x3320), 0, 0x00010003);
+ }
+ ///
+ /// SPI Flash Programming Guide Section 5.5.2 Vendor Component Lock
+ /// It is strongly recommended that BIOS sets the Vendor Component Lock (VCL) bits. VCL applies
+ /// the lock to both VSCC0 and VSCC1 even if VSCC0 is not used. Without the VCL bits set, it is
+ /// possible to make Host/GbE VSCC register(s) changes in that can cause undesired host and
+ /// integrated GbE Serial Flash functionality.
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_SPI_VSCC0), B_PCH_SPI_VSCC0_VCL);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_SPI_VSCC0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_VSCC0)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.4 Additional Power Management Programming
+ /// Step 3
+ /// Set GEN_PMCON_LOCK register, D31:F0:A6h = 06h, after stretch and ACPI base programming completed.
+ ///
+ MmioOr8 (
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK),
+ (UINT8) (B_PCH_LPC_GEN_PMCON_LOCK_S4_STRET_LD | B_PCH_LPC_GEN_PMCON_LOCK_ABASE_LK)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_LOCK)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 3.6 Flash Security Recommendation
+ /// Step 1
+ /// Intel strongly recommends that BIOS enables the BIOS Lock Enable (BLE) feature of the PCH.
+ /// Left to platform code to register an callback function to handle IchnBiosWp SMI
+ ///
+ /// Step 2
+ /// Intel strongly recommends that BIOS enables SMI_LOCK (B0:D31:F0:Offset A0h [4]=1)
+ /// which prevent writes to the Global SMI Enable bit (GLB_SMI_EN PMBASE + 30h Bit
+ /// [0]). Enabling this bit will mitigate malicious software attempts to gain system management
+ /// mode privileges.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->GlobalSmi == PCH_DEVICE_ENABLE) {
+ ///
+ /// Save Global SMI Enable bit setting before BIOS enables SMI_LOCK during S3 resume
+ ///
+ Data32Or = IoRead32 ((UINTN) (PmBase + R_PCH_SMI_EN));
+ if ((Data32Or & B_PCH_SMI_EN_GBL_SMI) != 0) {
+ Data32And = 0xFFFFFFFF;
+ Data32Or &= B_PCH_SMI_EN_GBL_SMI;
+ SCRIPT_IO_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PmBase + R_PCH_SMI_EN),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ MmioOr8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), B_PCH_LPC_GEN_PMCON_SMI_LOCK);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1)
+ );
+ }
+ ///
+ /// Step 3
+ /// Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit
+ /// (RCBA+3410[0]=1 General Control and Status - BILD). Setting this bit will prevent writes
+ /// to the Backup Control Register Top Swap bit (BUC.TS RCBA + 3414 [0]) and the General
+ /// Control and Status Registers Boot BIOS Straps (RCBA + 3410h [11:10]). Enabling this bit
+ /// will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->BiosInterface == PCH_DEVICE_ENABLE) {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_GCS), (UINT32) B_PCH_RCRB_GCS_BILD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_GCS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_GCS)
+ );
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ Data32Or = MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_GCS));
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_GCS),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ }
+ ///
+ /// PCH EDS Rev 1.0, Section 14.1.35.1.2
+ /// SATA Indexed Register 1Ch Bit18, 1 = This bit allows entrance to the PCH SATA test modes when set.
+ /// This bit should only be set when following the PCH MSQT for system board testing.
+ /// It is recommended to set this bit manually.
+ ///
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.15 IntelR Stable Image Platform Program (SIPP)
+ /// For platforms supporting Intel(R) SIPP, System BIOS will need to enable the CRID feature by:
+ /// Write the value 1Dh to to the RevID field in B0:D31:F0 Offset 08h
+ ///
+
+ ///
+ /// Update CRID FVI record
+ ///
+ mPchFviElementsData[CRID_ORIGINAL].Element.Version.BuildNum = (UINT16) MmioRead8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID));
+ if (PchPlatformPolicy->DeviceEnabling->Crid == PCH_DEVICE_ENABLE) {
+ Data8 = 0x1D;
+ MmioWrite8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID), Data8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_RID),
+ 1,
+ &Data8
+ );
+ CopyMem (mPchFviElementsData[CRID_STATUS].Element.VerString, StrEnabled, sizeof (StrEnabled));
+ } else {
+ CopyMem (mPchFviElementsData[CRID_STATUS].Element.VerString, StrDisabled, sizeof (StrDisabled));
+ }
+
+ mPchFviElementsData[CRID_NEW].Element.Version.BuildNum = (UINT16) MmioRead8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_RID));
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 16.4 GPIO Registers Lockdown
+ /// If GPIO configurations are not used after boot, it is recommended that the GLE Lockdown Enable
+ /// and the GPIO_UNLOCK_SMI_EN bits are set by BIOS prior to end of POST.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->GpioLockDown == PCH_DEVICE_ENABLE) {
+ ///
+ /// Set GPIO Lockdown Enable bit
+ ///
+ MmioOr8 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT), (UINT8) B_PCH_LPC_GPIO_LOCKDOWN_EN);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GPIO_CNT)
+ );
+ ///
+ /// Please locate SMM ICHn SMI Dispatch Extended Protocol and register the callback function to
+ /// IchnExGpioUnlock to set GPIO_UNLOCK_SMI_EN bit in the platform code.
+ ///
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.13 BIOS guide on using RTC RAM
+ /// For Data integrity protection, set RTC Memory locks (Upper 128 Byte Lock and
+ /// Lower 128 Byte Lock) at RCBA + 3400h[4] and RCBA + 3400h[3]. Note once locked
+ /// bytes 0x38 - 0x3F in each of the Upper and Lower Byte blocks, respectively,
+ /// cannot be unlocked until next reset.
+ ///
+ if (PchPlatformPolicy->LockDownConfig->RtcLock == PCH_DEVICE_ENABLE) {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF),
+ (UINT32) (B_PCH_RCRB_RTC_CONF_UCMOS_LOCK | B_PCH_RCRB_RTC_CONF_LCMOS_LOCK)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_RTC_CONF)
+ );
+ }
+ ///
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 3.6 Flash Security Recommendation
+ /// Step 1
+ /// BIOS needs to enable the BIOS Lock Enable (BLE) feature of the PCH by setting
+ /// B0:D31:F0:DCh[1] = 1b. When this bit is set, attempts to write the BIOS Write
+ /// Enable (BIOSWE) bit in PCH will cause a SMI which will allow the BIOS to verify
+ /// that the write is from a valid source. Remember that BIOS needs to set B0:D31:F0
+ /// Offset DC [0] = 0b to enable BIOS region protection before exiting the SMI handler.
+ /// Also, TCO_EN bit needs to be set (SMI_EN Register, PMBASE + 30h[13] = 1b) to keep
+ /// BLE feature enabled after booting to the OS.
+ ///
+ /// Generate PCH IO TRAP SMI to register IchnBiosWp callback function in
+ /// PchBiosLockIoTrapCallback() to handle TCO BIOSWR SMI
+ ///
+ if ((PchPlatformPolicy->LockDownConfig->BiosLock == PCH_DEVICE_ENABLE)) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "PchBiosLockIoTrapAddress = 0x%x\n",
+ PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress)
+ );
+
+ if (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0) {
+ ///
+ /// Write PCH_BWP_SIGNATURE to IoTrap Address
+ ///
+ IoWrite32 (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress, PCH_BWP_SIGNATURE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_BIOS_CNTL),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_BIOS_CNTL)
+ );
+ }
+ }
+ ///
+ /// Lock Down TCO
+ ///
+ Data16And = 0xFFFF;
+ Data16Or = B_PCH_TCO_CNT_LOCK;
+ IoOr16(PmBase + PCH_TCO_BASE + R_PCH_TCO1_CNT, Data16Or);
+ SCRIPT_IO_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PmBase + PCH_TCO_BASE + R_PCH_TCO1_CNT),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.15.1 Additional Chipset Initialization
+ /// Step 1
+ /// Set SPIBAR + F0h [0] to 1b
+ ///
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDL), B_PCH_SPI_SRDL_SSL);
+ ///
+ /// Check to disable Smbus controller
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Smbus == PCH_DEVICE_DISABLE) {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS), (UINT32) B_PCH_RCRB_FUNC_DIS_SMBUS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS)
+ );
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ Data32Or = MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS));
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ }
+
+ UsbInitBeforeBoot (PchPlatformPolicy);
+ FoundLegacyRaid = FALSE;
+ ///
+ /// Get all PCI IO protocols
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Find the RAID BIOS by checking each PCI IO handle for RST OPROM
+ ///
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo
+ );
+ if (EFI_ERROR (Status) || (PciIo->RomImage == NULL)) {
+ ///
+ /// If this PCI device doesn't have a ROM image, skip to the next device.
+ ///
+ continue;
+ }
+
+ RomImage = PciIo->RomImage;
+
+ ///
+ /// Get pointer to PCIR structure
+ ///
+ PcirBlockPtr = (PCI_DATA_STRUCTURE *) ((UINTN) RomImage + RomImage->PcirOffset);
+
+ ///
+ /// Check if we have an RAID BIOS OPROM.
+ ///
+ if ((RomImage->Signature == 0xAA55) &&
+ (PcirBlockPtr->ClassCode[0] == 0x00) &&
+ (PcirBlockPtr->ClassCode[1] == 0x04) &&
+ (PcirBlockPtr->ClassCode[2] == 0x01)
+ ) {
+ mPchFviElementsData[RAID_VER].Element.Version.MajorVersion = (UINT8) ((PcirBlockPtr->CodeRevision & 0xFF00) >> 8);
+ mPchFviElementsData[RAID_VER].Element.Version.MinorVersion = (UINT8) (PcirBlockPtr->CodeRevision & 0x00FF);
+ mPchFviElementsData[RAID_VER].Element.Version.Revision = 0;
+ mPchFviElementsData[RAID_VER].Element.Version.BuildNum = 0;
+ FoundLegacyRaid = TRUE;
+ }
+ }
+ }
+ ///
+ /// Search EFI RST OPROM
+ ///
+ if (FoundLegacyRaid == FALSE) {
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiComponentName2ProtocolGuid,
+ (VOID **) &ComponentName2
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = ComponentName2->GetDriverName (ComponentName2, LANGUAGE_CODE_ENGLISH, &DriverName);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ if ((StrnCmp (DriverName, RstDriverName1, (sizeof (RstDriverName1) / sizeof (CHAR16)) - 1) == 0) ||
+ (StrnCmp (DriverName, RstDriverName2, (sizeof (RstDriverName2) / sizeof (CHAR16)) - 1) == 0)) {
+ Status = gBS->HandleProtocol(
+ HandleBuffer[Index],
+ &gEfiDriverSupportedEfiVersionProtocolGuid,
+ (VOID**)&DriverEfiVersion);
+ mPchFviElementsData[RAID_VER].Element.Version.MajorVersion = (UINT8) ((DriverEfiVersion->FirmwareVersion & 0x00FF0000) >> 16);
+ mPchFviElementsData[RAID_VER].Element.Version.MinorVersion = (UINT8) (DriverEfiVersion->FirmwareVersion & 0x000000FF);
+ mPchFviElementsData[RAID_VER].Element.Version.Revision = 0;
+ mPchFviElementsData[RAID_VER].Element.Version.BuildNum = 0;
+ }
+ }
+ }
+ }
+
+ if (PchSeries == PchLp) {
+#ifdef SERIAL_IO_FLAG
+ ConfigureSerialIoBeforeBoot(PchPlatformPolicy, RootComplexBar);
+#endif // SERIAL_IO_FLAG
+#ifdef ADSP_FLAG
+ ConfigureAudioDspBeforeBoot (PchPlatformPolicy, RootComplexBar);
+#endif // ADSP_FLAG
+ }
+
+ //
+ // Update ASL objects
+ //
+ PchUpdateAslObjects (PchPlatformPolicy, RootComplexBar);
+
+ //
+ // Create RC FVI data hubs
+ //
+ CreateRcFviDatahub (&mPchFviVersionData);
+ }
+
+#ifdef EFI_S3_RESUME
+ if (!PchS3Support) {
+ DEBUG ((EFI_D_INFO, "Locating the S3 Support Protocol - PCH Init before Boot\n"));
+
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ Status = PchS3Support->ReadyToLock(PchS3Support);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ }
+#endif
+
+ DEBUG ((EFI_D_INFO, "PchInitBeforeBoot() End\n"));
+
+ return;
+}
+
+// [ EIP357393 ]+>>>
+EFI_STATUS
+EFIAPI
+PchSpiLockBeforeEndOfDxe (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Locking SPI configuration before End of Dxe
+
+Arguments:
+
+ Event A pointer to the Event that triggered the callback.
+ Context A pointer to private data registered with the callback function.
+
+Returns:
+
+ EFI_SUCCESS The function completed successfully
+
+ --*/
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ UINT32 RootComplexBar;
+ UINTN PciD25F0RegBase;
+ UINT32 GbEMemBar;
+ PCH_SERIES PchSeries = GetPchSeries();
+// UINT32 Data32And;
+// UINT32 Data32Or;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+// UINT8 Data8;
+ VOID *ProtocolPointer;
+
+ //
+ // Check whether this is real AMI ExtPciBusProtocol notification, or just a SignalEvent
+ //
+ Status = gBS->LocateProtocol (&gAmiExtPciBusProtocolGuid, NULL, &ProtocolPointer);
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Closed the event to avoid call twice when launch shell
+ //
+ gBS->CloseEvent (Event);
+
+
+ //
+ // Retrieve all instances of PCH Platform Policy protocol
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate handle buffer for PCH Policy protocol.\n"));
+ return Status;
+ }
+ //
+ // Find the matching PCH Policy protocol
+ //
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gDxePchPlatformPolicyProtocolGuid,
+ &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to find PCH Policy protocol.\n"));
+ return Status;
+ }
+
+ RootComplexBar = PCH_RCRB_BASE;
+
+ ///
+ /// SPI Flash Programming Guide Section 5.5.1 Flash Configuration Lockdown
+ /// It is strongly recommended that BIOS sets the Host and GbE Flash Configuration Lock-Down (FLOCKDN)
+ /// bits (located at SPIBAR + 04h and MBAR + 04h respectively) to 1 on production platforms
+ ///
+ if (PchSeries == PchH) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN + B_PCH_SPI_PRR3PRR4_LOCKDN));
+ } else if (PchSeries == PchLp) {
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_SPI_HSFS), (UINT16) (B_PCH_SPI_HSFS_FLOCKDN));
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_SPI_HSFS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_SPI_HSFS)
+ );
+ //
+ // Set the GbE Flash Configuration Lock-Down (FLOCKDN) bit (MBAR + 04h[15]) to 1
+ //
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_ENABLE) {
+ PciD25F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 25, 0, 0);
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MBARB) & B_PCH_LAN_MBARB_BA;
+ if (GbEMemBar) {
+ //
+ // Enable memory space decoding in command register
+ //
+ Data16And = 0xFFFF;
+ Data16Or = (UINT16) B_PCH_LAN_CMD_MSE;
+ MmioOr16 (PciD25F0RegBase + R_PCH_LAN_CMD, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_CMD),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Assert if the memory data of GbEMemBar is invalid.
+ ///
+ if (MmioRead32 (GbEMemBar) == 0xFFFFFFFF) {
+ ASSERT (FALSE);
+ } else {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_MBARB)
+ );
+ MmioOr16 (GbEMemBar + 0x04, BIT15);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (GbEMemBar + 0x04),
+ 1,
+ (VOID *) (UINTN) (GbEMemBar + 0x04)
+ );
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+// [ EIP357393 ]+<<<
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs
new file mode 100644
index 0000000..5e1ad9a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.dxs
@@ -0,0 +1,48 @@
+/** @file
+ Dispatch dependency expression file for the PchInit driver.
+
+@copyright
+ Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEFINITION (BootScriptSave)
+#include EFI_PROTOCOL_DEFINITION (PchPlatformPolicy)
+#include EFI_PROTOCOL_DEFINITION (PchS3Support)
+#include EFI_PROTOCOL_DEFINITION (SmmControl)
+#endif
+
+DEPENDENCY_START
+#ifdef EFI_S3_RESUME
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID AND
+ EFI_PCH_S3_SUPPORT_PROTOCOL_GUID AND
+#endif
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID AND
+ EFI_SMM_CONTROL_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.h
new file mode 100644
index 0000000..a99c375
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInit.h
@@ -0,0 +1,653 @@
+/** @file
+ Header file for PCH Initialization Driver.
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#ifndef _PCH_INITIALIZATION_DRIVER_H_
+#define _PCH_INITIALIZATION_DRIVER_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+#include "EfiScriptLib.h"
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include EFI_PROTOCOL_CONSUMER (BootScriptSave)
+#include EFI_PROTOCOL_CONSUMER (ExitPmAuth)
+#include EFI_PROTOCOL_CONSUMER (PchS3Support)
+#include EFI_PROTOCOL_PRODUCER (PchInfo)
+#include EFI_PROTOCOL_CONSUMER (DriverSupportedEfiVersion)
+#include EFI_GUID_DEFINITION (ChipsetInitHob)
+
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchPciExpressHelpersLib.h"
+#include "PchUsbCommon.h"
+#include "PchHsio.h"
+#include "Pci22.h"
+#include "IobpDefinitions.h"
+#include "RcFviDxeLib.h"
+#include "PchInitVar.h"
+#include "PchAslUpdateLib.h"
+#endif
+
+#define AZALIA_MAX_LOOP_TIME 10
+#define AZALIA_WAIT_PERIOD 100
+#define AZALIA_MAX_SID_NUMBER_PCH_H 4
+#define AZALIA_MAX_SID_NUMBER_PCH_LP 2
+#define AZALIA_MAX_SID_MASK_PCH_H ((1 << AZALIA_MAX_SID_NUMBER_PCH_H) - 1)
+#define AZALIA_MAX_SID_MASK_PCH_LP ((1 << AZALIA_MAX_SID_NUMBER_PCH_LP) - 1)
+//
+// CPUID and MSR definitions
+//
+#define CPUID_VERSION_INFO 0x1
+#define CPUID_FULL_FAMILY_MODEL 0x0FFF0FF0
+#define CPUID_FULL_STEPPING 0x0000000F
+#define CPUID_FULL_FAMILY_MODEL_HASWELL 0x000306C0
+#define CPUID_FULL_FAMILY_MODEL_HASWELL_ULT 0x00040650
+#define CPUID_FULL_FAMILY_MODEL_CRYSTALWELL 0x00040660
+#define MSR_TEMPERATURE_TARGET 0x000001A2
+
+typedef enum {
+ //
+ // Haswell Family Stepping
+ //
+ EnumHswA0 = 1,
+ EnumHswB0,
+ EnumHswC0,
+ EnumHswD0,
+ //
+ // Haswell ULT Family Stepping
+ //
+ EnumHswUltB0 = 0,
+ EnumHswUltC0,
+ //
+ // Crystalwell Family Stepping
+ //
+ EnumCrwB0 = 0,
+ EnumCrwC0,
+ EnumCrwD0,
+ EnumCpuSteppingMax = CPUID_FULL_STEPPING
+} CPU_STEPPING;
+
+#pragma pack(1)
+typedef union _MSR_REGISTER {
+ UINT64 Qword;
+
+ struct _DWORDS {
+ UINT32 Low;
+ UINT32 High;
+ } Dwords;
+
+ struct _BYTES {
+ UINT8 FirstByte;
+ UINT8 SecondByte;
+ UINT8 ThirdByte;
+ UINT8 FouthByte;
+ UINT8 FifthByte;
+ UINT8 SixthByte;
+ UINT8 SeventhByte;
+ UINT8 EighthByte;
+ } Bytes;
+
+} MSR_REGISTER;
+
+typedef struct {
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+} EFI_CPUID_REGISTER;
+#pragma pack()
+
+typedef struct {
+ EFI_PCH_INFO_PROTOCOL PchInfo;
+} PCH_INSTANCE_PRIVATE_DATA;
+
+#define IS_PCH_H_EHCI(DeviceNumber, FunctionNumber) \
+ ( \
+ (DeviceNumber == PCI_DEVICE_NUMBER_PCH_USB && FunctionNumber == PCI_FUNCTION_NUMBER_PCH_EHCI) || \
+ (DeviceNumber == PCI_DEVICE_NUMBER_PCH_USB_EXT && FunctionNumber == PCI_FUNCTION_NUMBER_PCH_EHCI2) \
+ )
+
+#define IS_PCH_LP_EHCI(DeviceNumber, FunctionNumber) \
+ ( \
+ (DeviceNumber == PCI_DEVICE_NUMBER_PCH_USB && FunctionNumber == PCI_FUNCTION_NUMBER_PCH_EHCI) \
+ )
+
+//
+// Data definitions
+//
+extern EFI_HANDLE mImageHandle;
+
+///
+/// SVID / SID init table entry
+///
+typedef struct {
+ UINT8 DeviceNumber;
+ UINT8 FunctionNumber;
+ UINT8 SvidRegOffset;
+} PCH_SVID_SID_INIT_ENTRY;
+
+#define PCH_FVI_STRING "Reference Code - PCH - Lynxpoint"
+#define PCH_FVI_SMBIOS_TYPE 0xDD
+#define PCH_FVI_SMBIOS_INSTANCE 0x04
+#define PCH_CRID_STATUS "PCH-CRID Status"
+#define PCH_CRID_ORIGINAL_VALUE "PCH-CRID Original Value"
+#define PCH_CRID_NEW_VALUE "PCH-CRID New Value"
+#define PCH_CRID_ENABLED "Enabled "
+#define PCH_CRID_DISABLED "Disabled"
+#define PCH_LPTLPBX_HSIO_STRING "LPTLp Bx Hsio Version"
+#define PCH_LPTHB0_HSIO_STRING "LPTH B0 Hsio Version"
+#define PCH_LPTHCX_HSIO_STRING "LPTH Cx Hsio Version"
+#define PCH_CRID_VERSION \
+ { \
+ 0xFF, 0xFF, 0xFF, 0xFFFF \
+ }
+#define RAID_FVI_STRING "OPROM - RST - RAID"
+#define RAID_RC_VERSION \
+ { \
+ 0xFF, 0xFF, 0xFF, 0xFFFF \
+ }
+
+enum {
+ RC_VER = 0,
+ CRID_STATUS,
+ CRID_ORIGINAL,
+ CRID_NEW,
+ RAID_VER,
+ HSIO_LPTLPAX_VER,
+ HSIO_LPTLPBX_VER,
+ HSIO_LPTHB0_VER,
+ HSIO_LPTHCX_VER
+} PCH_FVI_INDEX;
+
+extern FVI_ELEMENT_AND_FUNCTION mPchFviElementsData[];
+extern FVI_DATA_HUB_CALLBACK_CONTEXT mPchFviVersionData;
+extern UINTN mPchFviElements;
+
+//
+// Function Prototype
+//
+
+/**
+ Configures PCH IOBP and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+ProgramIobpWithScript (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ );
+
+/**
+ Configures 32-bit MMIO register and stores this configuration in S3 boot script
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+**/
+VOID
+MmioAndThenOr32WithScript (
+ IN UINTN Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ );
+
+/**
+ Detect and initialize the type of codec (AC'97 and HDA) present in the system.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] AzaliaEnable Returned with TRUE if Azalia High Definition Audio codec
+ is detected and initialized.
+
+ @retval EFI_SUCCESS Codec is detected and initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to initialize the codec.
+**/
+EFI_STATUS
+ConfigureAzalia (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT BOOLEAN *AzaliaEnable
+ );
+
+/**
+ Configure miscellaneous power management settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureMiscPm (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar,
+ UINT16 GpioBase
+ );
+
+/**
+ Configure additional power management settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureAdditionalPm (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Configure deep Sx programming
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ProgramDeepSx (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar
+ );
+
+/**
+ Perform miscellany PCH initialization
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureMiscItems (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ Initialize LAN device. Reference: PCH BIOS Spec Rev 0.5.0,
+ 10.2 Enabling / Disabling the Internal GbE Controller
+ ** NOTE:
+ - The platform reset mandated by GbE enabling / disabling is handled
+ in PchInit PEIM. Platform PEI code is responsible for calling PCH Init PPI
+ - (BUC register setting is also done in the PCH Init PPI)
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureLan (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Configures PCH USB controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg Function Disable Register
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureUsb (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ Configures PCH Sata Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg Function Disable Register
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSata (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg,
+ IN UINT16 GpioBase
+ );
+
+/**
+ Perform Clock Gating programming
+ Enables clock gating in various PCH interfaces and the registers must be restored during S3 resume.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] FuncDisableReg The Function Disable Register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT32 FuncDisableReg
+ );
+
+/**
+ Configure IoApic Controler
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureIoApic (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Configure PCH Display
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureDisplay (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Perform Root Port Initialization.
+
+ @param[in] RootPort The root port to be initialized (zero based)
+ @param[in] RootPortFunction The PCI function number of the root port
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol
+ @param[in] PmBase The PM I/O Base address of the PCH
+ @param[in] RootComplexBar RCBA of the PCH
+
+ @retval EFI_SUCCESS Device found. The root port must be enabled.
+ @retval EFI_NOT_FOUND No device is found on the root port. It may be disabled.
+ @exception EFI_UNSUPPORTED Unsupported operation.
+**/
+EFI_STATUS
+PchInitSingleRootPort (
+ IN UINT8 RootPort,
+ IN UINT8 RootPortFunction,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT16 PmBase,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Perform Initialization of the Downstream Root Ports.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol
+ @param[in] RootComplexBar RCBA of the PCH
+ @param[in] PmBase The PM I/O Base address of the PCH
+ @param[in, out] FuncDisableReg The function disable register. IN / OUT parameter.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_INVALID_PARAMETER The PCIe Root Port Number of D28:F0 is not found
+ or invalid
+**/
+EFI_STATUS
+PchInitRootPorts (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ This is the function to enable the clock gating for PCI Express ports.
+
+ @param[in] BusNumber The Bus Number of the PCH device
+ @param[in] PchPlatformPolicy PCH Platform Policy protocol
+ @param[in] RpEnableMask Bit Mask indicating the enabled root ports
+ @param[in] RpHiddenMask Bit Mask indicating the root ports used for other > x1 root ports
+ @param[in] RootComplexBar Root complex base address
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieEnableClockGating (
+ IN UINT8 BusNumber,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RpEnableMask,
+ IN UINT32 RpHiddenMask,
+ IN UINT32 RootComplexBar,
+ IN UINT32 NandPort
+ );
+
+/**
+ Set an Init Root Port Downstream devices S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SetInitRootPortDownstreamS3Item (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax
+ );
+
+/**
+ Set an PCH IOBP programming S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Out of resources
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_NOT_FOUND Protocol interface not found
+**/
+EFI_STATUS
+SetProgramIobpS3Item (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ );
+
+/**
+ Locking Thermal Reporting Settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ThermalLockDown (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT16 GpioBase
+ );
+
+/**
+ Configures PCH DMI according to policies specified in PCH Platform Policy protocol
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+EFIAPI
+ConfigureDmiPm (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Dump whole DXE_PCH_PLATFORM_POLICY_PROTOCOL and serial out.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval None
+**/
+VOID
+PchDumpPlatformProtocol (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+/**
+ Lock USB registers before boot
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+
+ @retval None
+**/
+VOID
+UsbInitBeforeBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+/**
+ Configures ports of the PCH USB3 (xHCI) controller
+ just before OS boot.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+VOID
+ConfigureXhciAtBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+#ifdef SERIAL_IO_FLAG
+/**
+ Puts Serial IO controllers in D3
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+**/
+VOID
+ConfigureSerialIoAtBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ );
+
+/**
+ Hide PCI config space of Serial IO Controllerss and do any
+ final initialization.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSerialIoBeforeBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+/**
+ Configures Serial IO Controllers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+EFI_STATUS
+ConfigureSerialIo (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+#endif // SERIAL_IO_FLAG
+
+#ifdef ADSP_FLAG
+/**
+ Initialize Audio DSP subsystem
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS Codec is detected and initialized
+ @retval EFI_UNSUPPORTED Audio DSP disabled
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources to initialize the codec
+**/
+EFI_STATUS
+ConfigureAudioDsp (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ Finalize Audio DSP initialization after PCI enumeration.
+ In particular configure ADSP in ACPI or PCI mode.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_UNSUPPORTED Audio DSP not found or not enabled
+**/
+EFI_STATUS
+ConfigureAudioDspBeforeBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ );
+
+#endif // ADSP_FLAG
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h
new file mode 100644
index 0000000..86a6805
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitCommon.h
@@ -0,0 +1,110 @@
+/** @file
+
+ Header file for PCH common Initialization Driver.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _PCH_INIT_COMMON_DRIVER_H_
+#define _PCH_INIT_COMMON_DRIVER_H_
+
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+#include "EfiScriptLib.h"
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+#include "PchUsbPrecondition.h"
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+#endif
+
+#define PCH_INIT_COMMON_SCRIPT_IO_WRITE(TableName, Width, Address, Count, Buffer) \
+ SCRIPT_IO_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_IO_READ_WRITE(TableName, Width, Address, Data, DataMask) \
+ SCRIPT_IO_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_MEM_WRITE(TableName, Width, Address, Count, Buffer) \
+ SCRIPT_MEM_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_MEM_READ_WRITE(TableName, Width, Address, Data, DataMask) \
+ SCRIPT_MEM_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_PCI_CFG_WRITE(TableName, Width, Address, Count, Buffer) \
+ SCRIPT_PCI_CFG_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_PCI_CFG_READ_WRITE(TableName, Width, Address, Data, DataMask) \
+ SCRIPT_PCI_CFG_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_STALL(TableName, Duration) SCRIPT_STALL (TableName, Duration)
+
+#define PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM(RootComplexBar, Address, AndMask, OrMask) \
+ SetProgramIobpS3Item(RootComplexBar, Address, AndMask, OrMask)
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+///
+/// Execute function when running in PEI
+/// It is always FALSE for DXE phase check
+///
+#define USB_RUN_IN_PEI FALSE
+
+///
+/// Execute function when running in DXE
+///
+#define USB_RUN_IN_DXE TRUE
+
+///
+/// USB precondition policy check
+///
+#define USB_PRECONDITION_POLICY_SUPPORT(UsbPolicy) \
+ ((UsbPolicy)->UsbPrecondition)
+
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+///
+/// USB3 port setting policy check
+///
+#define USB3PORT_SETTING_POLICY_SUPPORT(Revision) \
+ ((Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_5))
+
+/**
+ Set an PCH IOBP programming S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Out of resources
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_NOT_FOUND Protocol interface not found
+**/
+EFI_STATUS
+SetProgramIobpS3Item (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif
new file mode 100644
index 0000000..a8922a8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.cif
@@ -0,0 +1,28 @@
+<component>
+ name = "PchInitDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchInit\Dxe"
+ RefName = "PchInitDxe"
+[files]
+"PchInitDxe.sdl"
+"PchInitDxe.mak"
+"PchInit.h"
+"PchInit.c"
+"PchAzalia.c"
+"PchIoApic.c"
+"PchLan.c"
+"PchMisc.c"
+"PchPm.c"
+"PchSata.c"
+"PchUsb.c"
+"PchInit.dxs"
+"PchRootPorts.c"
+"PchInitCommon.h"
+"PchDebugDump.c"
+"PchFvi.c"
+"PchInitDxe.inf"
+"PchAudioDsp.c"
+"PchUsbPrecondition.c"
+"PchUsbPrecondition.h"
+"PchSerialIo.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf
new file mode 100644
index 0000000..62675c2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.inf
@@ -0,0 +1,134 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+#@copyright
+# Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchInitDxe
+FILE_GUID = DE23ACEE-CF55-4fb6-AA77-984AB53DE823
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchInit.h
+ PchInit.c
+ PchAzalia.c
+ PchIoApic.c
+ PchLan.c
+ PchMisc.c
+ PchPm.c
+ PchSata.c
+ PchUsb.c
+ PchRootPorts.c
+ PchDebugDump.c
+ ../Common/PchUsbCommon.c
+ ../Common/PchHsio.c
+ ../Common/PchInitVar.c
+ PchFvi.c
+ PchSerialIo.c
+ PchAudioDsp.c
+ PchUsbPrecondition.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Framework/Guid/Hob
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Guid/ChipsetInitHob
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchInfo
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Samplecode/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Samplecode/Library/AslUpdate/Dxe
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Guid/MeDataHob
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/include
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/Dxe
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Protocol/MePlatformPolicy
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Library
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_SA_ROOT)/Include
+ $(EFI_SOURCE)/Include
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeFirmwarePerformanceLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ EdkIIGlueDxeHobLib
+ PchPciExpressHelpersLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EfiGuidLib
+ EfiScriptLib
+ RcFviDxeLib
+ PchAslUpdateLib
+ MeLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchInit.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchInitEntryPoint
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ -D __EDKII_GLUE_DXE_HOB_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak
new file mode 100644
index 0000000..a1c641e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.mak
@@ -0,0 +1,150 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitDxe/PchInitDxe.mak 6 1/14/13 2:40a Scottyang $
+#
+# $Revision: 6 $
+#
+# $Date: 1/14/13 2:40a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitDxe/PchInitDxe.mak $
+#
+# 6 1/14/13 2:40a Scottyang
+# [TAG] EIP112059
+#
+# [Category] Improvement
+#
+# [Description] Update PCH RC 0.9.0.
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*
+#
+# 5 11/20/12 8:34a Scottyang
+# [TAG] EIP107014
+# [Category] Improvement
+# [Description] Update RC 0.8.0
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 4 8/13/12 9:14a Victortu
+#
+# 3 7/02/12 9:56a Victortu
+#
+# 2 2/24/12 2:12a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:51a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchInitDxe Driver
+#---------------------------------------------------------------------------
+EDK : PchInitDxe
+PchInitDxe : $(BUILD_DIR)\PchInitDxe.mak PchInitDxeBin
+
+
+$(BUILD_DIR)\PchInitDxe.mak : $(PchInitDxe_DIR)\$(@B).cif $(PchInitDxe_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchInitDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MY_DEFINES=\
+!IF "$(PCH_DEBUG_INFO)"=="1"
+ /D"PCH_DEBUG_INFO=1"\
+!ELSE
+ /D"PCH_DEBUG_INFO=0"\
+!ENDIF
+
+PchInitDxe_INCLUDES=\
+ /I$(PchUsbCommonLib_DIR)\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(INTEL_PCH_DIR)\Protocol\PchInfo\
+ /I$(INTEL_PCH_DIR)\SampleCode\Include\
+ /I$(INTEL_PCH_DIR)\SampleCode\Library\AslUpdate\Dxe\
+ /I$(INTEL_PCH_DIR)\Guid\SurvivabilityHob\
+ $(ME_INCLUDES)
+
+PchInitDxe_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PchInitEntryPoint"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__\
+ /D __EDKII_GLUE_DXE_HOB_LIB__
+
+PchInitDxe_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPciExpressHelpersDxeLib_LIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EFIGUIDLIB)\
+ $(EFISCRIPTLIB)\
+ $(PchUsbCommonDxeLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(RcFviDxeLib_LIB)\
+ $(PchAslUpdateLib_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+!IF "$(iME_SUPPORT)"=="1"
+ $(PchGuidLib_LIB)\
+ $(MeLibDxe_LIB)
+!ENDIF
+
+PchInitDxeBin: $(PchInitDxe_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchInitDxe.mak all \
+ "MY_INCLUDES=$(PchInitDxe_INCLUDES)"\
+ "MY_DEFINES=$(PchInitDxe_DEFINES)"\
+ GUID=DE23ACEE-CF55-4fb6-AA77-984AB53DE823\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchInitDxe_DIR)\PchInit.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+!IF "$(SOFTSDV_PARTIAL_COMPRESS)"=="1"
+ COMPRESS=0
+!ELSE
+ COMPRESS=1
+!ENDIF
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl
new file mode 100644
index 0000000..e0b5eb2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchInitDxe.sdl
@@ -0,0 +1,66 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitDxe/PchInitDxe.sdl 1 2/08/12 8:51a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:51a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitDxe/PchInitDxe.sdl $
+#
+# 1 2/08/12 8:51a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchInitDxe_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchInitDxe support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchInitDxe_DIR"
+End
+
+MODULE
+ File = "PchInitDxe.mak"
+ Help = "Includes PchInitDxe.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchInitDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c
new file mode 100644
index 0000000..ba0b94f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchIoApic.c
@@ -0,0 +1,134 @@
+/** @file
+ Initializes PCH IO APIC Device.
+
+@copyright
+ Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchInit.h"
+
+/**
+ Configure IoApic Controler
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureIoApic (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 RegData8;
+ UINT16 RegData16;
+ UINT32 RegData32;
+ UINTN PciD31F0RegBase;
+ UINT32 IoApicAddress;
+ PCH_IO_APIC_CONFIG *IoApicConfig;
+ PCH_LPC_HPET_CONFIG *HpetConfig;
+ UINT8 Index;
+
+ DEBUG ((EFI_D_INFO, "ConfigureIoApic() Start\n"));
+
+ ///
+ /// Get LPC base address
+ ///
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ IoApicConfig = PchPlatformPolicy->IoApicConfig;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 6.6.2.1
+ /// 1. Enable the IOAPIC by setting the APIC Enable bit, RCBA + offset 31FFh, Bit[0] if the
+ /// system needs to use the IOxAPIC. The APIC Enable bits needs read back after the bit is written.
+ /// Done in PchInitPeim.c PchIoApicInit()
+ ///
+ /// 2. Build the MP table and/or ACPI APIC table for the OS
+ /// This will be done in ACPI code.
+ ///
+ /// 3. Maximum Redirection Entries (MRE) in APIC Version Register (VER), offset 01h,
+ /// [23:16] has to be written once for Microsoft Windows OS.
+ /// The address bits 19:12 of IOAPIC INDEX and DATA are programmable
+ /// through OIC register at RCBA + 31FEh[7:0].
+ ///
+ IoApicAddress = (UINT32) MmioRead8 (RootComplexBar + R_PCH_RCRB_OIC);
+ IoApicAddress = IoApicAddress << N_PCH_IO_APIC_ASEL;
+ RegData8 = 0x01;
+ MmioWrite8 ((UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress), RegData8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress),
+ 1,
+ &RegData8
+ );
+ RegData32 = 0x170020;
+ if (GetPchSeries() == PchLp) {
+ if (IoApicConfig->IoApicEntry24_39 == PCH_DEVICE_ENABLE) {
+ RegData32 = 0x270020;
+ }
+ }
+ MmioWrite32 ((R_PCH_IO_APIC_DATA | IoApicAddress), RegData32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (R_PCH_IO_APIC_DATA | IoApicAddress),
+ 1,
+ &RegData32
+ );
+
+ ///
+ /// Program this field to provide a unique bus:device:function number for the internal IOxAPIC
+ ///
+ if (IoApicConfig->BdfValid) {
+ RegData16 = ((UINT16) (IoApicConfig->BusNumber) << 8) & B_PCH_LPC_IOXAPIC_BUS;
+ RegData16 |= ((UINT16) (IoApicConfig->DeviceNumber) << 3) & B_PCH_LPC_IOXAPIC_DEVICE;
+ RegData16 |= (UINT16) (IoApicConfig->FunctionNumber) & B_PCH_LPC_IOXAPIC_FUNC;
+ MmioWrite16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_IOXAPIC), RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_IOXAPIC),
+ 1,
+ &RegData16
+ );
+ }
+ ///
+ /// Program this field accordingly if unique bus:device:function number is required for the
+ /// corresponding HPET
+ ///
+ HpetConfig = PchPlatformPolicy->HpetConfig;
+ if (HpetConfig->BdfValid) {
+ for (Index = 0; Index < PCH_HPET_BDF_MAX; Index++) {
+ RegData16 = ((UINT16) (HpetConfig->Hpet[Index].BusNumber) << 8) & B_PCH_LPC_HPET0_BUS;
+ RegData16 |= ((UINT16) (HpetConfig->Hpet[Index].DeviceNumber) << 3) & B_PCH_LPC_HPET0_DEVICE;
+ RegData16 |= (UINT16) (HpetConfig->Hpet[Index].FunctionNumber) & B_PCH_LPC_HPET0_FUNC;
+ MmioWrite16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_HPET0 + Index * 2), RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_HPET0 + Index * 2),
+ 1,
+ &RegData16
+ );
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureIoApic() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchLan.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchLan.c
new file mode 100644
index 0000000..ab0c427
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchLan.c
@@ -0,0 +1,152 @@
+/** @file
+ Initializes PCH LAN Device
+
+@copyright
+ Copyright (c) 1999 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchInit.h"
+
+/**
+ Enable GbE Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EnableGbEController (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar
+ )
+{
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 10.2.1
+ /// Done in PchInitPeimm.c PchGbeMandatedReset()
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable GbE Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+DisableGbEController (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar
+ )
+{
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 10.2.2
+ /// Done in PchInitPeimm.c PchGbeMandatedReset()
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize LAN device. Reference: PCH BIOS Spec Rev 0.5.0,
+ 10.2 Enabling / Disabling the Internal GbE Controller
+ ** NOTE:
+ - The platform reset mandated by GbE enabling / disabling is handled
+ in PchInit PEIM. Platform PEI code is responsible for calling PCH Init PPI
+ - BUC register setting is also done in the PCH Init PPI
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureLan (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT32 RegData32;
+ UINTN PciD25F0RegBase;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ConfigureLan() Start\n"));
+ PchSeries = GetPchSeries();
+ ///
+ /// If SPI is used and in Descriptor mode, the PCIE Port X need to be disabled to use GbE
+ /// if not, the GbE should be disabled
+ ///
+ if (PchIsSpiDescriptorMode (RootComplexBar)) {
+ DEBUG ((EFI_D_INFO, "LAN can be enabled or disabled as SPI is in Descriptor Mode.\n"));
+
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_DISABLE) {
+ ///
+ /// Disable LAN
+ ///
+ DisableGbEController (PchPlatformPolicy, RootComplexBar);
+ } else {
+ ///
+ /// Enable LAN
+ ///
+ EnableGbEController (PchPlatformPolicy, RootComplexBar);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.6 Section 10.7.1 LTR Programming
+ /// The maximum snoop/non-snoop platform latency values to 00000846h
+ /// in the GbE controller's PCI LTR capability register at D25:F0:Reg 0A8h
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptGbe == PCH_DEVICE_ENABLE) {
+ PciD25F0RegBase = MmPciAddress (
+ 0,
+ PCI_BUS_NUMBER_PCH_LAN,
+ PCI_DEVICE_NUMBER_PCH_LAN,
+ PCI_FUNCTION_NUMBER_PCH_LAN,
+ 0
+ );
+ RegData32 = 0x00000000;
+ if (PchSeries == PchH) {
+ RegData32 = 0x00000846;
+ }
+ if (PchSeries == PchLp) {
+ RegData32 = 0x00001003;
+ }
+ MmioWrite32 (PciD25F0RegBase + R_PCH_LAN_LTR_CAP, RegData32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD25F0RegBase + R_PCH_LAN_LTR_CAP),
+ 1,
+ (VOID *) (UINTN) (PciD25F0RegBase + R_PCH_LAN_LTR_CAP)
+ );
+ }
+ }
+ } else {
+ ///
+ /// Non Descriptor mode: Disable LAN
+ ///
+ DEBUG ((EFI_D_ERROR, "LAN is disabled as SPI not in Descriptor Mode.\n"));
+ ///
+ /// Disable LAN
+ ///
+ DisableGbEController (PchPlatformPolicy, RootComplexBar);
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureLan() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchMisc.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchMisc.c
new file mode 100644
index 0000000..ec38433
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchMisc.c
@@ -0,0 +1,395 @@
+/** @file
+ Miscellaneous PCH initialization tasks
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+/**
+ Perform miscellany PCH initialization
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg The value of Function disable register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureMiscItems (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINTN PciD31F0RegBase;
+ UINT8 RegData8;
+ UINT16 RegData16;
+ UINT16 LpcDeviceId;
+ UINTN RPBase;
+ UINT16 RpcConfig;
+
+ DEBUG ((EFI_D_INFO, "ConfigureMiscItems() Start\n"));
+
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ RegData8 = 0;
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// Get PCIE Root Port Configuration
+ ///
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ 0
+ );
+ RpcConfig = MmioRead16 (RPBase + R_PCH_PCIE_STRPFUSECFG);
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, 8.13 IOSF Port Configuration and Grant Count Programming
+ /// The following table shows the setting of IOSF fabric register (RCBA 0x103C [15:0]) based
+ /// on PCIe port configuration. BIOS should program the register based on the table below.
+ /// For Root Port 1 - 4:
+ /// (Program RCBA + 103Ch[7:3] according to B0:D28:F0 + FCh[15:14])
+ /// B0:D28:F0+FCh[15:14] RCBA+103Ch[1:0] RCBA+103Ch[3:2] RCBA+103Ch[5:4] RCBA+103Ch[7:6]
+ /// 00b 00b 00b 00b 00b
+ /// 01b 10b 00b 00b 00b
+ /// 10b 10b 00b 10b 00b
+ /// 11b 10b 00b 00b 00b
+ ///
+ switch (RpcConfig & B_PCH_PCIE_STRPFUSECFG_RPC) {
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1:
+ RegData16 = 0x02;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_2:
+ RegData16 = 0x22;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_4:
+ RegData16 = 0x02;
+ break;
+
+ default:
+ RegData16 = 0x0;
+ break;
+ }
+
+ if (GetPchSeries() == PchH) {
+ ///
+ /// Get PCIE Root Port Configuration
+ ///
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5,
+ 0
+ );
+ RpcConfig = MmioRead16 (RPBase + R_PCH_PCIE_STRPFUSECFG);
+ ///
+ /// For Root Port 5 - 8:
+ /// (Program RCBA + 103Ch[7:3] according to B0:D28:F4 + FCh[15:14])
+ /// B0:D28:F4+FCh[15:14] RCBA+103Ch[9:8] RCBA+103Ch[11:10] RCBA+103Ch[13:12] RCBA+103Ch[15:14]
+ /// 00b 00b 00b 00b 00b
+ /// 01b 10b 00b 00b 00b
+ /// 10b 10b 00b 10b 00b
+ /// 11b 10b 00b 00b 00b
+ ///
+ switch (RpcConfig & B_PCH_PCIE_STRPFUSECFG_RPC) {
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1:
+ RegData16 |= 0x02 << 8;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_2:
+ RegData16 |= 0x22 << 8;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_4:
+ RegData16 |= 0x02 << 8;
+ break;
+
+ default:
+ RegData16 |= 0x0 << 8;
+ break;
+ }
+ }
+
+ MmioWrite16 (RootComplexBar + 0x103C, RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + 0x103C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x103C)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 6.2 Serial IRQs
+ /// The only System BIOS requirement to use IRQs as a serial IRQ is to enable the function in D31:F0:Reg 64h[7] and
+ /// select continuous or quiet mode, D31:F0:Reg 64h[6].
+ /// PCH requires that the System BIOS first set the SERIRQ logic to continuous mode operation for at least one frame
+ /// before switching it into quiet mode operation. This operation should be performed during the normal boot sequence
+ /// as well as a resume from STR (S3).
+ ///
+ RegData8 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT) &
+ (UINT8) ~(B_PCH_LPC_SERIRQ_CNT_SIRQEN | B_PCH_LPC_SERIRQ_CNT_SFPW);
+
+ if (PchPlatformPolicy->SerialIrqConfig->SirqEnable == TRUE) {
+ switch (PchPlatformPolicy->SerialIrqConfig->StartFramePulse) {
+ case PchSfpw8Clk:
+ RegData8 |= V_PCH_LPC_SERIRQ_CNT_SFPW_8CLK;
+ break;
+
+ case PchSfpw6Clk:
+ RegData8 |= V_PCH_LPC_SERIRQ_CNT_SFPW_6CLK;
+ break;
+
+ case PchSfpw4Clk:
+ default:
+ RegData8 |= V_PCH_LPC_SERIRQ_CNT_SFPW_4CLK;
+ break;
+ }
+ ///
+ /// Set the SERIRQ logic to continuous mode
+ ///
+ RegData8 |= (UINT8) (B_PCH_LPC_SERIRQ_CNT_SIRQEN | B_PCH_LPC_SERIRQ_CNT_SIRQMD);
+ }
+
+ MmioWrite8 (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT, RegData8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.8.1 RTC Resets
+ /// The PCH will set the RTC_PWR_STS bit (D31:F0:Reg A4h[2]) when the RTCRST# pin goes low.
+ /// The System BIOS shouldn't rely on the RTC RAM contents when the RTC_PWR_STS bit is set.
+ /// BIOS should clear this bit by writing a 0 to this bit position.
+ /// This bit isn't cleared by any reset function.
+ ///
+ MmioAnd8 ((UINTN) (PciD31F0RegBase + 0xA4), (UINT8) (~(BIT2)));
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 5.11 Intel PCH Boot Checklist
+ /// Step 8.1
+ /// Always set RCBA + Offset 3418h[0] = 1b
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_FUNCTION_0;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.1 Handling Status Registers
+ /// System BIOS must set 1b to clear the following registers during power-on
+ /// and resuming from Sx sleep state.
+ /// - RCBA + Offset 3310h[0] = 1b
+ /// - RCBA + Offset 3310h[4] = 1b, needs to be done as early as possible during PEI
+ /// Done in InstallPchInitPpi ()
+ /// - RCBA + Offset 3310h[5] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PRSTS),
+ (UINT32) (B_PCH_RCRB_PRSTS_ME_WAKE_STS | B_PCH_RCRB_PRSTS_WOL_OVR_WK_STS)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PRSTS),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_PRSTS)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 4.7
+ /// Enabling SLP_S3# and SLP_S4# Stretch
+ /// B0:D31:F0 Reg A4h[12:10] = 110b
+ /// B0:D31:F0 Reg A4h[5:3] = 001b
+ ///
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3) &
+ (UINT16) (~(B_PCH_LPC_GEN_PMCON_SLP_S3_MAW |
+ B_PCH_LPC_GEN_PMCON_SLP_S4_MAW));
+
+ switch (PchPlatformPolicy->MiscPmConfig->PchSlpS3MinAssert) {
+ case PchSlpS360us:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_60US;
+ break;
+
+ case PchSlpS31ms:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_1MS;
+ break;
+
+ case PchSlpS350ms:
+ default:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_50MS;
+ break;
+
+ case PchSlpS32s:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_2S;
+ break;
+ }
+
+ switch (PchPlatformPolicy->MiscPmConfig->PchSlpS4MinAssert) {
+ case PchSlpS4PchTime:
+ RegData16 &= (UINT16) (~B_PCH_LPC_GEN_PMCON_SLP_S4_ASE);
+ break;
+
+ case PchSlpS41s:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_1S | B_PCH_LPC_GEN_PMCON_SLP_S4_ASE;
+ break;
+
+ case PchSlpS42s:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_2S | B_PCH_LPC_GEN_PMCON_SLP_S4_ASE;
+ break;
+
+ case PchSlpS43s:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_3S | B_PCH_LPC_GEN_PMCON_SLP_S4_ASE;
+ break;
+
+ case PchSlpS44s:
+ default:
+ RegData16 |= V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_4S | B_PCH_LPC_GEN_PMCON_SLP_S4_ASE;
+ break;
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->SlpStrchSusUp == PCH_DEVICE_DISABLE) {
+ RegData16 |= B_PCH_LPC_GEN_PMCON_DISABLE_SX_STRETCH;
+ } else {
+ RegData16 &= ~B_PCH_LPC_GEN_PMCON_DISABLE_SX_STRETCH;
+ }
+
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3, RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 6.2 Serial IRQs
+ /// The only System BIOS requirement to use IRQs as a serial IRQ is to enable the function
+ /// in D31:F0:Reg 64h[7] and select continuous or quiet mode, D31:F0:Reg 64h[6].
+ ///
+ if ((PchPlatformPolicy->SerialIrqConfig->SirqEnable == TRUE) &&
+ (PchPlatformPolicy->SerialIrqConfig->SirqMode == PchQuietMode)) {
+ MmioAnd8 (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT, (UINT8)~B_PCH_LPC_SERIRQ_CNT_SIRQMD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_SERIRQ_CNT)
+ );
+ }
+
+ ///
+ /// For LPT-LP, if Direct Connect Interface (DCI) is enabled, set RCBA + 3F02h[0] = 1,
+ /// else, set RCBA + 3F02h[0] = 0.
+ /// When enabling DCI (through the enable bit), it's able to access JTAG and Run Control features
+ /// in a closed chassis situation, by using the USB3 port on a Shark Bay ULT platform.
+ ///
+ if ((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_6) &&
+ (GetPchSeries() == PchLp)) {
+ RegData16 = MmioRead16 (RootComplexBar + 0x3F02) & (UINT16)~BIT0;
+ if (PchPlatformPolicy->MiscConfig->DciEn) {
+ RegData16 |= BIT0;
+ }
+ MmioWrite16 (RootComplexBar + 0x3F02, RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + 0x3F02),
+ 1,
+ &RegData16
+ );
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureMiscItems() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Configure PCH Display
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureDisplay (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT32 Data32And;
+ UINT32 Data32Or;
+
+ DEBUG ((EFI_D_INFO, "ConfigureDisplay() Start\n"));
+
+ if (PchPlatformPolicy->DeviceEnabling->Display == PCH_DEVICE_DISABLE) {
+ ///
+ /// Disable PCH Display Port
+ /// Step 1
+ /// Set RCBA + 3424h = 0h
+ ///
+ MmioWrite16 ((UINTN) (RootComplexBar + R_PCH_RCRB_DISPBDF), (UINT16) 0x0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DISPBDF),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_DISPBDF)
+ );
+ ///
+ /// Step 2
+ /// Set RCBA + 3428h[0] = 0b
+ ///
+ Data32Or = 0;
+ Data32And = (UINT32) ~(B_PCH_RCRB_FD2_DBDFEN);
+ MmioAnd32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FD2), Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FD2),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ Data32Or = 0;
+ Data32And = (UINT32) (~BIT0);
+ MmioAnd32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FD2), Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FD2),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureDisplay() End\n"));
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchPm.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchPm.c
new file mode 100644
index 0000000..b2f53d7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchPm.c
@@ -0,0 +1,3389 @@
+/** @file
+ Initializes PCH power management features.
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+/**
+ Set an PCH IOBP programming S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] AndMask Mask to AND with the register
+ @param[in] OrMask Mask to OR with the register
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_OUT_OF_RESOURCES Out of resources
+ @retval EFI_INVALID_PARAMETER Invalid parameter
+ @retval EFI_NOT_FOUND Protocol interface not found
+**/
+EFI_STATUS
+SetProgramIobpS3Item (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ EFI_STATUS Status;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+ STATIC EFI_PCH_S3_PARAMETER_PROG_IOBP S3ParameterProgramIobp;
+ STATIC EFI_PCH_S3_DISPATCH_ITEM S3DispatchItem = {
+ PchS3ItemTypeProgramIobp,
+ &S3ParameterProgramIobp
+ };
+ EFI_PHYSICAL_ADDRESS S3DispatchEntryPoint;
+
+ if (!PchS3Support) {
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ S3ParameterProgramIobp.RootComplexBar = RootComplexBar;
+ S3ParameterProgramIobp.Address = Address;
+ S3ParameterProgramIobp.AndMask = AndMask;
+ S3ParameterProgramIobp.OrMask = OrMask;
+ Status = PchS3Support->SetDispatchItem (
+ PchS3Support,
+ &S3DispatchItem,
+ &S3DispatchEntryPoint
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Save the script dispatch item in the Boot Script
+ ///
+ SCRIPT_DISPATCH (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, S3DispatchEntryPoint);
+#else
+ Status = EFI_SUCCESS;
+#endif
+ return Status;
+}
+
+/**
+ Locking Thermal Reporting Settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ThermalLockDown (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT16 GpioBase
+ )
+{
+ UINTN PciD31F6RegBase;
+ UINTN PciD31F2RegBase;
+ UINT32 ThermalBaseB;
+ UINT32 ThermalBase;
+ EFI_PHYSICAL_ADDRESS MemBaseAddress;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT8 RegData8;
+ UINT16 RegData16;
+ UINT32 RegData32;
+ UINT32 RootComplexBar;
+ UINT32 Data32And;
+ UINT32 Data32Or = 0;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINT32 PchTTLevels = 0;
+ BOOLEAN PchHotEnable;
+ PCH_SERIES PchSeries;
+ EFI_CPUID_REGISTER Cpuid;
+ MSR_REGISTER TempMsr;
+ UINT32 temperature;
+ UINT8 MaxSataPortNum;
+
+ DEBUG ((EFI_D_INFO, "ThermalLockDown() Start\n"));
+
+ PchSeries = GetPchSeries();
+ ///
+ /// Check if TBARB is already initialized by platform code
+ ///
+ PciD31F6RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_THERMAL,
+ PCI_FUNCTION_NUMBER_PCH_THERMAL,
+ 0
+ );
+ PciD31F2RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_SATA,
+ PCI_FUNCTION_NUMBER_PCH_SATA,
+ 0
+ );
+ RootComplexBar = PCH_RCRB_BASE;
+ ThermalBaseB = MmioRead32 (PciD31F6RegBase + R_PCH_THERMAL_TBARB);
+ MemBaseAddress = 0x0ffffffff;
+
+ if (ThermalBaseB & B_PCH_THERMAL_SPTYPEN) {
+ ///
+ /// Check if TBARB is already initialized and if so use it.
+ ///
+ ThermalBaseB &= B_PCH_THERMAL_TBARB_MASK;
+ } else {
+#ifndef AMI_OVERRIDE_FOR_PCH
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_THREMAL_TBARB_ALIGNMENT,
+ V_PCH_THERMAL_TBARB_SIZE,
+ &MemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+#else
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_THREMAL_TBARB_ALIGNMENT,
+ V_PCH_THERMAL_TBARB_SIZE,
+ &MemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+#endif
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ThermalBaseB = (UINT32) MemBaseAddress;
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBARB, ThermalBaseB);
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBARBH, 0);
+ MmioOr32 (PciD31F6RegBase + R_PCH_THERMAL_TBARB, (UINT32) B_PCH_THERMAL_SPTYPEN);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARB),
+ 1,
+ (VOID *) (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARB)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARBH),
+ 1,
+ (VOID *) (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARBH)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, 17.3.1 Initializing Lynx Point Thermal Sensors
+ /// Step 1
+ /// TSC must then be written to 0x81 to enable the power down and lock the register.
+ ///
+ RegData8 = MmioRead8 (ThermalBaseB + R_PCH_TBARB_TSC);
+ ///
+ /// Enable Catastrophic Power Down
+ ///
+ RegData8 |= (UINT8) B_PCH_TBARB_TSC_CPDE;
+ ///
+ /// Step 8.1
+ /// It is recommended that TSC [7] set to 1 to lock the CAT Trip behavior.
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TscLock == PCH_DEVICE_ENABLE) {
+ RegData8 |= (UINT8) B_PCH_TBARB_TSC_PLD;
+ }
+
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSC, RegData8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSC),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSC)
+ );
+ ///
+ /// Step 8.2
+ /// TSMIC [7] locks SMI reporting of thermal events
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TsmicLock == PCH_DEVICE_ENABLE) {
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSMIC, 0x80);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSMIC),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSMIC)
+ );
+ }
+
+ ///
+ /// Step 5
+ /// If the PCH_Hot pin reporting is supported, then write the temperature value and set the enable in PHL.
+ ///
+ PchHotEnable = FALSE;
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ ///
+ /// Note: For PCHHOT# support, we need to make sure if GPIO74 is set to native mode and PCHSTRP9[22] is
+ /// set to 1.
+ /// Check if GPIO74 is set to native mode.
+ ///
+ RegData8 = (UINT8)((IoRead32 ((UINTN) (GpioBase + R_PCH_GPIO_USE_SEL3)) & BIT10) >> 10);
+ }
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// Note: For PCHHOT# support, we need to make sure if GPIO73 is set to native mode and PCHSTRP9[22] is
+ /// set to 1.
+ /// Check if GPIO73 is set to native mode.
+ ///
+ RegData8 = (UINT8)(IoRead32 ((UINTN) (GpioBase + R_PCH_GP_73_CONFIG0)) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ }
+#endif // ULT_FLAG
+
+ if(RegData8 == 0x00) {
+ ///
+ /// Check if PCHSTRP9[22] is set to 1 (PCHHOT# is the native functionality of GPIO74)
+ ///
+ if ((MmioRead16 (RootComplexBar + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
+ MmioAnd32 ((RootComplexBar + R_PCH_SPI_FDOC), (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)));
+ MmioOr32 ((RootComplexBar + R_PCH_SPI_FDOC), (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9));
+ if (MmioRead32 (RootComplexBar + R_PCH_SPI_FDOD) & B_PCH_SPI_STRP9_HOT_SML1_SEL) {
+ PchHotEnable = TRUE;
+ }
+ }
+ }
+
+ ///
+ /// The value in PHL register is valid only if it is between 00h and 1FFh.
+ ///
+ if ((PchHotEnable == TRUE) && (PchPlatformPolicy->ThermalConfig->PchHotLevel < 0x0200)) {
+ ///
+ /// Program PHL register according to PchHotLevel setting.
+ ///
+ RegData16 = (PchPlatformPolicy->ThermalConfig->PchHotLevel | B_PCH_TBARB_PHLE);
+ MmioWrite16 (ThermalBaseB + R_PCH_TBARB_PHL, RegData16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_PHL),
+ 1,
+ &RegData16
+ );
+ }
+ ///
+ /// Step 8.3
+ /// PHLC [0] locks the PHL and PHLC registers for PCH_Hot#
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.PhlcLock == PCH_DEVICE_ENABLE) {
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_PHLC, 0x01);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_PHLC),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_PHLC)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 17.5 Thermal Throttling
+ /// Step 1
+ /// Additional programming to initialize Thermal Throttle device
+ /// For LPT-H,
+ /// a. Program ThermalBAR + 0xC0 to 8000390Bh
+ /// b. Program ThermalBAR + 0xC4 to C11F0201h
+ /// c. Program ThermalBAR + 0xC8 to 05800000h
+ /// d. Program ThermalBAR + 0xCC to 0000C000h
+ /// e. Program ThermalBAR + 0xD0 to 00000320h
+ /// f. Program ThermalBAR + 0xE0 to 80001E4Fh
+ /// g. Program ThermalBAR + 0xF0 to 00000003h
+ /// For LPT-LP,
+ /// a. Program ThermalBar + 0xC0 to 8000390Bh
+ /// b. Program ThermalBar + 0xC4 to C11F0401h
+ /// c. Program ThermalBAR + 0xC8 to 05800000h
+ /// d. Program ThermalBar + 0xCC to 0000C000h
+ /// e. Program ThermalBar + 0xD0 to 00000320h
+ /// f. Program ThermalBar + 0xE0 to 80001EDCh
+ /// g. Program ThermalBar + 0xF0 to 00000003h
+ ///
+
+ if (PchSeries == PchH) {
+ MmioWrite32 (ThermalBaseB + 0xC4, 0xC11F0201);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xC4),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xC4)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xE0, 0x80001E4F);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xE0),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xE0)
+ );
+ }
+
+ if (PchSeries == PchLp) {
+ MmioWrite32 (ThermalBaseB + 0xC4, 0xC11F0401);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xC4),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xC4)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xE0, 0x80001EDC);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xE0),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xE0)
+ );
+ }
+
+ MmioWrite32 (ThermalBaseB + 0xC0, 0x8000390B);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xC0),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xC0)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xC8, 0x05800000);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xC8),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xC8)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xCC, 0x0000C000);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xCC),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xCC)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xD0, 0x00000320);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xD0),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xD0)
+ );
+
+ MmioWrite32 (ThermalBaseB + 0xF0, 0x00000003);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + 0xF0),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xF0)
+ );
+ ///
+ /// HSW BWG 15.8 : Processor PCH-LP cross throttling
+ ///
+ if (PchSeries == PchLp){
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ if (((Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL) == CPUID_FULL_FAMILY_MODEL_HASWELL_ULT) &&
+ ((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.PchCrossThrottling == PCH_DEVICE_ENABLE) ||
+ (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting == PCH_DEVICE_ENABLE))) {
+ //
+ // Read MSR 0x1A2 TEMPERATURE_TARGET
+ //
+ TempMsr.Qword = AsmReadMsr64 (MSR_TEMPERATURE_TARGET);
+ ///
+ /// Tcc activation offset in temperature target MSR changes from 4 bits [27:24] to 6 bits [29:24] on ULT C step onwards
+ /// since Tcc will never be more than 205C, thus the calculation for PHL will never overflow
+ ///
+ if ((Cpuid.RegEax & CPUID_FULL_STEPPING) >= EnumHswUltC0) {
+ temperature = (TempMsr.Bytes.ThirdByte - (TempMsr.Bytes.FouthByte & 0x3F));
+ } else {
+ temperature = (TempMsr.Bytes.ThirdByte - (TempMsr.Bytes.FouthByte & 0xF));
+ }
+
+ if (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting == PCH_DEVICE_ENABLE) {
+ ///
+ /// PCH T0/T1/T2 Level (MMIO TBARB+40h) :
+ /// T0L = (((MSR TEMPERATURE_TARGET[23:16] - TEMPERATURE_TARGET) + 50) * 2)
+ /// T1L = T0L + 5C
+ /// T2L = T1L + 5C
+ ///
+ PchTTLevels = (UINT32)((( temperature + 10 + 50) * 2) << 20) |
+ (UINT32)(((temperature + 5 + 50) * 2) << 10) |
+ (UINT32)((temperature + 50) * 2);
+ Data32Or = BIT31 | BIT29;
+ } else {
+ PchTTLevels = (UINT32) (((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T2Level + 10 + 50) * 2) << 20) |
+ (UINT32) (((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T1Level + 5 + 50) * 2) << 10) |
+ (UINT32) ((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T0Level + 50) * 2);
+ Data32Or = (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTLock << 31) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTState13Enable << 30) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTEnable << 29);
+ }
+ }
+ } else if (PchSeries == PchH) {
+ if (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting == PCH_DEVICE_ENABLE) {
+ ///
+ /// Set TBARB + 40h = 0B485093Ch
+ /// Program TBARB + 40h[31:28] in separate write
+ ///
+ PchTTLevels = 0xB485093C;
+ Data32Or = BIT31 | BIT29;
+ }else {
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 17.3.1 Initializing Lynx Point Thermal Sensors
+ /// Trip Point Temperature = (Trip Point Register [8:0]) / 2 - 50 centigrade degree
+ /// If Trip Point Temperature <= T0Level, the system will be in T0 state.
+ /// If T1Level >= Trip Point Temperature > T0Level, the system will be in T1 state.
+ /// If T2Level >= Trip Point Temperature > T1Level, the system will be in T2 state.
+ /// If Trip Point Temperature > T2Level, the system will be in T3 state.
+ ///
+ PchTTLevels = (UINT32) (((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T2Level + 50) * 2) << 20) |
+ (UINT32) (((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T1Level + 50) * 2) << 10) |
+ (UINT32) ((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.T0Level + 50) * 2);
+ Data32Or = (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTLock << 31) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTState13Enable << 30) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.TTEnable << 29);
+ }
+ }
+
+ ///
+ /// Program TBARB + 40h[27:0]
+ ///
+ MmioWrite32 (ThermalBaseB + R_PCH_TBARB_TL, PchTTLevels);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TL),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TL)
+ );
+ ///
+ /// Program TBARB + 40h[31:28]
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, 17.3.1 Initializing Lynx Point Thermal Sensors
+ /// Step 8.4
+ /// TL [31] locks the thermal throttling registers
+ ///
+ MmioOr32 (ThermalBaseB + R_PCH_TBARB_TL, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TL),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TL)
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Processor PCH-LP cross throttling - Set RCBA MMIO offset 0x33C4[26:24] = 101b
+ ///
+ AsmCpuid (CPUID_VERSION_INFO, &Cpuid.RegEax, &Cpuid.RegEbx, &Cpuid.RegEcx, &Cpuid.RegEdx);
+ if (((Cpuid.RegEax & CPUID_FULL_FAMILY_MODEL) == CPUID_FULL_FAMILY_MODEL_HASWELL_ULT) &&
+ ((PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.PchCrossThrottling == PCH_DEVICE_ENABLE) ||
+ (PchPlatformPolicy->ThermalConfig->ThermalThrottling.TTLevels.SuggestedSetting == PCH_DEVICE_ENABLE))) {
+ Data32And = (UINT32)~(BIT26 | BIT25 | BIT24);
+ Data32Or = BIT26 | BIT24;
+ MmioAndThenOr32 ((UINTN) (RootComplexBar + PMSYNC_TPR_CONFIG), Data32And, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + PMSYNC_TPR_CONFIG),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + PMSYNC_TPR_CONFIG)
+ );
+ }
+ ///
+ /// Lock PMSYNC_TPR_CFG and PMSYNC_TPR_CFG2
+ /// Set RCBA + 0x33C4[31] = 1b.
+ ///
+ MmioOr32 (RootComplexBar + PMSYNC_TPR_CONFIG,B_PMSYNC_TPR_CONFIG_LOCK);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + PMSYNC_TPR_CONFIG),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + PMSYNC_TPR_CONFIG)
+ );
+ }
+
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 17.5 Thermal Throttling
+ /// Step 3
+ /// Set Chipset Initialization Register 30 (RCBA + 2238h) = 00000941h
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.SuggestedSetting == PCH_DEVICE_ENABLE) {
+ RegData32 = 0x00000941;
+ } else {
+ RegData32 = (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS3TW << 10) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS2TW << 8) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS1TW << 6) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.TS0TW << 4) |
+ (UINT32) PchPlatformPolicy->ThermalConfig->ThermalThrottling.DmiHaAWC.DmiTsawEn;
+ }
+ ///
+ /// If DMI IOT is enabled, set chipset Initialization Register 30 (RCBA + 2238h) = 00000551h
+ ///
+ if (PchPlatformPolicy->DmiConfig->DmiIot == PCH_DEVICE_ENABLE) {
+ RegData32 = 0x00000551;
+ }
+ MmioWrite32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238), RegData32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238)
+ );
+ }
+
+ ///
+ /// Step 4
+ /// Program SATA Indexed Register Index and Data:
+ /// a. If port 0 is empty, set D31:F2:A0h=A0h and D31:F2:A4h[15:00] = 0000h
+ /// else if Port 0 has a HDD, set D31:F2:A4h[15:00] = 0039h
+ /// else if Port 0 has a SSD, set D31:F2:A4h[15:00] = 0F39h
+ /// b. If port 1 is empty, set D31:F2:A0h=A0h and D31:F2:A4h[31:16] = 0000h
+ /// else if Port 1 has a HDD, set D31:F2:A4h[31:16] = 0039h
+ /// else if Port 1 has a SSD, set D31:F2:A4h[31:16] = 0F39h
+ /// c. If port 2 is empty, set D31:F2:A0h=A4h and D31:F2:A4h[15:00] = 0000h
+ /// else if Port 2 has a HDD, set D31:F2:A4h[15:00] = 0039h
+ /// else if Port 2 has a SSD, set D31:F2:A4h[15:00] = 0F39h
+ /// d. If port 3 is empty, set D31:F2:A0h=A4h and D31:F2:A4h[31:16] = 0000h
+ /// else if Port 3 has a HDD, set D31:F2:A4h[31:16] = 0039h
+ /// else if Port 3 has a SSD, set D31:F2:A4h[31:16] = 0F39h
+ /// e. If port 4 is empty, set D31:F2:A0h=A8h and D31:F2:A4h[15:00] = 0000h
+ /// else if Port 4 has a HDD, set D31:F2:A4h[15:00] = 0039h
+ /// else if Port 4 has a SSD, set D31:F2:A4h[15:00] = 0F39h
+ /// f. If port 5 is empty, set D31:F2:A0h=A8h and D31:F2:A4h[31:16] = 0000h
+ /// else if Port 5 has a HDD, set D31:F2:A4h[31:16] = 0039h
+ /// else if Port 5 has a SSD, set D31:F2:A4h[31:16] = 0F39h
+ ///
+ MaxSataPortNum = GetPchMaxSataPortNum();
+ RegData16 = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ for (Index = 0; Index < (MaxSataPortNum / 2); Index++) {
+ Data32And = 0x70C070C0;
+ Data32Or = 0x00000000;
+ if (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.SuggestedSetting == PCH_DEVICE_ENABLE) {
+ if ((RegData16 & (B_PCH_SATA_PCS_PORT0_DET << (Index * 2))) != 0) {
+ Data32Or |= 0x00000039;
+ if (PchPlatformPolicy->SataConfig->PortSettings[0 + (Index * 2)].SolidStateDrive == PCH_DEVICE_ENABLE) {
+ Data32Or |= 0x00000F00;
+ }
+ }
+
+ if ((RegData16 & (B_PCH_SATA_PCS_PORT0_DET << ((Index * 2) + 1))) != 0) {
+ Data32Or |= 0x00390000;
+ if (PchPlatformPolicy->SataConfig->PortSettings[1 + (Index * 2)].SolidStateDrive == PCH_DEVICE_ENABLE) {
+ Data32Or |= 0x0F000000;
+ }
+ }
+ } else {
+ Data32Or = (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1TDispFinit << 31) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1Tinact << 26) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1TDisp << 24) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T3M << 20) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T2M << 18) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P1T1M << 16) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0TDispFinit << 15) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0Tinact << 10) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0TDisp << 8) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T3M << 4) |
+ (UINT32) (PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T2M << 2) |
+ (UINT32) PchPlatformPolicy->ThermalConfig->ThermalThrottling.SataTT.P0T1M;
+ }
+
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, (0xA0 + (Index * 4)));
+ MmioAndThenOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD), Data32And, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ }
+
+ ///
+ /// Program ThermalBar + 0xA4 [1:0] = 11b
+ ///
+ MmioOr8 (ThermalBaseB + 0xA4, (UINT8) (BIT1 | BIT0));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + 0xA4),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + 0xA4)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, 17.3.1 Initializing Lynx Point Thermal Sensors
+ /// Step 7
+ /// Enable thermal sensor by programming TSEL register to 01h
+ /// This should be done after all thermal initialization steps are finished.
+ ///
+ RegData8 = MmioRead8 (ThermalBaseB + R_PCH_TBARB_TSEL);
+ RegData8 |= (UINT8) B_PCH_TBARB_TSEL_ETS;
+ ///
+ /// Step 8.5
+ /// TSEL [7] locks the thermal sensor enable, after TAHV and TAHL are programmed by BIOS or driver
+ /// later in case.
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalAlertEnable.TselLock == PCH_DEVICE_ENABLE) {
+ RegData8 |= (UINT8) B_PCH_TBARB_TSEL_PLD;
+ }
+
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSEL, RegData8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSEL),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSEL)
+ );
+ ///
+ /// Step 8.6
+ /// Program ThermalBAR + 0x0A [7] = 1b
+ /// For LP, Program ThermalBar + 0x0A [7, 0] = 1b, 1b
+ ///
+ RegData8 = BIT7;
+ if (PchSeries == PchLp) {
+ RegData8 |= BIT0;
+ }
+ MmioOr8 (ThermalBaseB + R_PCH_TBARB_TSREL, RegData8);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSREL),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSREL)
+ );
+
+ ///
+ /// For LP, Program ThermalBar + 0x1C [14:0] = 48C8h
+ /// For LP, Program ThermalBar + 0x1C [15] = 1h
+ ///
+ if (PchSeries == PchLp) {
+ Data16And = (B_PCH_TBARB_TSPM_LTT | B_PCH_TBARB_TSPM_MAXTSST | B_PCH_TBARB_TSPM_MINTSST | B_PCH_TBARB_TSPM_DTSSIC0 |
+ B_PCH_TBARB_TSPM_DTSSS0EN);
+ Data16Or = (V_PCH_TBARB_TSPM_LTT | V_PCH_TBARB_TSPM_MAXTSST | B_PCH_TBARB_TSPM_DTSSS0EN);
+ MmioAndThenOr16 (ThermalBaseB + R_PCH_TBARB_TSPM,
+ (UINT16) Data16And,
+ (UINT16) Data16Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSPM),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSPM)
+ );
+
+ MmioOr16 (ThermalBaseB + R_PCH_TBARB_TSPM, (UINT16) B_PCH_TBARB_TSPM_TSPMLOCK);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (ThermalBaseB + R_PCH_TBARB_TSPM),
+ 1,
+ (VOID *) (UINTN) (ThermalBaseB + R_PCH_TBARB_TSPM)
+ );
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 17.2, Thermal Subsystem Device Initialization
+ /// Step 5
+ /// BIOS needs to perform the following steps prior to end of POST to free up the PCI resources
+ /// and hide the thermal subsystem device(OPTIONAL), except on mobile platforms that support
+ /// Intel DPPM. Also, BIOS may keep the TBARBH programmed if BIOS needs runtime access to PCH
+ /// thermal subsystem device data. In that case, BIOS must ensure TBARBH memory is reserved and
+ /// reported to the OS as motherboard resources to avoid memory allocation conflicts.
+ ///
+ if (PchPlatformPolicy->ThermalConfig->ThermalDeviceEnable == FALSE) {
+ ///
+ /// Step 5.1
+ /// Clear the Memory and Bus Master enable bit of D31:F6
+ ///
+ MmioAnd16 (
+ PciD31F6RegBase + R_PCH_THERMAL_COMMAND,
+ (UINT16)~(B_PCH_THERMAL_COMMAND_MSE | B_PCH_THERMAL_COMMAND_BME)
+ );
+ ///
+ /// Step 5.2
+ /// Clear and release memory resource assigned in TBAR (D31:F6:10h-13h)
+ ///
+ ThermalBase = MmioRead32 (PciD31F6RegBase + R_PCH_THERMAL_TBAR) & B_PCH_THERMAL_TBAR_MASK;
+
+ if ((ThermalBase != 0) && (ThermalBase != B_PCH_THERMAL_TBAR_MASK)) {
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBAR, 0);
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBARH, 0);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBAR),
+ 1,
+ (VOID *) (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBAR)
+ );
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARH),
+ 1,
+ (VOID *) (UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARH)
+ );
+
+ gDS->FreeMemorySpace (
+ (EFI_PHYSICAL_ADDRESS) ThermalBase,
+ V_PCH_THERMAL_TBAR_SIZE
+ );
+ }
+ ///
+ /// Step 5.3
+ /// Optionally, release and clear memory resource assigned in TBARB (D31:F6:40h-48h) if BIOS/ASL
+ /// implementation does not require access to PCH thermal subsystem device data during run time.
+ /// Left this to platform code
+ ///
+ /// Step 5.4
+ /// Hide D31:F6 PCI configuration space by setting FD.TTD (RCBA + 3418h[24])
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) B_PCH_RCRB_FUNC_DIS_THERMAL;
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ Data32Or = MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS));
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ }
+
+ DEBUG ((EFI_D_INFO, "ThermalLockDown() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Perform Clock Gating programming
+ Enables clock gating in various PCH interfaces and the registers must be restored during S3 resume.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] FuncDisableReg The Function Disable Register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureClockGating (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT32 FuncDisableReg
+ )
+{
+ UINT8 RegData8;
+ UINT32 RegData32;
+ UINT32 RegDataOr32;
+ UINT32 RegDataAnd32;
+ UINTN PciD31F0RegBase;
+ UINT16 LpcDeviceId;
+ UINT16 Data16Or;
+ PCH_SERIES PchSeries;
+ UINT32 D2F0Base;
+
+ DEBUG ((EFI_D_INFO, "ConfigureClockGating() Start\n"));
+
+ PchSeries = GetPchSeries();
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, section 19.10
+ /// 1
+ /// DMI interface
+ /// Enable Dynamic Clock Gating in the DMIC register by programming
+ /// For PCH LP
+ /// RCBA + 2234h [2] to 1b, RCBA + 2234h [0] to 1b
+ /// RCBA + 2234h [3:0] to 1111b
+ /// Set D31:F0:A0h[5] = 1b
+ /// Set D31:F0:A0h[6] = 1b
+ /// Set D31:F0:A0h[7] = 1b
+ /// Set D31:F0:A0h[11] = 0b
+ /// Set D31:F0:A0h[12] = 1b
+ /// For PCH H
+ /// RCBA + 2234h [3:0] to 1111b
+ /// Enable Dynamic Clock Gating in the DMIC register by programming RCBA + 2234h [3:0] to 1111b
+ /// before enabling ASPM.
+ /// Set D31:F0:A0h[11] = 1b
+ /// Set D31:F0:A0h[12] = 1b
+ /// Set D31:F0:A0h[14] = 1b.
+ /// System BIOS is also required to set following bit.
+ /// Dekstop: "Pseudo CLKRUN_EN (PSEUDO_CLKRUN_EN)" bit (D31:F0:A0h[3]) = 1b
+ /// Mobile: "PCI CLKRUN# Enable" bit (D31:F0:A0h[2]) = 1b
+ ///
+ switch (PchSeries) {
+ case PchLp:
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_RCRB_DMIC), (UINT8) (B_PCH_LP_RCRB_DMIC_DMICGEN));
+ break;
+
+ case PchH:
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_RCRB_DMIC), (UINT8) (B_PCH_H_RCRB_DMIC_DMICGEN));
+ break;
+
+ default:
+ break;
+ }
+
+ if (PchSeries == PchLp) {
+ Data16Or = (UINT16)(BIT12 | BIT7 | BIT6 | BIT5);
+ Data16Or |= BIT11;
+ MmioOr16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), Data16Or);
+ } else if (PchSeries == PchH) {
+ MmioOr16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), (UINT16) (BIT14 | BIT12 | BIT11));
+ }
+
+ if (PchPlatformPolicy->DeviceEnabling->PciClockRun == PCH_DEVICE_DISABLE) {
+ if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
+ MmioAnd16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), (UINT16) (~B_PCH_LPC_GEN_PMCON_CLKRUN_EN));
+ } else {
+ MmioAnd16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), (UINT16) (~B_PCH_LPC_GEN_PMCON_PSEUDO_CLKRUN_EN));
+ }
+ } else {
+ if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
+ MmioOr16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), (UINT16) (B_PCH_LPC_GEN_PMCON_CLKRUN_EN));
+ } else {
+ MmioOr16 ((UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1), (UINT16) (B_PCH_LPC_GEN_PMCON_PSEUDO_CLKRUN_EN));
+ }
+ }
+
+ RegData8 = MmioRead8 (RootComplexBar + R_PCH_RCRB_DMIC);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DMIC),
+ 1,
+ &RegData8
+ );
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1)
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set RCBA + 2614h[27:25],[14:13],[10],[8] = 101b, 11b, 1b, 1b respectively
+ /// Set RCBA + 2614h[23:16] = 0x20
+ /// Set RCBA + 2614h[30:28] = 0b
+ /// Set RCBA + 2614h[26] = 1b if D2F0+8 >= 0x0B
+ ///
+ D2F0Base = MmPciAddress (0, 0, 2, 0, 0);
+ RegDataAnd32 = (UINT32) ~(BIT30 | BIT29 | BIT28 | BIT26 | 0x00FF0000);
+ RegDataOr32 = (UINT32) (BIT27 | BIT25 | BIT21 | BIT14 | BIT13 | BIT10 | BIT8);
+ if ((MmioRead16 (D2F0Base) != 0xFFFF) && (MmioRead8 (D2F0Base + 8) >= 0x0B)) {
+ RegDataOr32 |= (UINT32) BIT26;
+ }
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + 0x2614),
+ RegDataAnd32,
+ RegDataOr32
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2614),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2614)
+ );
+ ///
+ /// Set Chipset Initialization Register 2 [4:0] (RCBA + 900h) = 11111b
+ /// Set Chipset Initialization Register 2 [9:8] (RCBA + 900h) = 11b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900),
+ (UINT32) (BIT9 | BIT8 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900)
+ );
+ } else if (PchSeries == PchH) {
+ ///
+ /// Set Chipset Initialization Register 2 [14] (RCBA + 900h) = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900),
+ (UINT32) (BIT14)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR0900)
+ );
+ }
+ ///
+ /// 2
+ /// PCI Express* interface
+ /// 2.1
+ /// For each enabled PCI Express* root port, program D28:F0~F7:Reg E1h[1:0] to 3h to enable dynamic clock gating.
+ /// System BIOS also require to set D28:F0~F7:Reg E8h[0] = 1b
+ /// 2.2
+ /// Additionally, if port 0 is in x2 mode, these bits should not be set for port 1.
+ /// Likewise, if port 0 is in x4 mode, these bits should not be set for ports 1, 2, or 3
+ /// Done in PchRootPorts.c PcieEnableClockGating
+ /// 2.2.1
+ /// If PCIe root ports 0-3 are all disabled, set B0:D28:F0 + E2h[0] = 1b
+ /// if PCIe root ports 4-7 are all disabled, set B0:D28:F4 + E2h[0] = 1b
+ /// 2.3
+ /// Set B0:D28:F0&F4 + E1h [5:2] = 1111b
+ /// 2.4
+ /// Set B0:D28:F0&F4:E1h[7] = 1b
+ /// 2.6
+ /// Set B0:D28:F0~F7 + 324h[5] = 1b
+ /// Done in PchRootPorts.c PcieEnableClockGating
+ ///
+ /// Reg RCBA+341C is modified at multiple places, save at the end of the function
+ ///
+ /// 3
+ /// Serial ATA*
+ /// - Set bits D31:F2:94h[29:24] to 3Fh as part of the chipset initialization before disabling
+ /// the SATA function when the SATA interface is not supported on the platform. BIOS can also
+ /// set PCD bits to disable clocks for the un-routed ports on the platform.
+ /// - After configuring Port and Control Status (PCS) Register Port x Enabled (PxE) bits accordingly,
+ /// wait 1.4 micro second, then the PCD bits (D31:F2:Reg 94h[29:24]) should be set to be the inverse
+ /// of the Port and Control Status (PCS) Register Port x Enabled (PxE) bits
+ /// Please note that PCS should be set and PCD should not be set when ports are enabled for hot
+ /// plug support or used for SATA testing in test mode.
+ /// Done in ConfigureSata();
+ /// - Program D31:F2:98h[29] to 1b
+ /// Done in PchInitBeforeBoot()
+ /// - Set SATA Initialization Register 70h[31:0] = 3F00BF1Fh (Done in ConfigureMiscPm)
+ /// Set SATA Initialization Register 54h[31:0] = CF000F0Fh (Done in ConfigureMiscPm)
+ /// Set SATA Initialization Register 58h[31:0] = 190000h (Done in ConfigureMiscPm)
+ ///
+ /// 4
+ /// USB 1.1 / USB 2.0 / USB 3.0
+ ///
+ /// ConfigureUsbClockGating() has been moved to ConfigureMiscPm() to run before Function Disable
+ ///
+ /// 5
+ /// Intel High Definition Audio (HDA) controller.
+ ///
+ if (FuncDisableReg & B_PCH_RCRB_FUNC_DIS_AZALIA) {
+ ///
+ /// 5.1
+ /// If the HD Audio Controller is not being used, D27:F0 can be disabled and statically gated. Only statically
+ /// gate the Intel High Definition Audio controller if it is not being used in the system by setting RCBA + 341Ch[21].
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_SCG_HDA));
+ } else {
+ ///
+ /// 5.2
+ /// When the Intel High Definition Audio controller is used in the system,
+ /// dynamic clock gating can be used by setting RCBA + 341Ch[22].
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_DCG_HDA));
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// For PchLp, set RCBA + 341Ch[22]
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_DCG_HDA));
+ ///
+ /// 5.3
+ /// Set D27:F0:43h[6:5][2:0] = 11b, 111b (Done in ConfigureMiscPm)
+ ///
+ }
+ ///
+ /// Reg RCBA+341C is modified at multiple places, save at the end of the function
+ ///
+ /// 7
+ /// LPC.
+ /// Enable dynamic clock gating by setting RCRB+341C[31] to 1b.
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_DCG_LPC));
+ if (PchSeries == PchH) {
+ ///
+ /// Reg RCBA+341C is modified at multiple places, save at the end of the function
+ ///
+ /// 8
+ /// PCI Interface.
+ /// Enable PCI dynamic clock gating by setting RCBA + 341Ch[16].
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_DCG_PCI));
+ } else if (PchSeries == PchLp) {
+ ///
+ /// Set RCRB+341Ch[30][28:26] to 1b, 111b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CG),
+ (UINT32) (B_PCH_RCRB_CG_EN_DCG_BLA | B_PCH_RCRB_CG_EN_DCG_GPIO | B_PCH_RCRB_CG_EN_DCG_HPET |
+ B_PCH_RCRB_CG_EN_CG_GPEC));
+ ///
+ /// Set RCRB+3434h[2:0] to 111b
+ ///
+ MmioOr8 (
+ (UINTN) (RootComplexBar + 0x3434),
+ (UINT8) (BIT2 | BIT1 | BIT0)
+ );
+ RegData8 = MmioRead8 (RootComplexBar + 0x3434);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RootComplexBar + 0x3434),
+ 1,
+ &RegData8
+ );
+ ///
+ /// If RCRB+3454h[4] is 0b, then set RCRB+341C[29] to 1b, else set RCRB+341C[29] to 0b
+ ///
+ if ((MmioRead32 (RootComplexBar + R_PCH_RCRB_GSX_CTRL) & B_PCH_RCRB_GSX_BAR_ENABLE) == 0) {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_SCG_GSX));
+ } else {
+ MmioAnd32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (~B_PCH_RCRB_CG_EN_SCG_GSX));
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2.1/10.2.2 Enable/Disable the GbE Clock Gating
+ /// Set RCBA + 341Ch[23]
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Lan == PCH_DEVICE_ENABLE) {
+ MmioAnd32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (~B_PCH_RCRB_CG_EN_SCG_LAN));
+ } else {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_SCG_LAN));
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// 9
+ /// SPI Clock gating.
+ /// Enable SPI clock gating by programming RCBA + 38C0h [13:10][2:0] to 1111b, 111b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_SPI_AFC),
+ (UINT32) (BIT13 | BIT12 | BIT11 | BIT10 | B_PCH_SPI_AFC_INF_DCGE | B_PCH_SPI_AFC_CORE_DCGE)
+ );
+ RegData32 = MmioRead32 (RootComplexBar + R_PCH_SPI_AFC);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_SPI_AFC),
+ 1,
+ &RegData32
+ );
+ } else if (PchSeries == PchH) {
+ ///
+ /// 9
+ /// SPI Clock gating.
+ /// Enable SPI clock gating by programming RCBA + 38C0h [2:0] to 111b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_SPI_AFC),
+ (UINT32) (B_PCH_SPI_AFC_INF_DCGE | B_PCH_SPI_AFC_CORE_DCGE)
+ );
+ RegData32 = MmioRead32 (RootComplexBar + R_PCH_SPI_AFC);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_SPI_AFC),
+ 1,
+ &RegData32
+ );
+ }
+ ///
+ /// 10
+ /// SMBus
+ /// Enable SMBus dynamic clock gating by setting D31:F3:80h [8, 10, 12 and 14] = 0b respectively (Done in ConfigureMiscPm)
+ ///
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, section 19.10
+ /// 11
+ /// Misc
+ /// Set D31:F2:300h [17:16] = 11b (Done in ConfigureMiscPm)
+ ///
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set D31:F2:98h [31:30], [23] to 00b, 1b (Done in ConfigureMiscPm)
+ ///
+ /// Set iobp register CE00C000h[0] to 0b
+ ///
+ ProgramIobpWithScript (
+ RootComplexBar,
+ 0xCE00C000,
+ (UINT32)~(BIT0),
+ 0
+ );
+
+ ///
+ /// Disable legacy DMA (8237) if desired
+ /// Set RCBA + Offset 0x341C[24] = 1
+ ///
+ if ((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4)
+ && PchPlatformPolicy->PwrOptConfig->LegacyDmaDisable)
+ {
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CG), (UINT32) (B_PCH_RCRB_CG_EN_SCG_8237));
+ }
+ }
+ ///
+ /// Save 341C value to the S3 script table. This register is modified at multiple places in this function. So instead of saving
+ /// at each location read the value once at the end of the function and save in S3 resume script.
+ ///
+ RegData32 = MmioRead32 (RootComplexBar + R_PCH_RCRB_CG);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CG),
+ 1,
+ &RegData32
+ );
+
+ DEBUG ((EFI_D_INFO, "ConfigureClockGating() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Configure miscellaneous power management settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureMiscPm (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 GpioBase
+ )
+{
+ UINT8 Data8Or;
+ UINT8 Data8And;
+ UINT32 RegData32;
+ UINT16 RegData16;
+ UINT32 RegData32Tmp;
+ UINTN PciD31F0RegBase;
+ UINTN PciD31F3RegBase;
+ UINTN PciD31F2RegBase;
+ UINT16 LpcDeviceId;
+ UINTN PciD27F0RegBase;
+ PCH_SERIES PchSeries;
+ UINT32 DsxCfg;
+
+ DEBUG ((EFI_D_INFO, "ConfigureMiscPm() Start\n"));
+
+ PchSeries = GetPchSeries();
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ PciD31F3RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 3, 0);
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ PciD27F0RegBase = 0;
+ if (PchSeries == PchLp) {
+ PciD27F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 27, 0, 0);
+ }
+
+ ///
+ /// Clear power / reset status bits on PCH Corporate
+ ///
+ RegData32 = 0;
+ if (PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeWakeSts) {
+ RegData32 |= B_PCH_RCRB_PRSTS_ME_WAKE_STS;
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstColdSts) {
+ RegData32 |= B_PCH_RCRB_PRSTS_ME_HRST_COLD_STS;
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHrstWarmSts) {
+ RegData32 |= B_PCH_RCRB_PRSTS_ME_HRST_WARM_STS;
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.MeHostPowerDn) {
+ RegData32 |= B_PCH_RCRB_PRSTS_ME_HOST_PWRDN;
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->PowerResetStatusClear.WolOvrWkSts) {
+ RegData32 |= B_PCH_RCRB_PRSTS_WOL_OVR_WK_STS;
+ }
+
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_PRSTS, RegData32);
+ RegData32Tmp = 0xFFFFFFFF;
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ RootComplexBar + R_PCH_RCRB_PRSTS,
+ &RegData32, // OR mask
+ &RegData32Tmp // AND mask
+ );
+
+ ///
+ /// We need to enable GP27_PIN_DSX_EN for Wake from both SX and DSX
+ ///
+ DsxCfg = MmioRead32(RootComplexBar + 0x3334);
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.Gp27WakeFromDeepSx == PCH_DEVICE_ENABLE) {
+ DsxCfg |= BIT0;
+ } else {
+ DsxCfg &= ~BIT0;
+ }
+
+ ///
+ /// Enable WAKE_PIN__DSX_EN for Wake
+ ///
+ if(PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_5) {
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.PcieWakeFromDeepSx == PCH_DEVICE_ENABLE) {
+ DsxCfg |= BIT2;
+ } else {
+ DsxCfg &= ~BIT2;
+ }
+ }
+ MmioWrite32 ((RootComplexBar + 0x3334), DsxCfg);
+
+ ///
+ /// Handle wake policy
+ /// Don't need to record in S3 script as R_PCH_LPC_GEN_PMCON_3 is in RTC and SUS power well
+ ///
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3) &
+ (UINT16) (~(B_PCH_LPC_GEN_PMCON_PME_B0_S5_DIS +
+ B_PCH_LPC_GEN_PMCON_WOL_ENABLE_OVERRIDE));
+
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.PmeB0S5Dis) {
+ RegData16 |= B_PCH_LPC_GEN_PMCON_PME_B0_S5_DIS;
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3, RegData16);
+ }
+
+ if (PchPlatformPolicy->MiscPmConfig->WakeConfig.WolEnableOverride) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 10.4 Wake-On-LAN (WOL) Implementation
+ /// Step 1
+ /// Clear D31:F0:A2h[14] = 0b to ensure the LAN PHY will be powered for WOL
+ /// when the power source is either the AC or the DC battery.
+ ///
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2);
+ RegData16 &= (UINT16) ~B_PCH_LPC_GEN_PMCON_DC_PP_DIS;
+
+ ///
+ /// Step 2
+ /// Clear D31:F0:A2h[13] = 0b to ensure the LAN PHY will be powered for WOL in Deep Sx.
+ ///
+ RegData16 &= (UINT16) ~B_PCH_LPC_GEN_PMCON_DSX_PP_DIS;
+
+ ///
+ /// Step 3
+ /// Set D31:F0:A2h[12] = 1b to ensure the LAN PHY will be powered for WOL after a G3 transition.
+ ///
+ RegData16 |= (UINT16) B_PCH_LPC_GEN_PMCON_AG3_PP_EN;
+
+ ///
+ /// Step 4
+ /// Set D31:F0:A2h[11] = 1b to ensure the LAN PHY will be powered for WOL from Sx.
+ ///
+ RegData16 |= (UINT16) B_PCH_LPC_GEN_PMCON_SX_PP_EN;
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2, RegData16);
+
+ ///
+ /// Step 5
+ /// "PME_B0_EN", PMBASE + Offset 28h[13], bit must be programmed to enable wakes
+ /// from S1-S4 at the Power Management Controller
+ /// Done in ASL code(_PRW)
+ ///
+ ///
+ /// Step 6
+ /// Set "WOL Enable Override", D31:F0:A4h:[13], bit to 1b to guarantee the
+ /// LAN-Wakes are enabled at the Power Management Controller, even in surprise
+ /// S5 cases such as power loss/return and Power Button Override
+ ///
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3);
+ RegData16 |= (UINT16) B_PCH_LPC_GEN_PMCON_WOL_ENABLE_OVERRIDE;
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3, RegData16);
+
+ ///
+ /// Step 7
+ /// Moreover, system BIOS also require to enables in the LAN device by performing
+ /// the WOL configuration requirements in the GbE region of the SPI flash.
+ /// Done in PchSmmSxGoToSleep() SMM handler.
+ ///
+ } else {
+ ///
+ /// D31:F0:A2h[14:11] and D31:F0:A4h[13] are all in RTC or DSW well, so BIOS also
+ /// needs to program them while WOL setup option is disabled.
+ ///
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2);
+ RegData16 |= (UINT16) (B_PCH_LPC_GEN_PMCON_DC_PP_DIS | B_PCH_LPC_GEN_PMCON_DSX_PP_DIS);
+ RegData16 &= (UINT16) ~(B_PCH_LPC_GEN_PMCON_AG3_PP_EN | B_PCH_LPC_GEN_PMCON_SX_PP_EN);
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2, RegData16);
+
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3);
+ RegData16 &= (UINT16) ~(B_PCH_LPC_GEN_PMCON_WOL_ENABLE_OVERRIDE);
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3, RegData16);
+ }
+
+ ///
+ /// Configure On DC PHY Power Diable according to policy SlpLanLowDc.
+ /// When this bit is set, SLP_LAN# will be driven low when ACPRESENT is low.
+ /// This indicates that LAN PHY should be powered off on battery mode.
+ /// This will override the DC_PP_DIS setting by WolEnableOverride.
+ ///
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ RegData16 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2);
+ if (PchPlatformPolicy->MiscPmConfig->SlpLanLowDc) {
+ if ((RegData16 & B_PCH_LPC_GEN_PMCON_DC_PP_DIS) == 0) {
+ RegData16 |= (UINT16) (B_PCH_LPC_GEN_PMCON_DC_PP_DIS);
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2, RegData16);
+ }
+ } else {
+ if ((RegData16 & B_PCH_LPC_GEN_PMCON_DC_PP_DIS) != 0) {
+ RegData16 &= (UINT16) ~(B_PCH_LPC_GEN_PMCON_DC_PP_DIS);
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_2, RegData16);
+ }
+ }
+ }
+
+ ///
+ /// - Set SATA Initialization Register 70h[31:0] = 3F00BF1Fh
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x70);
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x3F00BF1F);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ if (PchSeries == PchLp) {
+ ///
+ /// Set SATA Initialization Register 54h[31:0] = CF000F0Fh
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x54);
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0xCF000F0F);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Set SATA Initialization Register 58h[31:0] = 190000h
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x58);
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x190000);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ }
+ ///
+ /// 4
+ /// USB 1.1 / USB 2.0 / USB 3.0
+ ///
+ ConfigureUsbClockGating (PchPlatformPolicy, RootComplexBar);
+
+ if (PchSeries == PchLp) {
+ ///
+ /// 5.3
+ /// Set D27:F0:43h[6:5][3:0] = 11b, 111b
+ ///
+ Data8And = (UINT8) ~0x0;
+ Data8Or = (BIT6 | BIT5 | BIT3 | BIT2 | BIT1 | BIT0);
+ MmioOr8 ((UINTN) (PciD27F0RegBase + 0x43), Data8Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD27F0RegBase + 0x43),
+ &Data8Or, // Data to be ORed
+ &Data8And // Data to be ANDed
+ );
+ }
+ ///
+ /// 10
+ /// SMBus
+ /// Enable SMBus dynamic clock gating by setting D31:F3:80h [8, 10, 12 and 14] = 0b respectively
+ ///
+ MmioAnd16 ((UINTN) (PciD31F3RegBase + 0x80), (UINT16) ~(BIT14 | BIT12 | BIT10 | BIT8));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F3RegBase + 0x80),
+ 1,
+ (VOID *) (UINTN) (PciD31F3RegBase + 0x80)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, section 19.10
+ /// 11
+ /// Misc
+ ///
+ /// Set D31:F2:300h [31:29] to 111b and [19] to 1b
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x300), BIT31 | BIT30 | BIT29 | BIT19);
+ ///
+ /// Set D31:F2:300h [17:16] = 11b
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x300), BIT17 | BIT16);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x300),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x300)
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set D31:F2:98h [31:30], [23] to 00b, 1b
+ ///
+ MmioAndThenOr32(PciD31F2RegBase + 0x98, (UINT32)~(BIT31 | BIT30), BIT23);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x98),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x98)
+ );
+
+ ///
+ /// Set RCBA + 0x333C[23:20] to 1100b
+ ///
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG2),
+ (UINT32)~(BIT21 | BIT20),
+ (UINT32) (BIT22 | BIT23)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG2),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG2)
+ );
+ }
+ DEBUG ((EFI_D_INFO, "ConfigureMiscPm() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Configure additional power management settings
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureAdditionalPm (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINTN PciD31F0RegBase;
+ UINTN PciD31F2RegBase;
+ UINTN PciD28F0RegBase;
+ UINT32 Data32;
+ UINT8 Data8;
+ UINT16 LpcDeviceId;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+
+ Data32 = 0x0;
+ PchSeries = GetPchSeries();
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ PciD28F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 28, 0, 0);
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.4 Additional Power Management Programming
+ /// Step 1
+ /// Set D31:F0:A9h[7:0] = 46h
+ ///
+ MmioWrite8 (
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_CIR4),
+ (UINT8) (0x46)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_CIR4),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_CIR4)
+ );
+ ///
+ /// Step 2
+ /// Set Power Management Initialization Register (PMIR) Field 1, D31:F0:ACh[31] = 1b
+ /// Done in Intel Management Engine Framework Reference Code
+ /// Step 3
+ /// Set GEN_PMCON_LOCK register, D31:F0:A6h = 06h, after stretch and ACPI base programming completed.
+ /// Done in PchInitBeforeBoot()
+ if (PchSeries == PchH) {
+ ///
+ /// Step 4
+ /// Set RCBA + Offset 2238h[0] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238),
+ (UINT32) (BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2238)
+ );
+ }
+ ///
+ /// Step 5
+ /// Set RCBA + Offset 232Ch[0] = 1b
+ ///
+ if (PchSeries == PchH) {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x232C),
+ (UINT32) (BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x232C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x232C)
+ );
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Step 5
+ /// Set RCBA + Offset 232Ch[0] = 0b
+ ///
+ MmioAnd32 (
+ (UINTN) (RootComplexBar + 0x232C),
+ (UINT32) ~(BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x232C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x232C)
+ );
+ ///
+ /// Step 6
+ /// If Trunk Clock Gating is enabled:
+ /// set RCBA + Offset 1100h[15,14,8,5,4,3,2,1,0] all 1b
+ /// If Trunk Clock Gating is disabled:
+ /// set RCBA + Offset 1100h[15] = 0b
+ /// set RCBA + Offset 1100h[14,8,5,4,3,2,1,0] all 1b
+ ///
+
+ if((PchPlatformPolicy->UsbConfig->Usb30Settings.Mode != PCH_XHCI_MODE_ON) &&
+ (PchPlatformPolicy->UsbConfig->Usb30Settings.Btcg == PCH_DEVICE_DISABLE)) {
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100),
+ (UINT32)~(BIT15),
+ (UINT32) (BIT14 | BIT8 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+ );
+ } else {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100),
+ (UINT32) (BIT15 | BIT14 | BIT8 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+ );
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100)
+ );
+ } else if (PchSeries == PchH) {
+ ///
+ /// Step 6
+ /// If Truck Clock Gating is enabled:
+ /// set RCBA + Offset 1100h[14:13] = 11b
+ /// If Truck Clock Gating is disabled:
+ /// set RCBA + Offset 1100h[14:13] = 10b
+ ///
+ if((PchPlatformPolicy->UsbConfig->Usb30Settings.Mode != PCH_XHCI_MODE_ON) &&
+ (PchPlatformPolicy->UsbConfig->Usb30Settings.Btcg == PCH_DEVICE_DISABLE)) {
+ MmioAndThenOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100), (UINT32) ~(BIT13), (UINT32) (BIT14));
+ } else {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100),
+ (UINT32) (BIT14 | BIT13)
+ );
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR1100)
+ );
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set IOBP register 0xCF000000[14:12] = 111b
+ /// Set IOBP register 0XCF000000[0] = 1b
+ ///
+ Data32And = (UINT32)~(0);
+ Data32Or = 0x7001;
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xCF000000,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xCF000000,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Set IOBP register 0xCA000000[3] = 1b
+ /// Set IOBP register 0XCA000000[0] = 1b
+ ///
+ Data32And = (UINT32)~(0);
+ Data32Or = (UINT32) (0x09);
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xCA000000,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM (
+ RootComplexBar,
+ 0xCA000000,
+ Data32And,
+ Data32Or
+ );
+ ASSERT_EFI_ERROR (Status);
+ } else if (PchSeries == PchH) {
+ ///
+ /// Step 7
+ /// Set RCBA + Offset 2304h[31:0] = 0xC07B8400
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DMC),
+ (UINT32) (0xC07B8400)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DMC),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_DMC)
+ );
+ ///
+ /// Step 8
+ /// Set RCBA + Offset 2314h[23 and 5] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2314),
+ (UINT32) (BIT23 | BIT5)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2314),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2314)
+ );
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 19.4 Additional Power Management Programming
+ /// Step 9
+ /// Set B0:D28:F0 + F5h[3:0] = 0101b
+ ///
+ MmioAndThenOr8 (
+ (UINTN) (PciD28F0RegBase + 0xF5),
+ (UINT8) ~(BIT3 | BIT1),
+ (UINT8) (BIT2 | BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD28F0RegBase + 0xF5),
+ 1,
+ (VOID *) (UINTN) (PciD28F0RegBase + 0xF5)
+ );
+
+ if (PchSeries == PchH) {
+ ///
+ /// Step 10
+ /// Set RCBA + Offset 2320h [1] = 1b
+ ///
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320), (UINT32) (BIT1));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320)
+ );
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Step 10
+ /// Set RCBA + Offset 2320h [6:4] = 001b
+ ///
+ MmioAndThenOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320),
+ (UINT8) ~(BIT6 | BIT5),
+ (UINT8) (BIT4)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2320)
+ );
+ }
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 11
+ /// Set RCBA + Offset 3314h[31:0] = 0x00012FFF
+ ///
+ Data32 = 0x00012FFF;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 11
+ /// Set RCBA + Offset 3314h[31:0] = 0x000007BF
+ ///
+ Data32 = 0x000007BF;
+ break;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3314),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3314),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3314)
+ );
+
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 12
+ /// Set RCBA + Offset 3318h[31:0] = 0x0DCF0400
+ ///
+ Data32 = 0x0DCF0400;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 12
+ /// Set RCBA + Offset 3318h[31:0] = 0x0DCF0020 (Note: Keep BIT5 unchanged)
+ ///
+ Data32 = 0x0DCF0020;
+ break;
+ }
+ ///
+ /// Note: RCBA + 3318h[19:16] are platform dependent settings (0Fh provides longest assertion),
+ /// please consult with your board design engineers for correct values to be programmed to.
+ ///
+ /// For RCBA + 3318h[9:8] Reset Power Cycle Duration could be customized, please refer to EDS
+ /// and make sure the setting correct, which never less than the following register.
+ /// - GEN_PMCON_3.SLP_S3_MIN_ASST_WDTH
+ /// - GEN_PMCON_3.SLP_S4_MIN_ASST_WDTH
+ /// - PM_CFG.SLP_A_MIN_ASST_WDTH
+ /// - PM_CFG.SLP_LAN_MIN_ASST_WDTH
+ ///
+ Data32 &= (UINT32)~(B_PCH_RCRB_PM_CFG_SSMAW_MASK | B_PCH_RCRB_PM_CFG_SAMAW_MASK);
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4) {
+ Data32 &= (UINT32)~(B_PCH_RCRB_PM_CFG_RPCD_MASK);
+ }
+
+ switch (PchPlatformPolicy->MiscPmConfig->PchSlpSusMinAssert) {
+ case PchSlpSus0ms:
+ Data32 |= V_PCH_RCRB_PM_CFG_SSMAW_0S;
+ break;
+
+ case PchSlpSus500ms:
+ Data32 |= V_PCH_RCRB_PM_CFG_SSMAW_0_5S;
+ break;
+
+ case PchSlpSus1s:
+ Data32 |= V_PCH_RCRB_PM_CFG_SSMAW_1S;
+ break;
+
+ case PchSlpSus4s:
+ default:
+ Data32 |= V_PCH_RCRB_PM_CFG_SSMAW_4S;
+ break;
+ }
+ switch (PchPlatformPolicy->MiscPmConfig->PchSlpAMinAssert) {
+ case PchSlpA0ms:
+ Data32 |= V_PCH_RCRB_PM_CFG_SAMAW_0S;
+ break;
+
+ case PchSlpA4s:
+ Data32 |= V_PCH_RCRB_PM_CFG_SAMAW_4S;
+ break;
+
+ case PchSlpA98ms:
+ Data32 |= V_PCH_RCRB_PM_CFG_SAMAW_98ms;
+ break;
+
+ case PchSlpA2s:
+ default:
+ Data32 |= V_PCH_RCRB_PM_CFG_SAMAW_2S;
+ break;
+ }
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4) {
+ switch (PchPlatformPolicy->MiscPmConfig->PchPwrCycDur) {
+ case 0: // treat as PCH default
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_4S;
+ break;
+
+ case 1:
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_1S;
+ break;
+
+ case 2:
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_2S;
+ break;
+
+ case 3:
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_3S;
+ break;
+
+ case 4:
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_4S;
+ break;
+
+ default:
+ Data32 |= V_PCH_RCRB_PM_CFG_RPCD_4S;
+ DEBUG ((EFI_D_ERROR, "Error. Not a valid PCH reset power cycle duration setting.\n"));
+ break;
+ }
+ }
+ ///
+ /// For LP, force bit 5 = 0
+ /// For LPT-H, preserve bit 5
+ ///
+ if (PchSeries == PchLp) {
+ Data32 &= (UINT32) ~(BIT5);
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG),
+ Data32
+ );
+ } else {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG),
+ Data32
+ );
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_PM_CFG)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.4 Additional Power Management Programming
+ /// Step 13
+ /// Set RCBA + Offset 3324h[31:0] = 0x04000000
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3324),
+ (UINT32) (0x04000000)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3324),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3324)
+ );
+
+ if (PchSeries == PchH) {
+ ///
+ /// Step 14
+ /// Set RCBA + Offset 3340h[31:0] = 0x020DDBFF
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3340),
+ (UINT32) (0x020DDBFF)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3340),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3340)
+ );
+ ///
+ /// Step 15
+ /// Set RCBA + Offset 3344h[0] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3344),
+ (UINT32) (BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3344),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3344)
+ );
+ }
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 16
+ /// Set RCBA + Offset 3368h[31:0] = 0x00041400
+ ///
+ Data32 = 0x00041400;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 16
+ /// Set RCBA + Offset 3368h[31:0] = 0x00041000
+ ///
+ Data32 = 0x00041000;
+ break;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3368),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3368),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3368)
+ );
+
+ if (PchSeries == PchH) {
+ ///
+ /// Step 17
+ /// Set RCBA + Offset 3378h[31:0] = 3F8DDBFFh
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3378),
+ (UINT32) (0x3F8DDBFF)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3378),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3378)
+ );
+ ///
+ /// Step 18
+ /// Set RCBA + Offset 337Ch[31:0] = 000001E1h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR337C),
+ (UINT32) (0x000001E1)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR337C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR337C)
+ );
+ }
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 19
+ /// Set RCBA + Offset 3388h[31:0] = 0x3F8DDBFF
+ ///
+ Data32 = 0x3F8DDBFF;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 19
+ /// Set RCBA + Offset 3388h[31:0] = 0x00001000
+ ///
+ Data32 = 0x00001000;
+ break;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3388),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3388),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3388)
+ );
+ if (PchSeries == PchH) {
+ ///
+ /// Step 20
+ /// Set RCBA + Offset 33A0h[31:0] = 00000800h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33A0),
+ (UINT32) (0x00000800)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33A0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33A0)
+ );
+ }
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 21
+ /// Set RCBA + Offset 33ACh[31:0] = 0x00007001
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33AC),
+ (UINT32) (0x00007001)
+ );
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 21
+ /// Set RCBA + Offset 33ACh[31:0] = 00001000h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33AC),
+ (UINT32) (0x00001000)
+ );
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33AC),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33AC)
+ );
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 22
+ /// Set RCBA + Offset 33B0h[31:0] = 0x00181900
+ ///
+ Data32 = 0x00181900;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 22
+ /// Set RCBA + Offset 33B0h[31:0] = 0x00001000
+ ///
+ Data32 = 0x00001000;
+ break;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33B0),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33B0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33B0)
+ );
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 23
+ /// Set RCBA + Offset 33C0h[31:0] = 0x00060A00
+ ///
+ Data32 = 0x00060A00;
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 23
+ /// Set RCBA + Offset 33C0h[31:0] = 0x00011900
+ ///
+ Data32 = 0x00011900;
+ break;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33C0),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33C0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33C0)
+ );
+ ///
+ /// Step 24
+ /// LP Set RCBA + Offset 33D0h[31:0] = 0x06200840
+ /// LP Set RCBA + Offset 33D0h[31:0] = 06004622h for LPT LP A0/A1 only
+ /// LPT-H Set RCBA + Offset 33D0h[31:0] = 06000802h
+ switch (PchSeries) {
+ case PchLp:
+ if (PchSeries == PchLp && PchStepping() < LptLpB0) {
+ Data32 = 0x06004622;
+ } else {
+ Data32 = 0x06200840;
+ }
+ break;
+
+ case PchH:
+ default:
+ Data32 = 0x06000802;
+ break;
+ }
+
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D0),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D0)
+ );
+ ///
+ /// Step 25 -- Note, this step has been moved to meet programming sequence requirements
+ /// Register 3A80 - 3A88 must be program after 3A00-3A3F and before 3A6C
+ /// Set RCBA + 3A88h[31:0] = 0x00000001
+ ///
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 26
+ /// Set RCBA + Offset 3A28h[31:0] = 01010101h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A28),
+ (UINT32) (0x01010101)
+ );
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 26
+ /// Set RCBA + Offset 3A28h[31:0] = 01010000h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A28),
+ (UINT32) (0x01010000)
+ );
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A28),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A28)
+ );
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 27
+ /// Set RCBA + Offset 3A2Ch[31:0] = 04040404h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A2C),
+ (UINT32) (0x04040404)
+ );
+ break;
+
+ case PchH:
+ default:
+ ///
+ /// Step 27
+ /// Set RCBA + Offset 3A2Ch[31:0] = 01010404h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A2C),
+ (UINT32) (0x01010404)
+ );
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A2C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A2C)
+ );
+ ///
+ /// Step 29
+ /// Set RCBA + Offset 3A6Ch[31:0] = 00000001h, after all steps in this routine are done
+ /// Done in PchInitBeforeBoot()
+ ///
+ /// Step 30
+ /// For PCH H
+ /// Set RCBA + Offset 2344h[31:24] = 0FFh
+ /// Set RCBA + Offset 2344h[7:0] = 0Ch
+ /// Done in PchInitBeforeBoot()
+ ///
+ /// Step 31
+ /// For LPT-H set RCBA + Offset 33A4h[0] = 1b
+ ///
+ if (PchSeries == PchH) {
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x33A4),
+ (UINT32) (BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33A4),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33A4)
+ );
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Step 32
+ ///
+ /// Set RCBA + Offset 2B1Ch
+ /// [31:30] =2'b00
+ /// [29] =0 if Audio DSP is enabled. 1 if disabled (RCBA offset x3418[1]=1). ConfigureAudioDsp will take care of this bit, which is executed later
+ /// Note1: Must assume enable in this flow because ConfigureAudioDsp only program this in the "audio disable flow" only
+ /// [28:22] = 7'b0001110
+ /// [21:16]=corresponding bit has to be set for each SRC[5:0]CLKRQ# pin that is enabled (ie attached to a PCIe device)
+ /// [15:0]=0x8033h
+ ///
+ Data32 = 0x03808033;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B1C),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B1C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B1C)
+ );
+ ///
+ /// Step 33
+ /// Set RCBA + Offset 2B34[31:0] = 80000009h
+ /// Set bit 3 and 0, PMC shutdown time = 16us
+ ///
+ Data32 = 0x80000009;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B34),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B34),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B34)
+ );
+
+ ///
+ /// Step 34
+ /// Set RCBA + Offset 3348[31:0] = 022DDFFFh
+ ///
+ Data32 = 0x022DDFFF;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3348),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3348),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3348)
+ );
+ ///
+ /// Step 35
+ /// Set RCBA + Offset 334C[31:0] = 00000001h
+ ///
+ Data32 = 0x00000001;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x334C),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x334C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x334C)
+ );
+ ///
+ /// Step 36
+ /// Set RCBA + Offset 3358[31:0] = 0001C000h
+ ///
+ Data32 = 0x0001C000;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3358),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3358),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3358)
+ );
+ ///
+ /// Step 37
+ /// Set RCBA + Offset 3380[31:0] = 3F8DDBFFh
+ ///
+ Data32 = 0x3F8DDBFF;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3380),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3380),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3380)
+ );
+ ///
+ /// Step 38
+ /// Set RCBA + Offset 3384[31:0] = 0001C7E1h
+ ///
+ Data32 = 0x0001C7E1;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3384),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3384),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3384)
+ );
+ ///
+ /// Step 39
+ /// Set RCBA + Offset 338C[31:0] = 0x0001C7E1
+ ///
+ Data32 = 0x0001C7E1;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x338C),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x338C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x338C)
+ );
+ ///
+ /// Step 40
+ /// Set RCBA + Offset 3398[31:0] = 0001C000h
+ ///
+ Data32 = 0x0001C000;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3398),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3398),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3398)
+ );
+ ///
+ /// Step 41
+ /// Set RCBA + Offset 33A8[31:0] = 0x00181900
+ ///
+ Data32 = 0x00181900;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33A8),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33A8),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33A8)
+ );
+ ///
+ /// Step 42
+ /// Set RCBA + Offset 33DC[31:0] = 00080000h
+ ///
+ Data32 = 0x00080000;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33DC),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33DC),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33DC)
+ );
+ ///
+ /// Step 43
+ /// Set RCBA + Offset 33E0[31:0] = 00000001h
+ ///
+ Data32 = 0x00000001;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33E0),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33E0),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33E0)
+ );
+ ///
+ /// Step 44
+ /// Set RCBA + Offset 3A20[31:0] = 00000404h
+ ///
+ Data32 = 0x00000404;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3A20),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3A20),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3A20)
+ );
+ ///
+ /// Step 45
+ /// Set RCBA + Offset 3A24[31:0] = 01010101h
+ ///
+ Data32 = 0x01010101;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3A24),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3A24),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3A24)
+ );
+ ///
+ /// Step 46
+ /// Set RCBA + Offset 3A30[31:0] = 01010101h
+ ///
+ Data32 = 0x01010101;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3A30),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3A30),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3A30)
+ );
+ ///
+ /// Step 47
+ /// Set D31:F0:ACh[21] = 0b
+ ///
+ MmioAnd32 (
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_PMIR),
+ (UINT32) ~(BIT21)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F0RegBase + R_PCH_LPC_PMIR),
+ 1,
+ (VOID *) (UINTN) (PciD31F0RegBase + R_PCH_LPC_PMIR)
+ );
+ ///
+ /// Step 48
+ /// set RCBA + Offset 410h[1:0] = 11b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x410),
+ (UINT32) (BIT1 | BIT0)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x410),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x410)
+ );
+ ///
+ /// Step 49
+ /// Set RCBA + 2618h[27] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x2618),
+ (UINT32) BIT27
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2618),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2618)
+ );
+ ///
+ /// Step 50
+ /// Set RCBA + 2300h[1] = 1b
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) BIT1;
+ MmioOr32 (RootComplexBar + 0x2300 , Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2300),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 51
+ /// Set RCBA + 2600h[3] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x2600),
+ (UINT32) BIT3
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2600),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2600)
+ );
+ ///
+ /// Step 52
+ /// Set RCBA + 33B4h[0] = 0x00007001
+ ///
+ Data32 = 0x00007001;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33B4),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33B4),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33B4)
+ );
+ /// Step 53
+ /// Set RCBA + Offset 3350[31:0] = 0x022DDFFF
+ ///
+ Data32 = 0x022DDFFF;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3350),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3350),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3350)
+ );
+ ///
+ /// Step 54
+ /// Set RCBA + Offset 3354[31:0] = 0x00000001
+ ///
+ Data32 = 0x00000001;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x3354),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x3354),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x3354)
+ );
+ }
+
+ if ((PchPlatformPolicy->PwrOptConfig->PchPwrOptDmi == PCH_DEVICE_ENABLE)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.13 Power Optimizer Considerations (MB Only)
+ /// Notes: Settings is not recommended for Lynx Point Power on ES0 samples
+ /// Step 1
+ /// Enable PM SYNC State 12
+ /// Program RCBA + 33D4h[27] = 1b
+ /// For PCH LP
+ /// Program RCBA + 2B14[31:0] = 1E0A4616h
+ /// Program RCBA + 2B24[31:0] = 40000005h
+ /// For PCH H
+ /// Program RCBA + 2B14[31:0] = 1E0A0317h
+ /// Program RCBA + 2B24[31:0] = 4000000Bh
+ /// Program RCBA + 2B28[31:0] = 00000002h
+ /// Program RCBA + 2B2C[31:0] = 00008813h
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D4),
+ (UINT32) BIT27
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D4),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR33D4)
+ );
+ ///
+ /// Program RCBA + 33C8h[27] = 1b
+ ///
+ Data32Or = BIT27;
+ if (PchSeries == PchLp) {
+ ///
+ /// Program RCBA + 33C8h[7] = 1b
+ ///
+ Data32Or = BIT7;
+ }
+ MmioOr32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PMSYNC),
+ (UINT32) Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PMSYNC),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_PMSYNC)
+ );
+ ///
+ /// For LPT-LP, Program RCBA + 2B10[31:0] = 0000883Ch
+ ///
+ if (PchSeries == PchLp) {
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B10),
+ (UINT32) (0x0000883C)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B10),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B10)
+ );
+ }
+ ///
+ /// Program RCBA + 2B14[31:0] = 1E0A0317h
+ /// For LP Program RCBA + 2B14[31:0] = 1E0A4616h
+ ///
+ Data32 = 0x1E0A0317;
+ if (PchSeries == PchLp) {
+ Data32 = 0x1E0A4616;
+ }
+ if (PchPlatformPolicy->PwrOptConfig->MemCloseStateEn == PCH_DEVICE_DISABLE) {
+ Data32 &= (UINT32) ~(BIT2);
+ }
+ if (PchPlatformPolicy->PwrOptConfig->InternalObffEn == PCH_DEVICE_DISABLE) {
+ Data32 &= (UINT32) ~(BIT1);
+ }
+ if (PchPlatformPolicy->PwrOptConfig->ExternalObffEn == PCH_DEVICE_DISABLE) {
+ Data32 &= (UINT32) ~(BIT0);
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B14),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B14),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B14)
+ );
+ if (PchSeries == PchLp) {
+ ///
+ /// Set RCBA + Offset 2B24[31:0] = 0x40000005
+ ///
+ Data32 = 0x40000005;
+ } else {
+ ///
+ /// Set RCBA + Offset 2B24[31:0] = 0x4000000B
+ ///
+ Data32 = 0x4000000B;
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B24),
+ Data32
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B24),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B24)
+ );
+ if (PchSeries == PchH) {
+ ///
+ /// Set RCBA + Offset 2B28[31:0] = 0x00000002
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B28),
+ (UINT32) (0x00000002)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B28),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B28)
+ );
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Set RCBA + Offset 2B2C[31:0] = 0x00008813
+ ///
+ Data32 = 0x00008813;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B2C),
+ Data32
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B2C),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B2C)
+ );
+ }
+ /// Step 7
+ /// Enable PM Demand in Cx States
+ /// For LPT-H, use default
+ /// For LPT-LP Program RCBA + 02B20h[1:0] = 0x0005DB01
+ ///
+ if (PchSeries == PchLp) {
+ Data32 = 0x0005DB01;
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x2B20),
+ Data32
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2B20),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x2B20)
+ );
+ }
+ }
+ switch (PchSeries) {
+ case PchLp:
+ ///
+ /// Step 55
+ /// Set RCBA + 3A80h[31:0] = 05145005h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A80),
+ (UINT32) (0x05145005)
+ );
+ break;
+ case PchH:
+ default:
+ ///
+ /// Step 55
+ /// Set RCBA + 3A80h[31:0] = 01040000h
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A80),
+ (UINT32) (0x01040000)
+ );
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A80),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A80)
+ );
+ ///
+ /// Step 56
+ /// Ensure this is done after 3A00-3A3C and before 3A6C
+ /// if PchLp, Set RCBA + Offset 3A84h[31:0] = 0x00001005
+ /// if PchH, Set RCBA + Offset 3A84h[31:0] = 0x01041001
+ /// if PCS.P0E and PCS.P1E = 0b, Set RCBA + Offset 3A84h[20,18] = 1b, 1b
+ /// if PCS.P2E and PCS.P3E = 0b, Set RCBA + Offset 3A84h[24,26] = 1b, 1b
+ ///
+ if (PchSeries == PchLp) {
+ Data32 = 0x00001005;
+ } else {
+ Data32 = 0x01041001;
+ }
+ Data8 = MmioRead8 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ if((Data8 & (UINT8) (B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN)) == 0) {
+ Data32 |= (BIT20 | BIT18);
+ }
+ if((Data8 & (UINT8) (B_PCH_SATA_PCS_PORT2_EN | B_PCH_SATA_PCS_PORT3_EN)) == 0) {
+ Data32 |= (BIT24 | BIT26);
+ }
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84),
+ (UINT32) (Data32)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A84)
+ );
+ ///
+ /// Step 57
+ /// Set RCBA + 3A88h[31:0] = 0x00000001
+ ///
+ if (PchSeries == PchH) {
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A88),
+ (UINT32) (0x00000001)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A88),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR3A88)
+ );
+ }
+ ///
+ /// Step 58
+ /// For LPT-LP Set RCBA + Offset 33D4h = 0x2FFF2FB1, after step #14 to #24 and D31:F0:A9h are done
+ /// Note for LP only: Preserve bits 31,30,28,15,14,12, which are platform specific
+ /// For LPT-H Set RCBA + Offset 33D4h = 0xC00BC000, after step #14 to #24 and D31:F0:A9h are done
+ ///
+ switch (PchSeries) {
+ case PchLp:
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x33D4),
+ (UINT32) (0x2FFF2FB1)
+ );
+ break;
+
+ case PchH:
+ default:
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + 0x33D4),
+ (UINT32) (0xC00BC000)
+ );
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33D4),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33D4)
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// This is the last step which only apply for LPT-LP
+ /// Set RCBA + Offset 33C8h[15] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (RootComplexBar + 0x33C8),
+ (UINT32) (BIT15)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x33C8),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x33C8)
+ );
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Configures PCH DMI according to policies specified in PCH Platform Policy protocol
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+EFIAPI
+ConfigureDmiPm (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT16 Data16And;
+ UINT16 Data16Or;
+ UINTN PciD28F0RegBase;
+ PCH_PCI_EXPRESS_ASPM_CONTROL DmiAspmCtrl;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ConfigureDmi() Start\n"));
+
+ PchSeries = GetPchSeries();
+ PciD28F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 28, 0, 0);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 7.1.5 Additional PCH DMI Programming Steps
+ ///
+ if (PchSeries == PchH) {
+ /// Step 4.1
+ /// If RCBA + Offset 2320h[1] = 0 and B0:D28:F0 + F5h[0] = 0, set RCBA + Offset 21A4h[17:15] = 010b
+ /// Else set RCBA + Offset 21A4h[17:15] = 100b
+ ///
+ if (((MmioRead32 ((UINTN) RootComplexBar + R_PCH_RCRB_CIR2320) & (UINT32) (BIT1)) == 0) &&
+ ((MmioRead8 (PciD28F0RegBase + 0xF5) & BIT0) == 0)) {
+ Data32Or = BIT16;
+ } else {
+ Data32Or = BIT17;
+ }
+ ///
+ /// Step 4.2
+ /// Set RCBA + Offset 21A4h[14:12] = 011b
+ ///
+ Data32Or |= BIT13 | BIT12;
+ Data32And = (UINT32)~(B_PCH_RCRB_LCAP_EL1 | B_PCH_RCRB_LCAP_EL0);
+ MmioAndThenOr32 (RootComplexBar + R_PCH_RCRB_LCAP, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_LCAP),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ ///
+ /// Step 4.3
+ /// Set RCBA + 2348[3:0] = 0h
+ ///
+ Data32Or = 0;
+ Data32And = (UINT32) ~(BIT0 | BIT1 | BIT2 | BIT3);
+ MmioAnd32 (RootComplexBar + 0x2348, Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + 0x2348),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ ///
+ /// Enable DMI ASPM
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ ///
+ if (PchPlatformPolicy->DmiConfig->DmiAspm == PCH_DEVICE_ENABLE) {
+ ///
+ /// While DmiAspm is enabled, DMI ASPM will be set to Intel recommended value.
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ /// Note: We recommend PCH platforms to enable L0s and L1, but unless both sides of the link have L0s and/or
+ /// L1 enabled they will be disabled by the link.
+ ///
+ DmiAspmCtrl = PchPcieAspmL0sL1;
+ } else {
+ DmiAspmCtrl = PchPcieAspmDisabled;
+ }
+
+ if (DmiAspmCtrl != PchPcieAspmDisabled) {
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1
+ /// BIOS should set RCBA + 2304h[10] to 0b prior to enabling DMI ASPM.
+ ///
+ Data32And = (UINT32)~(BIT10);
+ Data32Or = 0;
+ MmioAnd32 (RootComplexBar + R_PCH_RCRB_DMC, Data32And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DMC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1
+ ///
+ /// Step 1
+ /// RCBA + 21A4h[11:10] = 11b
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = B_PCH_RCRB_LCAP_APMS;
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_LCAP, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_LCAP),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ if (DmiAspmCtrl == PchPcieAspmL0sL1) {
+ ///
+ /// Step 2
+ /// Enable L0s/L1 on DMI by setting RCBA + offset 21A8h[1:0] to 11b
+ ///
+ Data16And = (UINT16) (~(BIT1 + BIT0));
+ Data16Or = (UINT16) (BIT1 + BIT0);
+
+ } else {
+ //
+ // Do nothing
+ //
+ Data16And = 0xFFFF;
+ Data16Or = 0;
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Program RCBA + offset 21A8h[1:0]
+ ///
+ MmioAndThenOr16 (RootComplexBar + R_PCH_RCRB_LCTL, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_LCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// BIOS should set RCBA + 2304h[10] back to 1b after enabling DMI ASPM.
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) (BIT10);
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_DMC, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_DMC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ }
+
+ if (PchSeries == PchH) {
+ if (PchPlatformPolicy->DmiConfig->DmiExtSync == PCH_DEVICE_ENABLE) {
+ Data16And = (UINT16) (~(B_PCH_RCRB_LCTL_ES));
+ Data16Or = (UINT16) B_PCH_RCRB_LCTL_ES;
+ MmioAndThenOr16 (RootComplexBar + R_PCH_RCRB_LCTL, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_LCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureDmi() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Configure deep Sx programming
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ProgramDeepSx (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar
+ )
+{
+ UINT32 S3Data32;
+ UINT32 S4Data32;
+ UINT32 S5Data32;
+ UINTN PciD31F0RegBase;
+ UINT16 LpcDeviceId;
+
+ PciD31F0RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 0, 0);
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.11 Deep Sx Power Policies
+ /// The System BIOS can perform the following register programming guidelines to enable system
+ /// enter Deep S4 or Deep S5.
+ ///
+ /// DPS3_EN_DC DPS3_EN_AC DPS4_EN_DC DPS4_EN_AC DPS5_EN_DC DPS5_EN_AC
+ /// RCBA+3328h[1] RCBA + 3328h[0] RCBA + 332Ch[1] RCBA + 332Ch[0] RCBA + 3330h[15] RCBA + 3330h[14]
+ /// Deep Sx disabled 0 0 0 0 0 0
+ ///
+ /// Enabled in S5 0 0 0 0 1 1
+ ///
+ /// Enabled in S4 and S5 0 0 1 1 1 1
+ ///
+ /// Enabled in S3, S4 and S5 1 1 1 1 1 1
+ ///
+ /// Configuration supported by MOBILE:
+ /// Enabled in S5 0 0 0 0 1 0
+ /// (Battery mode)
+ /// Enabled in S4 and S5 0 0 1 0 1 0
+ /// (Battery Mode)
+ /// Enabled in S3, S4 and S5 1 0 1 0 1 0
+ /// (Battery Mode)
+ ///
+ /// NOTE: Mobile platforms support Deep S4/S5 in DC ONLY,
+ /// Desktop and Intel C206 Chipset (LPC Dev ID 0x1C56) platforms support Deep S4/S5 in AC ONLY,
+ /// Intel C204 Chipset (LPC Dev ID 0x1C54) and Intel C202 Chipset (LPC Dev ID 0x1C52) platforms DO NOT support Deep S4/S5.
+ ///
+ /// Deep Sx disabled 0 0 0 0 0 0
+ ///
+ if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId) ||
+ IS_PCH_LPT_LPC_DEVICE_ID_SERVER (LpcDeviceId) ||
+ IS_PCH_LPT_LPC_DEVICE_ID_WS (LpcDeviceId)) {
+ if ((PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchMobileDpS5En) ||
+ (PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchMobileDpS4S5En) ||
+ (PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchMobileDpS3S4S5En)) {
+ ///
+ /// Set PchDeepSxPol to PchDeepSxPolDisable for unsupported deep Sx policy
+ ///
+ PchPlatformPolicy->MiscPmConfig->PchDeepSxPol = PchDeepSxPolDisable;
+ DEBUG ((EFI_D_ERROR, "Unsupported Deep Sx policy for desktop system\n"));
+ }
+
+ } else {
+ if ((PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchDesktopDpS5En) ||
+ (PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchDesktopDpS4S5En) ||
+ (PchPlatformPolicy->MiscPmConfig->PchDeepSxPol == PchDesktopDpS3S4S5En)) {
+ ///
+ /// Set PchDeepSxPol to PchDeepSxPolDisable for unsupported deep Sx policy
+ ///
+ PchPlatformPolicy->MiscPmConfig->PchDeepSxPol = PchDeepSxPolDisable;
+ DEBUG ((EFI_D_ERROR, "Unsupported Deep Sx policy for mobile system\n"));
+ }
+ }
+
+ switch (PchPlatformPolicy->MiscPmConfig->PchDeepSxPol) {
+ case PchDesktopDpS5En:
+ ///
+ /// Configuration 2: Enabled in S5/AC-DC
+ /// DEEP_S3_POL.DPS3_EN_DC = 0; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 0; DEEP_S4_POL.DPS4_EN_AC = 0;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 1;
+ ///
+ S3Data32 = 0;
+ S4Data32 = 0;
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_AC | B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchDesktopDpS4S5En:
+ ///
+ /// Configuration 4: Enabled only in S4-S5
+ /// DEEP_S3_POL.DPS3_EN_DC = 0; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 1; DEEP_S4_POL.DPS4_EN_AC = 1;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 1;
+ ///
+ S3Data32 = 0;
+ S4Data32 = (UINT32) (B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_AC | B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC);
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_AC | B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchDesktopDpS3S4S5En:
+ ///
+ /// Configuration 6: Enabled only in S3-S4-S5
+ /// DEEP_S3_POL.DPS3_EN_DC = 1; DEEP_S3_POL.DPS3_EN_AC = 1;
+ /// DEEP_S4_POL.DPS4_EN_DC = 1; DEEP_S4_POL.DPS4_EN_AC = 1;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 1;
+ ///
+ S3Data32 = (UINT32) (B_PCH_RCRB_DEEP_S3_POL_DPS3_EN_AC | B_PCH_RCRB_DEEP_S3_POL_DPS3_EN_DC);
+ S4Data32 = (UINT32) (B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_AC | B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC);
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_AC | B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchMobileDpS5En:
+ ///
+ /// Configuration 1: Enabled in S5/Battery only
+ /// DEEP_S3_POL.DPS3_EN_DC = 0; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 0; DEEP_S4_POL.DPS4_EN_AC = 0;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 0;
+ ///
+ S3Data32 = 0;
+ S4Data32 = 0;
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchMobileDpS4S5En:
+ ///
+ /// Configuration 3: Enabled only in S4-S5/Battery Mode
+ /// DEEP_S3_POL.DPS3_EN_DC = 0; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 1; DEEP_S4_POL.DPS4_EN_AC = 0;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 0;
+ ///
+ S3Data32 = 0;
+ S4Data32 = (UINT32) (B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC);
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchMobileDpS3S4S5En:
+ ///
+ /// Configuration 5: Enabled only in S4-S5/Battery Mode
+ /// DEEP_S3_POL.DPS3_EN_DC = 1; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 1; DEEP_S4_POL.DPS4_EN_AC = 0;
+ /// DEEP_S5_POL.DPS5_EN_DC = 1; DEEP_S5_POL.DPS5_EN_AC = 0;
+ ///
+ S3Data32 = (UINT32) (B_PCH_RCRB_DEEP_S3_POL_DPS3_EN_DC);
+ S4Data32 = (UINT32) (B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC);
+ S5Data32 = (UINT32) (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC);
+ break;
+
+ case PchDeepSxPolDisable:
+ default:
+ ///
+ /// Configuration 5: DeepSx Disabled
+ /// DEEP_S3_POL.DPS3_EN_DC = 0; DEEP_S3_POL.DPS3_EN_AC = 0;
+ /// DEEP_S4_POL.DPS4_EN_DC = 0; DEEP_S4_POL.DPS4_EN_AC = 0;
+ /// DEEP_S5_POL.DPS5_EN_DC = 0; DEEP_S5_POL.DPS5_EN_AC = 0;
+ ///
+ S3Data32 = 0;
+ S4Data32 = 0;
+ S5Data32 = 0;
+ break;
+ }
+
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_DEEP_S3_POL), S3Data32);
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_DEEP_S4_POL), S4Data32);
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_DEEP_S5_POL), S5Data32);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c
new file mode 100644
index 0000000..e9ae324
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchRootPorts.c
@@ -0,0 +1,2154 @@
+/** @file
+ This file contains functions that initializes PCI Express Root Ports of PCH.
+
+@copyright
+ Copyright (c) 1999 - 2014 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+// AMI_OVERRIDE, [EIP84720]>
+#include "Token.h"
+// AMI_OVERRIDE, [EIP84720]<
+
+#ifdef TRAD_FLAG
+UINT32 PchHPcieHsioAddr[] = {
+ 0xE9002E40,
+ 0xE9002C40,
+ 0xE9002A40,
+ 0xE9002840,
+ 0xE9002640,
+ 0xE9002440,
+ 0xE9002240,
+ 0xE9002040,
+ 0xEA002040,
+ 0xEA002240
+};
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+UINT32 PchLpPcieHsioAddr[] = {
+ 0xE9002440,
+ 0xE9002640,
+ 0xE9000840,
+ 0xE9000A40,
+ 0xE9000C40,
+ 0xE9000E40,
+ 0xE9001040,
+ 0xE9001240,
+ 0xEA002040,
+ 0xEA002240,
+ 0xEA002440,
+ 0xEA002640
+};
+#endif // ULT_FLAG
+
+/**
+ Set an Init Root Port Downstream devices S3 dispatch item, this function may assert if any error happend
+
+ @param[in] RootPortBus Pci Bus Number of the root port
+ @param[in] RootPortDevice Pci Device Number of the root port
+ @param[in] RootPortFunc Pci Function Number of the root port
+ @param[in] TempBusNumberMin Minimal temp bus number that can be assigned to the root port (as secondary
+ bus number) and its down stream switches
+ @param[in] TempBusNumberMax Maximal temp bus number that can be assigned to the root port (as subordinate
+ bus number) and its down stream switches
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SetInitRootPortDownstreamS3Item (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax
+ )
+{
+ EFI_STATUS Status;
+#ifdef EFI_S3_RESUME
+ STATIC EFI_PCH_S3_SUPPORT_PROTOCOL *PchS3Support;
+ STATIC EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM S3ParameterRootPortDownstream;
+ STATIC EFI_PCH_S3_DISPATCH_ITEM S3DispatchItem = {
+ PchS3ItemTypeInitPcieRootPortDownstream,
+ &S3ParameterRootPortDownstream
+ };
+ EFI_PHYSICAL_ADDRESS S3DispatchEntryPoint;
+
+ if (!PchS3Support) {
+ ///
+ /// Get the PCH S3 Support Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiPchS3SupportProtocolGuid,
+ NULL,
+ (VOID **) &PchS3Support
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ S3ParameterRootPortDownstream.RootPortBus = RootPortBus;
+ S3ParameterRootPortDownstream.RootPortDevice = RootPortDevice;
+ S3ParameterRootPortDownstream.RootPortFunc = RootPortFunc;
+ S3ParameterRootPortDownstream.TempBusNumberMin = TempBusNumberMin;
+ S3ParameterRootPortDownstream.TempBusNumberMax = TempBusNumberMax;
+ Status = PchS3Support->SetDispatchItem (
+ PchS3Support,
+ &S3DispatchItem,
+ &S3DispatchEntryPoint
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Save the script dispatch item in the Boot Script
+ ///
+ SCRIPT_DISPATCH (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, S3DispatchEntryPoint);
+#else
+ Status = EFI_SUCCESS;
+#endif
+ return Status;
+}
+
+/**
+ Perform Initialization of the Downstream Root Ports.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol
+ @param[in] RootComplexBar RCBA of the PCH
+ @param[in] PmBase The PM I/O Base address of the PCH
+ @param[in, out] FuncDisableReg The function disable register. IN / OUT parameter.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_INVALID_PARAMETER The PCIe Root Port Number of D28:F0 is not found
+ or invalid
+**/
+EFI_STATUS
+PchInitRootPorts (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN UINT16 PmBase,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ PCH_PCI_EXPRESS_CONFIG *PciExpressConfig;
+ UINT32 RpEnableMask;
+ UINT8 PortIndex;
+ UINTN RPBase;
+ UINT32 LoopTime;
+ UINTN PciD31F0RegBase;
+ UINTN PciD31F2RegBase;
+ UINTN PciD28F0RegBase;
+ UINTN PciD28F4RegBase;
+ UINT32 RpFnAnd;
+ UINT32 RpFnOr;
+ UINT32 StrpFuseCfg1;
+ UINT32 StrpFuseCfg2;
+ UINT8 RpLaneOwner;
+ UINT8 GbePort;
+ UINT8 NandPort;
+ UINT16 LpcDeviceId;
+ UINT32 BitMask;
+ UINT32 BitValue;
+ UINT8 FuncNum;
+ UINT8 RpPortFuncIndex;
+ UINT8 Func0PortNum;
+ ///
+ /// Whether a root port is hidden by another one with width > x1
+ ///
+ UINT32 RpHiddenMask;
+ ///
+ /// Subtractive Decode ports if enabled
+ ///
+ UINT32 SubDecodePort;
+ PCH_SERIES PchSeries;
+ UINT8 Mask;
+ BOOLEAN LanEnabled;
+
+ DEBUG ((EFI_D_INFO, "PchInitRootPorts() Start\n"));
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RpEnableMask = 0;
+ RpHiddenMask = 0;
+ PciExpressConfig = PchPlatformPolicy->PciExpressConfig;
+ Data32And = 0xFFFFFFFF;
+ Data32Or = 0;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ PciD31F2RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_SATA,
+ PCI_FUNCTION_NUMBER_PCH_SATA,
+ 0
+ );
+ PciD28F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ 0
+ );
+ PciD28F4RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5),
+ 0
+ );
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ FuncNum = 0;
+ RpPortFuncIndex = 0;
+ Func0PortNum = 0xFF;
+ RpLaneOwner = 0;
+
+ ///
+ /// Configure root port function number mapping and configuration space hiding
+ /// Program at end of function
+ ///
+ RpFnAnd = 0xFFFFFFFF;
+ RpFnOr = 0;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ //
+ // if RootPortFunctionSwapping is enabled, Function number is equal to port index.
+ // else, use the function number mapping from platform policy.
+ //
+ if ((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3) &&
+ (PciExpressConfig->RootPortFunctionSwapping == 1)) {
+ FuncNum = PortIndex;
+ } else {
+ FuncNum = PciExpressConfig->RootPort[PortIndex].FunctionNumber;
+ }
+ RpFnAnd &= (UINT32) (~((B_PCH_RCRB_RPFN_RP1CH | B_PCH_RCRB_RPFN_RP1FN) << (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)));
+ RpFnOr |= (FuncNum) << (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD);
+
+ if (FuncNum < GetPchMaxPciePortNum ()) {
+ ///
+ /// If FunctionNumber of the PCIE Root Port is duplicated, then disable the corresponding "Enable" field.
+ ///
+ if (RpPortFuncIndex & (UINT8) (1 << FuncNum)) {
+ DEBUG ((EFI_D_ERROR, " Hide Root Port %x since its FunctionNumber is duplicated.\n", PortIndex + 1));
+ ASSERT (FALSE);
+ PciExpressConfig->RootPort[PortIndex].Hide = PCH_DEVICE_ENABLE;
+ PciExpressConfig->RootPort[PortIndex].Enable = PCH_DEVICE_DISABLE;
+ RpHiddenMask |= (1 << PortIndex);
+ }
+ ///
+ /// Set RpPortFuncIndex while the FunctionNumber is used.
+ ///
+ RpPortFuncIndex |= (UINT8) (1 << FuncNum);
+ } else {
+ ///
+ /// If FunctionNumber of the PCIE Root Port is outside 7, the Root Port Config Hide bit will be set.
+ /// If so, then disable the corresponding "Enable" field.
+ ///
+ DEBUG ((EFI_D_ERROR, " Root Port %x will be hidden since its FunctionNumber is out of 7.\n", PortIndex + 1));
+ ASSERT (FALSE);
+ PciExpressConfig->RootPort[PortIndex].Enable = PCH_DEVICE_DISABLE;
+ RpHiddenMask |= (1 << PortIndex);
+ }
+
+ RpFnOr |= ((PciExpressConfig->RootPort[PortIndex].Hide) ? B_PCH_RCRB_RPFN_RP1CH : 0) << (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD);
+ ///
+ /// Func0PortNum indicates which PCIe Root Port is D28:F0
+ ///
+ if (FuncNum == 0) {
+ Func0PortNum = PortIndex;
+ }
+ }
+
+ if (Func0PortNum >= GetPchMaxPciePortNum ()) {
+ DEBUG ((EFI_D_ERROR, "The PCIe Root Port Number of D28:F0 is not found or invalid!\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Hide PCIE root port 1-4 according to the PCIE port configuration 1
+ ///
+ StrpFuseCfg1 = MmioRead32 (PciD28F0RegBase + R_PCH_PCIE_STRPFUSECFG);
+ switch (StrpFuseCfg1 & (UINT32) B_PCH_PCIE_STRPFUSECFG_RPC) {
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1:
+ ///
+ /// Port Configuration = 01b: 1x2, 2x1 Port 1 (x2), Port 2 (disabled), Ports 3, 4 (x1)
+ ///
+ RpHiddenMask |= BIT1;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_2:
+ ///
+ /// Port Configuration = 10b: 2x2 Port 1 (x2), Port 3 (x2), Ports 2, 4 (disabled)
+ ///
+ RpHiddenMask |= (BIT1 | BIT3);
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_4:
+ ///
+ /// Port Configuration = 11b: 1x4 Port 1 (x4), Ports 2-4 (disabled)
+ ///
+ RpHiddenMask |= (BIT1 | BIT2 | BIT3);
+ break;
+
+ default:
+ break;
+ }
+
+ if (PchSeries == PchH) {
+ ///
+ /// Hide PCIE root port 5-8 according to the PCIE port configuration
+ ///
+ StrpFuseCfg2 = MmioRead32 (PciD28F4RegBase + R_PCH_PCIE_STRPFUSECFG);
+ switch (StrpFuseCfg2 & (UINT32) B_PCH_PCIE_STRPFUSECFG_RPC) {
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1:
+ ///
+ /// Port Configuration = 01b: 1x2, 2x1 Port 5 (x2), Port 6 (disabled), Ports 7, 8 (x1)
+ ///
+ RpHiddenMask |= BIT5;
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_2_2:
+ ///
+ /// Port Configuration = 10b: 2x2 Port 5 (x2), Port 7 (x2), Ports 6, 8 (disabled)
+ ///
+ RpHiddenMask |= (BIT5 | BIT7);
+ break;
+
+ case V_PCH_PCIE_STRPFUSECFG_RPC_4:
+ ///
+ /// Port Configuration = 11b: 1x4 Port 5 (x4), Ports 6-8 (disabled)
+ ///
+ RpHiddenMask |= (BIT5 | BIT6 | BIT7);
+ break;
+
+ default:
+ break;
+ }
+ }
+ ///
+ /// If GBE Over PCIe Enabled, then System BIOS must disable the PCI Express* Root Port
+ ///
+ LanEnabled = !(MmioRead32 (RootComplexBar + R_PCH_RCRB_BUC) & B_PCH_RCRB_BUC_LAN_DIS);
+
+ if ((StrpFuseCfg1 & B_PCH_PCIE_STRPFUSECFG_GBE_PCIE_PEN) && LanEnabled) {
+ GbePort = (UINT8) ((StrpFuseCfg1 & B_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL) >> N_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL);
+ } else {
+ GbePort = 0xFF;
+ }
+ ///
+ /// If NAND Over PCIe Enabled, then System BIOS must disable the PCI Express* Root Port
+ ///
+ if ((MmioRead32 (PciD31F2RegBase + 0x300) & BIT0) != 0) {
+ NandPort = (UINT8) (((MmioRead32 (PciD31F2RegBase + 0x300)) & 0x1FE) >> 1);
+ } else {
+ NandPort = 0x00;
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 3
+ /// Function disable unused PCIE port
+ /// Disable PCIe Port 1 if either of the conditions are met
+ /// i. B0:D28:F0 + 410h[4] = 0b and B0:D28:F0 + 410h[0] = 0b
+ /// ii. GbeOverPCIe is configured to use Pcie Port 1 and SATA port 4 is mapped to this lane instead of PCIe Port 1
+ /// iii. NandOverPCIe is configured to use PCIe Port 1
+ /// NOTE:
+ /// For condition ii, if Gbe is configured to Pcie Port 1, and Pcie Port 1 ownes the shared lane instead of SATA port 4,
+ /// then it supports Gbe + 8 PCIES configuration, and BIOS won't hide the Root Port 1.
+ ///
+ RpLaneOwner = MmioRead8 (PciD28F0RegBase + 0x410);
+ if ((((RpLaneOwner & (BIT4)) == 0x0) && ((RpLaneOwner & BIT0) == 0x0)) ||
+ ((GbePort == 0x0) && ((RpLaneOwner & (BIT4)) == 0)) ||
+ (NandPort == BIT0)) {
+ RpHiddenMask |= BIT0;
+ }
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Function disabled unused PCIE port
+ /// Disable PCIe Port 1 if either of the conditions are met
+ /// i. B0:D28:F0 + 410h [1:0] = 00b or 10b
+ /// ii. NandOverPCIe is configured to use PCIe Port 1
+ ///
+ if (((MmioRead32 (PciD28F0RegBase + 0x410) & (BIT1 | BIT0)) == 0) ||
+ ((MmioRead32 (PciD28F0RegBase + 0x410) & (BIT1 | BIT0)) == BIT1) ||
+ (NandPort == BIT0)) {
+ RpHiddenMask |= BIT0;
+ }
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Disable PCIe Port 2 if either of the conditions are met
+ /// i. B0:D28:F0 + 410h [5] = 0b and B0:D28:F0 + 410h [2] = 0b
+ /// ii. GbeOverPCIe is configured to use Pcie Port 2 and SATA port 5 is mapped to this lane instead of PCIe Port 2
+ /// iii. NandOverPCIe is configured to use PCIe Port 2
+ /// NOTE:
+ /// For condition ii, if Gbe is configured to Pcie Port 2, and Pcie Port 2 ownes the shared lane instead of SATA port 5,
+ /// then it supports Gbe + 8 PCIES configuration, and BIOS won't hide the Root Port 2.
+ ///
+ if ((((RpLaneOwner & (BIT5)) == 0x0) && ((RpLaneOwner & BIT2) == 0x0)) ||
+ ((GbePort == 0x1) && ((RpLaneOwner & (BIT5)) == 0)) ||
+ (NandPort == BIT1)) {
+ RpHiddenMask |= BIT1;
+ }
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Disable PCIe Port 2 if either of the conditions are met
+ /// i. B0:D28:F0 + 410h [3:2] = 00b or 10b
+ /// ii. NandOverPCIe is configured to use PCIe Port 2
+ ///
+ if (((MmioRead32 (PciD28F0RegBase + 0x410) & (BIT3 | BIT2)) == 0) ||
+ ((MmioRead32 (PciD28F0RegBase + 0x410) & (BIT3 | BIT2)) == BIT3) ||
+ (NandPort == BIT1)) {
+ RpHiddenMask |= BIT1;
+ }
+ }
+ ///
+ /// Disable PCIe Port 3 if GbeOverPCIe is configured to use Port 3
+ ///
+ if ((PchSeries == PchH) && (GbePort == 0x2)) {
+ RpHiddenMask |= BIT2;
+ }
+ if ((PchSeries == PchLp) && (GbePort == 0x0)) {
+ RpHiddenMask |= BIT2;
+ }
+ ///
+ /// Disable PCIe Port 4 if GbeOverPCIe is configured to use Port 4
+ ///
+ if ((PchSeries == PchH) && (GbePort == 0x3)) {
+ RpHiddenMask |= BIT3;
+ }
+ if ((PchSeries == PchLp) && (GbePort == 0x1)) {
+ RpHiddenMask |= BIT3;
+ }
+ ///
+ /// Disable PCIe Port 5 if GbeOverPCIe is configured to use Port 5
+ /// or NandOverPCIe is configure to use Port 5
+ ///
+ if ((PchSeries == PchH) && (GbePort == 0x4 || NandPort == BIT4)) {
+ RpHiddenMask |= BIT4;
+ }
+ ///
+ /// Disable PCIe Port 5 if GbeOverPCIe is configured to use Port 5
+ /// NandOverPCIe is configure to use Port 5
+ ///
+ if ((PchSeries == PchLp) && (GbePort == 0x2 || GbePort == 0x3 || GbePort == 0x4 || GbePort == 0x5 || NandPort == BIT4)) {
+ RpHiddenMask |= BIT4;
+ }
+ ///
+ /// Disable PCIe Port 6 if GbeOverPCIe is configured to use Port 6
+ /// or NandOverPCIe is configure to use Port 6
+ ///
+ if ((PchSeries == PchH) && (GbePort == 0x5 || NandPort == BIT5)) {
+ RpHiddenMask |= BIT5;
+ }
+ ///
+ /// Disable PCIe Port 6 if SATA P1-P4 is configured
+ /// to use Port 6 Lane 0 - Lane 3
+ /// or NandOverPCIe is configure to use Port 6
+ ///
+ if ((PchSeries == PchLp) && ((MmioRead32 (PciD28F0RegBase + 0x410) & (BIT7 | BIT6 | BIT5 | BIT4)) == 0x0) || NandPort == BIT5) {
+ RpHiddenMask |= BIT5;
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Disable PCIe Port 7 if GbeOverPCIe is configured to use Port 7
+ ///
+ if (GbePort == 0x6) {
+ RpHiddenMask |= BIT6;
+ }
+ ///
+ /// Disable PCIe Port 8 if GbeOverPCIe is configured to use Port 8
+ ///
+ if (GbePort == 0x7) {
+ RpHiddenMask |= BIT7;
+ }
+ }
+ if (((MmioRead32 ((UINTN) (RootComplexBar + 0x1030))) & ((UINT32) (BIT22))) &&
+ (PciExpressConfig->EnableSubDecode)) {
+ ///
+ /// Assert if Subtractive Decode Port is disabled by configuration
+ ///
+ ASSERT_EFI_ERROR ((RpHiddenMask & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 <<
+ (PciExpressConfig->PchPcieSbdePort))) == 0x1);
+ SubDecodePort = PciExpressConfig->PchPcieSbdePort;
+ } else {
+ SubDecodePort = 0xFF;
+ }
+ ///
+ /// The port of function number 0 might be disabled.
+ /// Will swap the function number 0 to enabled port on the end of this function.
+ /// Gather the enabled root ports here.
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ if ((PciExpressConfig->RootPort[PortIndex].Enable) &&
+ (((*FuncDisableReg) & (B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex)) == 0)) {
+ RpEnableMask |= 1 << PortIndex;
+ }
+ }
+ ///
+ /// Disable the port which is going to be hidden.
+ ///
+ if (RpEnableMask != 0) {
+ RpEnableMask &= ~(RpHiddenMask);
+ }
+ //
+ // If RootPortFunctionSwapping is disabled, force to enable the root port of function 0
+ //
+ if (!((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3) &&
+ (PciExpressConfig->RootPortFunctionSwapping == 1))) {
+ RpEnableMask |= 1 << Func0PortNum;
+ }
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ FuncNum = GetPchPcieRpfn (RootComplexBar, PortIndex);
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ FuncNum,
+ 0
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 8.2
+ /// Else if the port is hot-plug enable, do not disable the port. If BIOS wants to disable the port,
+ /// BIOS should not enable the hot plug capability or must disable the hot plug capability of the port.
+ /// Set B0:D28:Fn + 338h [26] = 0b at early POST. Done in PchInitPeim.c PchMiscInit().
+ ///
+ /// Enabled Slot implemented for the enabled PCIE Root Ports. This is due to new PCIe disabling methodtology
+ /// to check if any is populated on the slots.
+ ///
+ if ((RpHiddenMask & (1 << PortIndex)) == 0) {
+ MmioOr16 (RPBase + R_PCH_PCIE_XCAP, B_PCH_PCIE_XCAP_SI);
+ }
+
+ if ((RpHiddenMask & (1 << PortIndex)) != 0) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex;
+ } else if (((RpEnableMask & (1 << PortIndex)) != 0) &&
+ ((MmioRead16 (RPBase + R_PCH_PCIE_SLSTS) & BIT6) == 0) &&
+ (PciExpressConfig->RootPort[PortIndex].HotPlug == 0) &&
+ (PortIndex != SubDecodePort)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 8.2
+ /// Else if the port is not hot plug enable and no PCIe card is detected,
+ /// Set B0:D28:Fn + 338h [26] = 1b
+ /// Poll B0:D28:Fn + 328h [31:24] until 01h or else 50ms timeout
+ /// Set B0:D28:Fn + 408h [27] = 1b
+ /// Function disable the port at RCBA+ 3418
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) BIT26;
+ MmioOr32 ((RPBase + 0x338), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + 0x338),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ BitMask = (UINT32) (BIT31 | BIT30 | BIT29 | BIT28 | BIT27 | BIT26 | BIT25 | BIT24);
+ BitValue = 1 << 24;
+ for (LoopTime = 0; LoopTime < 500; LoopTime++) {
+ if ((MmioRead32 (RPBase + 0x328) & BitMask) == BitValue) {
+ break;
+ } else {
+ PchPmTimerStall (100);
+ }
+ }
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ RPBase + 0x328,
+ &BitMask,
+ &BitValue,
+ 50,
+ 1000
+ );
+
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) BIT27;
+ MmioOr32 ((RPBase + 0x408), Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + 0x408),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex;
+ } else if ((RpEnableMask & (1 << PortIndex)) == 0) {
+ ///
+ /// Else if the port is not hot plug enable, and BIOS wants to disable the port
+ /// If a PCIe card is detected, set B0:D28:Fn + 50h[4] = 1b
+ /// followed by function disable the port at RCBA + 3418h
+ ///
+ if ((MmioRead16 (RPBase + R_PCH_PCIE_SLSTS) & BIT6) != 0) {
+ MmioOr16 ((RPBase + R_PCH_PCIE_LCTL), (UINT16) BIT4);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_LCTL),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_LCTL)
+ );
+ }
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << PortIndex;
+ } else {
+ ///
+ /// Configure the rootports
+ ///
+ Status = PchInitSingleRootPort (
+ (UINT8) PortIndex,
+ FuncNum,
+ PchPlatformPolicy,
+ PmBase,
+ RootComplexBar
+ );
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, " Root Port %x device enabled. RpEnableMask: 0x%x\n", PortIndex + 1, RpEnableMask));
+ }
+
+ if ((PciExpressConfig->RootPort[PortIndex].TransmitterHalfSwing) &&
+ (((MmioRead32 (RPBase + 0x328) & (0x00780000)) >> 19) == 0x7)) {
+ MmioOr8 (RPBase + R_PCH_PCIE_LCTL, B_PCH_PCIE_LCTL_LD);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_LCTL),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_LCTL)
+ );
+ MmioOr16 (RPBase + R_PCH_PCIE_PECR1, BIT13);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_PECR1),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_PECR1)
+ );
+ MmioAnd8 (RPBase + R_PCH_PCIE_LCTL, (UINT8) ~(B_PCH_PCIE_LCTL_LD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_LCTL),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_LCTL)
+ );
+ }
+ }
+
+ if (MmioRead32 (RPBase) == 0xFFFFFFFF) {
+ continue;
+ }
+
+ if ((PchSeries == PchH) && (PortIndex == 0 || PortIndex == 4)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 19
+ /// Set B0:F28:F0&F4 + F7h[3:2] = 00b
+ ///
+ MmioAnd8 (RPBase + 0xF7, (UINT8) ~(BIT3 | BIT2));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xF7),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xF7)
+ );
+ }
+ if ((PchSeries == PchLp) && (PortIndex == 0 || PortIndex == 4 || PortIndex == 5)) {
+ ///
+ /// Set B0:F28:F0,F4&F5 + F7h[3:2] = 00b
+ ///
+ MmioAnd8 (RPBase + 0xF7, (UINT8) ~(BIT3 | BIT2));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xF7),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xF7)
+ );
+ }
+
+ if ((RpHiddenMask & (1 << PortIndex)) == 0) {
+ ///
+ /// Disable the forwarding of EOI messages.
+ /// Set B0:D28:F0/F1/F2/F3/F4/F5/F6/F7 + D4h [1] = 1b
+ ///
+ #ifdef HOTPLUG_EOI_FLAG // AMI_OVERRIDE, [EIP84720]>
+ MmioOr8 (RPBase + 0xD4, (UINT8) (BIT1));
+ #else
+ //Supporting _RMV method in asl code, and reading hotplug capability register of root port
+ //if hotplug disable, then set EOI Forwarding Disable bit
+ #ifdef TBT_UP_PORT_FUNC_FLAG
+ if((TBT_UP_PORT_FUNC == PortIndex) || (!(MmioRead8 (RPBase + 0x54) & 0x40)))
+ #else
+ if(!(MmioRead8 (RPBase + 0x54) & 0x40))
+ #endif
+ MmioOr8 (RPBase + 0xD4, (UINT8) (BIT1));
+ #endif // AMI_OVERRIDE, [EIP84720]<
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xD4),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xD4)
+ );
+ }
+ }
+ //
+ // If RootPortFunctionSwapping is disabled, force to enable the root port of function 0
+ //
+ if (!((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3) &&
+ (PciExpressConfig->RootPortFunctionSwapping == 1))) {
+ Mask = (0xFF >>(8-GetPchMaxPciePortNum ()));
+ if (((*FuncDisableReg >> N_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1) & Mask) != Mask) {
+ *FuncDisableReg &= ~(B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 << Func0PortNum);
+ }
+ }
+
+ ///
+ /// Configure root port clock gating
+ ///
+ RpEnableMask = (UINT8)~(*FuncDisableReg >> 16);
+ if (PciExpressConfig->RootPortClockGating) {
+ PcieEnableClockGating (
+ PchPlatformPolicy->BusNumber,
+ PchPlatformPolicy,
+ RpEnableMask,
+ RpHiddenMask,
+ RootComplexBar,
+ NandPort
+ );
+ }
+
+ ///
+ /// Enable PCIE Relaxed Order. It always allows downstream completions to pass posted write.
+ /// Set B0:D28:Fx offset 320h [24,23] to 1, 1b.
+ /// Set RCBA 2314h[31,7] to 1, 1b.
+ /// Set RCBA 1114h[15,14] to 1, 1b.
+ ///
+ for (FuncNum = 0; FuncNum < GetPchMaxPciePortNum (); FuncNum++) {
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ FuncNum,
+ 0
+ );
+ if (MmioRead16 (RPBase + R_PCH_PCIE_VENDOR_ID) == 0xFFFF) {
+ continue;
+ }
+ MmioOr32 (RPBase + R_PCH_PCIE_PECR2, (BIT24 | BIT23));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PECR2),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_PECR2)
+ );
+ }
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_CIR2314, (BIT31 | BIT7));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2314),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + R_PCH_RCRB_CIR2314)
+ );
+ MmioOr16 (RootComplexBar + 0x1114, (BIT15 | BIT14));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RootComplexBar + 0x1114),
+ 1,
+ (VOID *) (UINTN) (RootComplexBar + 0x1114)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 4
+ /// Reconfigured the Function number using RPFN register at RCBA + 404h if function 0 (F0) is disabled
+ /// (If Port of function 0 is disable, swap the function number with other enabled port)
+ ///
+ if ((PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3) &&
+ (PciExpressConfig->RootPortFunctionSwapping == 1)) {
+ Func0PortNum = 0xFF;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ FuncNum = (UINT8)((RpFnOr >> (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+ if (FuncNum == 0) {
+ Func0PortNum = PortIndex;
+ break;
+ }
+ }
+ if ((Func0PortNum < GetPchMaxPciePortNum ()) && ((RpEnableMask & (BIT0 << Func0PortNum)) == 0)) {
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ if ((RpEnableMask & (BIT0 << PortIndex)) != 0) {
+ FuncNum = (UINT8)((RpFnOr >> (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+ RpFnOr &= ((UINT32)~(B_PCH_RCRB_RPFN_RP1FN << (Func0PortNum * S_PCH_RCRB_PRFN_RP_FIELD))) &
+ ((UINT32)~(B_PCH_RCRB_RPFN_RP1FN << (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)));
+ RpFnOr |= ((UINT32)(((UINT32)FuncNum) << (Func0PortNum * S_PCH_RCRB_PRFN_RP_FIELD)));
+ break;
+ }
+ }
+ }
+ }
+
+ MmioAndThenOr32 (RootComplexBar + R_PCH_RCRB_RPFN, RpFnAnd, RpFnOr);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RootComplexBar + R_PCH_RCRB_RPFN),
+ &RpFnOr, // Data to be ORed
+ &RpFnAnd // Data to be ANDed
+ );
+
+ DEBUG ((EFI_D_INFO, "PchInitRootPorts() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Perform Root Port Initialization.
+
+ @param[in] RootPort The root port to be initialized (zero based)
+ @param[in] RootPortFunction The PCI function number of the root port
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol
+ @param[in] PmBase The PM I/O Base address of the PCH
+ @param[in] RootComplexBar RCBA of the PCH
+
+ @retval EFI_SUCCESS Device found. The root port must be enabled.
+ @retval EFI_NOT_FOUND No device is found on the root port. It may be disabled.
+ @exception EFI_UNSUPPORTED Unsupported operation.
+**/
+EFI_STATUS
+PchInitSingleRootPort (
+ IN UINT8 RootPort,
+ IN UINT8 RootPortFunction,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT16 PmBase,
+ IN UINT32 RootComplexBar
+ )
+{
+ EFI_STATUS Status;
+ UINTN RPBase;
+ UINTN LpcBase;
+ UINTN PciD28F0RegBase;
+ UINTN PciD28F4RegBase;
+ UINTN PciD28F5RegBase;
+ UINT32 CapOffset;
+ UINT8 BusNumber;
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ UINT16 Data16Or;
+ UINT16 Data16And;
+ UINT32 PcieNccSSc;
+ UINT8 DeviceLaneOwner;
+ UINT32 PchPcieHsioAddrPerPort[4];
+ UINT8 NumOfLanePerPort;
+ UINT8 LaneIndex;
+ PCH_PCI_EXPRESS_ROOT_PORT_CONFIG *RootPortConfig;
+ BOOLEAN DeviceFound;
+ PCH_SERIES PchSeries;
+ UINT32 DeviceClassDword;
+
+ PchSeries = GetPchSeries();
+ DeviceFound = FALSE;
+ RootPortConfig = &PchPlatformPolicy->PciExpressConfig->RootPort[RootPort];
+ BusNumber = PchPlatformPolicy->BusNumber;
+ RPBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, RootPortFunction, 0);
+ LpcBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0);
+ PciD28F0RegBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1), 0);
+ PciD28F4RegBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5), 0);
+ PciD28F5RegBase = 0;
+ DeviceClassDword = 0;
+ if (PchSeries == PchLp) {
+ PciD28F5RegBase = MmPciAddress (0, BusNumber, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6), 0);
+ }
+ CapOffset = PcieFindCapId (
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ RootPortFunction,
+ 0x10
+ );
+
+ if (CapOffset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ PcieNccSSc = 0;
+ NumOfLanePerPort = 0;
+ switch (RootPort) {
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1:
+ PcieNccSSc = MmioRead32 (PciD28F0RegBase + 0x32C) & BIT28;
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2:
+ PcieNccSSc = MmioRead32 (PciD28F0RegBase + 0x32C) & BIT29;
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3:
+ PcieNccSSc = MmioRead32 (PciD28F0RegBase + 0x32C) & BIT30;
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4:
+ PcieNccSSc = MmioRead32 (PciD28F0RegBase + 0x32C) & BIT31;
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5:
+ PcieNccSSc = MmioRead32 (PciD28F4RegBase + 0x32C) & BIT28;
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6:
+ if (PchSeries == PchH) {
+ PcieNccSSc = MmioRead32 (PciD28F4RegBase + 0x32C) & BIT29;
+ } else if (PchSeries == PchLp) {
+ PcieNccSSc = MmioRead32 (PciD28F5RegBase + 0x32C) & BIT29;
+ }
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7:
+ if (PchSeries == PchH) {
+ PcieNccSSc = MmioRead32 (PciD28F4RegBase + 0x32C) & BIT30;
+ }
+ break;
+
+ case PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8:
+ if (PchSeries == PchH) {
+ PcieNccSSc = MmioRead32 (PciD28F4RegBase + 0x32C) & BIT31;
+ }
+ break;
+
+ default:
+ PcieNccSSc = 0;
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 5
+ /// If corresponding Root Port 4 to 1 in B0:D28:F0 + 32Ch [31:28], Root Port 8 to 5
+ /// in B0:D28:F4 + 32Ch [31:28], is set, for EACH PORT (x):
+ ///
+ if (PcieNccSSc) {
+ ///
+ /// Step 5.1, 5.2
+ /// Set B0:D28:Fx + D4h[4] = 1b
+ /// Set B0:D28:Fx + D4h[3:2] = 10b
+ ///
+ MmioAndThenOr8 ((RPBase + 0xD4), (UINT8)~BIT2, BIT4 | BIT3);
+ ///
+ /// Step 5.3
+ /// Set B0:D28:Fx + D8h[20:18] = 111b
+ ///
+ MmioOr32 ((RPBase + 0xD8), BIT20 | BIT19 | BIT18);
+ ///
+ /// Step 5.4
+ /// Set B0:D28:Fx + 4Ch[17:15] = 100b, see also step 9.
+ ///
+ MmioAndThenOr32 ((RPBase + 0x4C), (UINT32)~(BIT16 | BIT15), BIT17);
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// Step 5.5
+ /// Read the IOBP register below, increase the values by 2 and write back.
+ /// E9002440 [20:16], [12:8]
+ /// E9002640 [20:16], [12:8]
+ /// E9000840 [20:16], [12:8]
+ /// E9000A40 [20:16], [12:8]
+ /// E9000C40 [20:16], [12:8]
+ /// E9000E40 [20:16], [12:8]
+ /// E9001040 [20:16], [12:8]
+ /// E9001240 [20:16], [12:8]
+ /// EA002040 [20:16], [12:8]
+ /// EA002240 [20:16], [12:8]
+ /// EA002440 [20:16], [12:8]
+ /// EA002640 [20:16], [12:8]
+ ///
+ DeviceLaneOwner = MmioRead8 (PciD28F0RegBase + 0x410);
+ if (RootPort == PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5) {
+ NumOfLanePerPort = 4;
+ PchPcieHsioAddrPerPort[0] = PchLpPcieHsioAddr[4];
+ PchPcieHsioAddrPerPort[1] = PchLpPcieHsioAddr[5];
+ PchPcieHsioAddrPerPort[2] = PchLpPcieHsioAddr[6];
+ PchPcieHsioAddrPerPort[3] = PchLpPcieHsioAddr[7];
+ } else if (RootPort == PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6) {
+ NumOfLanePerPort = 0;
+ if ((DeviceLaneOwner & BIT4) == BIT4) {
+ PchPcieHsioAddrPerPort[NumOfLanePerPort++] = PchLpPcieHsioAddr[8];
+ }
+ if ((DeviceLaneOwner & BIT5) == BIT5) {
+ PchPcieHsioAddrPerPort[NumOfLanePerPort++] = PchLpPcieHsioAddr[9];
+ }
+ if ((DeviceLaneOwner & BIT6) == BIT6) {
+ PchPcieHsioAddrPerPort[NumOfLanePerPort++] = PchLpPcieHsioAddr[10];
+ }
+ if ((DeviceLaneOwner & BIT7) == BIT7) {
+ PchPcieHsioAddrPerPort[NumOfLanePerPort++] = PchLpPcieHsioAddr[11];
+ }
+ } else {
+ NumOfLanePerPort = 1;
+ PchPcieHsioAddrPerPort[0] = PchLpPcieHsioAddr[RootPort];
+ }
+ }
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ ///
+ /// Step 5.5
+ /// Read the IOBP register below, increase the values by 2 and write back.
+ /// Dedicated lane Setting
+ /// E9002040 [20:16], [12:8]
+ /// E9002240 [20:16], [12:8]
+ /// E9002440 [20:16], [12:8]
+ /// E9002640 [20:16], [12:8]
+ /// E9002840 [20:16], [12:8]
+ /// E9002A40 [20:16], [12:8]
+ /// Shared lane Setting
+ /// E9002C40 [20:16], [12:8]
+ /// E9002E40 [20:16], [12:8]
+ /// EA002040 [20:16], [12:8]
+ /// EA002240 [20:16], [12:8]
+ ///
+ DeviceLaneOwner = MmioRead8 (PciD28F0RegBase + 0x410);
+ NumOfLanePerPort = 1;
+ if (RootPort == PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1) {
+ if ((DeviceLaneOwner & (BIT1 | BIT0)) == BIT0) {
+ PchPcieHsioAddrPerPort[0] = PchHPcieHsioAddr[0];
+ } else {
+ PchPcieHsioAddrPerPort[0] = PchHPcieHsioAddr[8];
+ }
+ } else if (RootPort == PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2) {
+ if ((DeviceLaneOwner & (BIT3 | BIT2)) == BIT2) {
+ PchPcieHsioAddrPerPort[0] = PchHPcieHsioAddr[1];
+ } else {
+ PchPcieHsioAddrPerPort[0] = PchHPcieHsioAddr[9];
+ }
+ } else {
+ PchPcieHsioAddrPerPort[0] = PchHPcieHsioAddr[RootPort];
+ }
+ }
+#endif // TRAD_FLAG
+ for (LaneIndex = 0; LaneIndex < NumOfLanePerPort; LaneIndex++) {
+ Status = ReadIobp (
+ RootComplexBar,
+ PchPcieHsioAddrPerPort[LaneIndex],
+ &Data32
+ );
+ ASSERT_EFI_ERROR (Status);
+ Data32 += 0x00020200;
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchPcieHsioAddrPerPort[LaneIndex],
+ 0x0,
+ Data32
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = SetProgramIobpS3Item (
+ RootComplexBar,
+ PchPcieHsioAddrPerPort[LaneIndex],
+ 0x0,
+ Data32
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ ///
+ /// Step 5.6
+ /// Set B0:D28:Fx + 338h[26] = 0b
+ ///
+ MmioAnd32 ((RPBase + 0x338), (UINT32)~BIT26);
+ }
+
+ Data32 = MmioRead32 (RPBase + R_PCH_PCIE_DCAP2);
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 8.14.1 Power Optimizer Configuration
+ /// Step 1
+ /// Enable support Latency Tolerance Reporting (LTR)
+ /// Step 1.1
+ /// Program B0:D28:F0~F7 + 400h to 883C883Ch for ports which has a PCIe
+ /// device attached to it.
+ /// Done in PcieSetPm()
+ /// Step 1.2
+ /// Program B0:D28:F0~F7 + 404h [1:0] = 11b for ports which has a PCIe device
+ /// device attached to it.
+ /// Done in PcieSetPm()
+ /// Step 1.3
+ /// Program B0:D28:F0-F7 + 64h [11] = 1b
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[RootPort].LtrEnable == PCH_DEVICE_ENABLE) {
+ Data32 |= BIT11;
+ } else {
+ Data32 &= (UINT32) ~(BIT11);
+ }
+ ///
+ /// Step 2
+ /// Support Optimized Buffer Flush/Fill (OBFF)
+ /// Step 2.1
+ /// Program B0:D28:F0-F7 + 64h [19:18] = 2h
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[RootPort].ObffEnable == PCH_DEVICE_ENABLE) {
+ Data32 |= BIT19;
+ } else {
+ Data32 &= (UINT32) ~(BIT19 | BIT18);
+ }
+ MmioWrite32 (RPBase + R_PCH_PCIE_DCAP2, Data32);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_DCAP2),
+ 1,
+ &Data32
+ );
+
+ Data16 = MmioRead16 (RPBase + R_PCH_PCIE_DCTL2);
+ ///
+ /// Step 1.4
+ /// Program B0:D28:F0-F7 + 68h [10] = 1b
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[RootPort].LtrEnable == PCH_DEVICE_ENABLE) {
+ Data16 |= BIT10;
+ } else {
+ Data16 &= (UINT16) ~(BIT10);
+ }
+ ///
+ /// Step 2.2
+ /// Program B0:D28:F0-F7 + 68h [14:13] = 3h
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[RootPort].ObffEnable == PCH_DEVICE_ENABLE) {
+ Data16 |= BIT14 | BIT13;
+ } else {
+ Data16 &= (UINT16) ~(BIT14 | BIT13);
+ }
+
+ MmioWrite16 (RPBase + R_PCH_PCIE_DCTL2, Data16);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_DCTL2),
+ 1,
+ &Data16
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 6
+ /// Set B0:D28:F0~F7 + 318h [31:16] = 1414h
+ ///
+ Data32Or = 0x14140000;
+ Data32And = (UINT32) (~(0xFFFF0000));
+ MmioAndThenOr32 (RPBase + 0x318, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + 0x318),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ ///
+ /// Step 7
+ /// If B0:D28:F0 + F5h[0] = 1b or step 5 is TRUE, set B0:D28:F0~F7 + 4Ch[17:15] = 100b
+ /// Else set B0:D28:F0~F7 + 4Ch[17:15] = 010b
+ ///
+ if ((MmioRead8 (PciD28F0RegBase + 0xF5) & BIT0) || PcieNccSSc) {
+ Data32Or = BIT17;
+ } else {
+ Data32Or = BIT16;
+ }
+
+ Data32And = (UINT32) (~B_PCH_PCIE_LCAP_EL1);
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_LCAP, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_LCAP),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 8
+ /// Set B0:D28:F0~F7 + 314h[31:24] = 74h
+ /// Step 9
+ /// Set B0:D28:F0~F7 + 314h[23:16] = 3Ah
+ /// Step 10
+ /// Set B0:D28:F0~F7 + 314h[15:08] = 36h
+ /// Step 11
+ /// Set B0:D28:F0~F7 + 314h[07:00] = 1Bh
+ ///
+ Data32Or = 0x743A361B;
+ Data32And = (UINT32) (0x0);
+ MmioAndThenOr32 (RPBase + 0x314, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + 0x314),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 12
+ /// Set B0:D28:F0~F7 + D8h[17:15] = 3h
+ ///
+ Data32And = (UINT32) (~B_PCH_PCIE_MPC_CCEL);
+ Data32Or = BIT16 | BIT15;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_MPC, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_MPC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 13
+ /// Set B0:D28:F0~F7 + 33Ch[24:0] = 854C74h
+ ///
+ Data32And = 0xFF000000;
+ Data32Or = 0x854C74;
+ MmioAndThenOr32 (RPBase + 0x33C, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + 0x33C),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ ///
+ /// Step 16
+ /// Set B0:D28:F0~F7 + D8h[25] = 1b
+ ///
+ Data32And = (UINT32) ~(B_PCH_PCIE_MPC_IRRCE);
+ Data32Or = B_PCH_PCIE_MPC_IRRCE;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_MPC, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_MPC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 17
+ /// For system that support MCTP over PCIE set
+ /// Set B0:D28:F0~F7 + D8h[27] = 1b
+ /// Set B0:D28:F0~F7 + D8h[3] = 1b
+ ///
+ Data32And = (UINT32) ~(B_PCH_PCIE_MPC_MCTPSE | B_PCH_PCIE_MPC_MMBNCE);
+ Data32Or = B_PCH_PCIE_MPC_MCTPSE | B_PCH_PCIE_MPC_MMBNCE;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_MPC, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_MPC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 18
+ /// Set B0:D28:F0~F7 + F5h[7:4] = 0000b
+ ///
+ MmioAnd8 (RPBase + 0xF5, (UINT8) ~(BIT4 | BIT5 | BIT6 | BIT7));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xF5),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xF5)
+ );
+ ///
+ /// Step 20
+ /// If there is no IOAPIC behind the root port, set EOI Forwarding Disable bit (B0:D28:F0-F7:D4h[1]) to 1b.
+ /// Done in PchPciExpressHelpersLibrary.c PcieSetEoiFwdDisable()
+ ///
+ /// Step 21
+ /// For systems that support Advanced Error Reporting set
+ /// B0:D28:F0~F7:100h[19:0] = 10001h
+ /// Else
+ /// B0:D28:F0~F7:100h[19:0] = 0h
+ ///
+ if (RootPortConfig->AdvancedErrorReporting) {
+ Data32 = (UINT32)(BIT16 | BIT0);
+ } else {
+ Data32 = 0;
+ }
+ ///
+ /// For LPT-LP, setup the next capability offset to 0x200
+ /// B0:D28:F0~F7:100h[29] = 1b
+ ///
+ if (PchSeries == PchLp) {
+ Data32 |= BIT29;
+ }
+ MmioWrite32 (RPBase + R_PCH_PCIE_AECH, Data32);
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_AECH),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_AECH)
+ );
+ ///
+ /// Step 22
+ /// System bios should initiate link retrain for all slots that has card populated after register restoration.
+ /// Done in PchPciExpressHelpersLibrary.c PchPcieInitRootPortDownstreamDevices ()
+ /// Step 23
+ /// System BIOS should read and write back to capability register B0:D28:F0 offsets 34h, 40h,
+ /// 80h and 90h after it has been configure or prior to boot
+ /// Done in PchInit.c PciERWORegInit ()
+ ///
+ /// Configure Extended Synch
+ ///
+ if (RootPortConfig->ExtSync) {
+ Data16And = (UINT16) (-1);
+ Data16Or = B_PCH_PCIE_LCTL_ES;
+ } else {
+ Data16And = (UINT16) (~B_PCH_PCIE_LCTL_ES);
+ Data16Or = 0;
+ }
+
+ MmioAndThenOr16 (RPBase + R_PCH_PCIE_LCTL, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_LCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Step 23
+ /// Program B0:D28:F0~F5:320h[21:20] to 01b and [8:6] to 011b
+ ///
+ Data32And = (UINT32) (~(BIT21 | BIT20 | BIT8 | BIT7 | BIT6));
+ Data32Or = BIT20 | BIT7 | BIT6;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_PECR2, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PECR2),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ ///
+ /// Configure Completion Timeout
+ ///
+ Data16And = (UINT16)~(B_PCH_PCIE_DCTL2_CTD | B_PCH_PCIE_DCTL2_CTV);
+ Data16Or = 0;
+ if (RootPortConfig->CompletionTimeout == PchPcieCompletionTO_Disabled) {
+ Data16Or = B_PCH_PCIE_DCTL2_CTD;
+ } else {
+ switch (RootPortConfig->CompletionTimeout) {
+ case PchPcieCompletionTO_Default:
+ Data16Or = V_PCH_PCIE_DCTL2_CTV_DEFAULT;
+ break;
+
+ case PchPcieCompletionTO_16_55ms:
+ Data16Or = V_PCH_PCIE_DCTL2_CTV_40MS_50MS;
+ break;
+
+ case PchPcieCompletionTO_65_210ms:
+ Data16Or = V_PCH_PCIE_DCTL2_CTV_160MS_170MS;
+ break;
+
+ case PchPcieCompletionTO_260_900ms:
+ Data16Or = V_PCH_PCIE_DCTL2_CTV_400MS_500MS;
+ break;
+
+ case PchPcieCompletionTO_1_3P5s:
+ Data16Or = V_PCH_PCIE_DCTL2_CTV_1P6S_1P7S;
+ break;
+
+ default:
+ Data16Or = 0;
+ break;
+ }
+ }
+
+ MmioAndThenOr16 (RPBase + R_PCH_PCIE_DCTL2, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_DCTL2),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Set the Slot Implmemented Bit. Note that this must be set before
+ /// presence is valid.
+ /// PCH BIOS Spec Rev 0.5.0 section 8.2.2, The System BIOS must
+ /// initialize the "Slot Implemented" bit of the PCI Express* Capabilities Register,
+ /// XCAP D28:F0~7:Reg 42h[8] of each available and enabled downstream root port.
+ /// Setting this bit will indicate that the PCI Express* link associated with this
+ /// port is connected to a slot (as compared to being connected to an integrated
+ /// device component).
+ ///
+ if (RootPortConfig->SlotImplemented) {
+ ///
+ /// Slot Implemented enabled earlier. Here will only save this register for enabled ports
+ ///
+ Data16Or = BIT8;
+ Data16And = 0xFFFF;
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + CapOffset + 2),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// For Root Port Slots Numbering on the CRBs.
+ ///
+ Data32Or = 0;
+ Data32And = (UINT32) (~(B_PCH_PCIE_SLCAP_SLV | B_PCH_PCIE_SLCAP_SLS | B_PCH_PCIE_SLCAP_PSN));
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 8.8.2.1
+ /// Note: If Hot Plug is supported, then write a 1 to the Hot Plug Capable (bit6) and Hot Plug
+ /// Surprise (bit5) in the Slot Capabilities register, D28:F0~7:Reg 54h. Otherwise,
+ /// write 0 to the bits PCIe Hot Plug SCI Enable
+ ///
+ Data32And &= (UINT32) (~(B_PCH_PCIE_SLCAP_HPC | B_PCH_PCIE_SLCAP_HPS));
+ if (RootPortConfig->HotPlug) {
+ Data32Or |= B_PCH_PCIE_SLCAP_HPC | B_PCH_PCIE_SLCAP_HPS;
+ }
+ ///
+ /// Get the width from LCAP
+ /// Slot Type X1 X4/X8 X16
+ /// Default 10W 25W 75W
+ /// The slot power consumption and allocation is platform specific. Please refer to the
+ /// "PCI Express* Card Electromechanical (CEM) Spec" for details.
+ /// bugbug what's the default setting for X2
+ ///
+ if ((((MmioRead32 (RPBase + R_PCH_PCIE_LCAP)) & B_PCH_PCIE_LCAP_MLW) >> 4) == 0x01) {
+ Data32Or |= (UINT32) (100 << 7);
+ Data32Or |= (UINT32) (1 << 15);
+ } else if ((((MmioRead32 (RPBase + R_PCH_PCIE_LCAP)) & B_PCH_PCIE_LCAP_MLW) >> 4) >= 0x04) {
+ Data32Or |= (UINT32) (250 << 7);
+ Data32Or |= (UINT32) (1 << 15);
+ }
+
+ Data32Or |= (UINT32) (RootPortConfig->PhysicalSlotNumber << 19);
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_SLCAP, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_SLCAP),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ ///
+ /// Initialize downstream devices
+ ///
+ Status = PchPcieInitRootPortDownstreamDevices (
+ BusNumber,
+ (UINT8) PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ RootPortFunction,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax,
+ &DeviceClassDword
+ );
+ if (Status == EFI_SUCCESS) {
+ DeviceFound = TRUE;
+ } else {
+ ///
+ /// Disable the forwarding of EOI messages.
+ /// Set B0:D28:F0/F1/F2/F3/F4/F5/F6/F7 + D4h [1] = 1b
+ ///
+ #ifdef HOTPLUG_EOI_FLAG // AMI_OVERRIDE, [EIP84720]>
+ MmioOr8 (RPBase + 0xD4, (UINT8) (BIT1));
+ #else
+ //Supporting _RMV method in asl code, and reading hotplug capability register of root port
+ //if hotplug disable, then set EOI Forwarding Disable bit
+ #ifdef TBT_UP_PORT_FUNC_FLAG
+ if((TBT_UP_PORT_FUNC == RootPortFunction) || (!(MmioRead8 (RPBase + 0x54) & 0x40)))
+ #else
+ if(!(MmioRead8 (RPBase + 0x54) & 0x40))
+ #endif
+ MmioOr8 (RPBase + 0xD4, (UINT8) (BIT1));
+ #endif // AMI_OVERRIDE, [EIP84720]<
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xD4),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xD4)
+ );
+ }
+ ///
+ /// Not checking the error status here - downstream device not present does not
+ /// mean an error of this root port. Our return status of EFI_SUCCESS means this
+ /// port is enabled and outer function depends on this return status to do
+ /// subsequent initializations.
+ ///
+ Status = SetInitRootPortDownstreamS3Item (
+ BusNumber,
+ (UINT8) PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ RootPortFunction,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMin,
+ PchPlatformPolicy->PciExpressConfig->TempRootPortBusNumMax
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Additional configurations
+ ///
+
+ ///
+ /// Enable Subtractive Decode of RootPort
+ /// Step 1
+ /// Ensure flash descriptor PCH Strap 9 Bit 14, which read RCBA + 1030h[22] = 1b
+ /// Step 2
+ /// Set B0:D28:Fn + ECh[1:0] = 11b,
+ /// If downstream is PCI-to-PCI bridge, then also set B0:D28:Fn + ECh[2] = 1b
+ ///
+ if ((RootPort == PchPlatformPolicy->PciExpressConfig->PchPcieSbdePort) &&
+ (MmioRead32 ((UINTN) (RootComplexBar + 0x1030)) & BIT22) &&
+ (PchPlatformPolicy->PciExpressConfig->EnableSubDecode))
+ {
+ Data32Or = (B_PCH_PCIE_PECR3_SDCDID | B_PCH_PCIE_PECR3_SDE);
+ if ((((DeviceClassDword >> 24) & 0xFF) == PCI_CLASS_BRIDGE) && // BCC
+ (((DeviceClassDword >> 16) & 0xFF) == PCI_CLASS_BRIDGE_CARDBUS)) // SCC
+ {
+ Data32Or |= BIT2;
+ }
+
+ MmioOr32 (RPBase + R_PCH_PCIE_PECR3, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PECR3),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_PECR3)
+ );
+ }
+
+ ///
+ /// Configure Error Reporting policy in the Device Control Register
+ ///
+ Data16And = (UINT16) (~(B_PCH_PCIE_DCTL_URE | B_PCH_PCIE_DCTL_FEE | B_PCH_PCIE_DCTL_NFE | B_PCH_PCIE_DCTL_CEE));
+ Data16Or = 0;
+
+ if (RootPortConfig->UnsupportedRequestReport) {
+ Data16Or |= B_PCH_PCIE_DCTL_URE;
+ }
+
+ if (RootPortConfig->FatalErrorReport) {
+ Data16Or |= B_PCH_PCIE_DCTL_FEE;
+ }
+
+ if (RootPortConfig->NoFatalErrorReport) {
+ Data16Or |= B_PCH_PCIE_DCTL_NFE;
+ }
+
+ if (RootPortConfig->CorrectableErrorReport) {
+ Data16Or |= B_PCH_PCIE_DCTL_CEE;
+ }
+
+ MmioAndThenOr16 (RPBase + R_PCH_PCIE_DCTL, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_DCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Configure Interrupt / Error reporting in R_PCH_PCIE_RCTL
+ ///
+ Data16And = (UINT16) (~(B_PCH_PCIE_RCTL_PIE | B_PCH_PCIE_RCTL_SFE | B_PCH_PCIE_RCTL_SNE | B_PCH_PCIE_RCTL_SCE));
+ Data16Or = 0;
+
+ if (RootPortConfig->PmeInterrupt) {
+ Data16Or |= B_PCH_PCIE_RCTL_PIE;
+ }
+
+ if (RootPortConfig->SystemErrorOnFatalError) {
+ Data16Or |= B_PCH_PCIE_RCTL_SFE;
+ }
+
+ if (RootPortConfig->SystemErrorOnNonFatalError) {
+ Data16Or |= B_PCH_PCIE_RCTL_SNE;
+ }
+
+ if (RootPortConfig->SystemErrorOnCorrectableError) {
+ Data16Or |= B_PCH_PCIE_RCTL_SCE;
+ }
+
+ MmioAndThenOr16 (RPBase + R_PCH_PCIE_RCTL, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_RCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Root PCI-E Powermanagement SCI Enable
+ ///
+ if (RootPortConfig->PmSci) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 8.7.3 BIOS Enabling of Intel PCH PCI Express* PME SCI Generation
+ /// Step 1
+ /// Make sure that PME Interrupt Enable bit, D28:F0-7:Reg 5Ch[3] is cleared
+ ///
+ Data16And = (UINT16) (~B_PCH_PCIE_RCTL_PIE);
+ Data16Or = 0;
+ MmioAnd16 (RPBase + R_PCH_PCIE_RCTL, Data16And);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + R_PCH_PCIE_RCTL),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+
+ ///
+ /// Step 2
+ /// Program Misc Port Config (MPC) register at PCI config space offset
+ /// D8h as follows:
+ /// Set Power Management SCI Enable bit, D28:F0~7:Reg D8h[31]
+ /// Clear Power Management SMI Enable bit, D28:F0~7:Reg D8h[0]
+ ///
+ Data32And = (UINT32) (~B_PCH_PCIE_MPC_PMME);
+ Data32Or = B_PCH_PCIE_MPC_PMCE;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_MPC, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_MPC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+
+ ///
+ /// Step 3
+ /// Make sure GPE0 Register (PMBase+20h[9]), PCI_EXP_STS is 0, clear it if not zero
+ ///
+ if (PchSeries == PchLp) {
+ Data32Or = IoRead32 (PmBase + R_PCH_ACPI_GPE0_STS_127_96);
+ if ((Data32Or & B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP) != 0) {
+ Data32Or = B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP;
+ IoWrite32 (PmBase + R_PCH_ACPI_GPE0_STS_127_96, Data32Or);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PmBase + R_PCH_ACPI_GPE0_STS_127_96),
+ 1,
+ &Data32Or
+ );
+ }
+ } else if (PchSeries == PchH) {
+ Data32Or = IoRead32 (PmBase + R_PCH_ACPI_GPE0a_STS);
+ if ((Data32Or & B_PCH_ACPI_GPE0a_STS_PCI_EXP) != 0) {
+ Data32Or = B_PCH_ACPI_GPE0a_STS_PCI_EXP;
+ IoWrite32 (PmBase + R_PCH_ACPI_GPE0a_STS, Data32Or);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PmBase + R_PCH_ACPI_GPE0a_STS),
+ 1,
+ &Data32Or
+ );
+ }
+ }
+ ///
+ /// Step 4
+ /// Set BIOS_PCI_EXP_EN bit, D31:F0:Reg A0[10],
+ /// to globally enable the setting of the PCI_EXP_STS bit by a PCI Express* PME event.
+ ///
+ Data16Or = MmioRead16 (LpcBase + R_PCH_LPC_GEN_PMCON_1);
+ if ((Data16Or & B_PCH_LPC_GEN_PMCON_BIOS_PCI_EXP_EN) == 0) {
+ Data16And = 0xFFFF;
+ Data16Or = B_PCH_LPC_GEN_PMCON_BIOS_PCI_EXP_EN;
+ MmioOr16 (LpcBase + R_PCH_LPC_GEN_PMCON_1, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (LpcBase + R_PCH_LPC_GEN_PMCON_1),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ }
+ }
+
+ if (RootPortConfig->HotPlug) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 8.8.2.1
+ /// Step 1
+ /// Clear following status bits, by writing 1b to them, in the Slot
+ /// Status register at offset 1Ah of PCI Express Capability structure:
+ /// Attention Button Pressed (bit0)
+ /// Presence Detect Changed (bit3)
+ ///
+ Data16And = 0xFFFF;
+ Data16Or = (BIT3 | BIT0);
+ MmioOr16 (RPBase + CapOffset + 0x1A, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + CapOffset + 0x1A),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// Step 2
+ /// Program the following bits in Slot Control register at offset 18h
+ /// of PCI Express* Capability structure:
+ /// Attention Button Pressed Enable (bit0) = 1b
+ /// Presence Detect Changed Enable (bit3) = 1b
+ /// Hot Plug Interrupt Enable (bit5) = 0b
+ ///
+ Data16And = (UINT16) (~BIT5);
+ Data16Or = (BIT3 | BIT0);
+ MmioAndThenOr16 (RPBase + CapOffset + 0x18, Data16And, Data16Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (RPBase + CapOffset + 0x18),
+ &Data16Or, // Data to be ORed
+ &Data16And // Data to be ANDed
+ );
+ ///
+ /// Step 3
+ /// Program Misc Port Config (MPC) register at PCI config space offset
+ /// D8h as follows:
+ /// Hot Plug SCI Enable (HPCE, bit30) = 1b
+ /// Hot Plug SMI Enable (HPME, bit1) = 0b
+ ///
+ Data32And = (UINT32) (~B_PCH_PCIE_MPC_HPME);
+ Data32Or = B_PCH_PCIE_MPC_HPCE;
+ MmioAndThenOr32 (RPBase + R_PCH_PCIE_MPC, Data32And, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_MPC),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 4
+ /// Clear GPE0 Register (PMBase+20h), bit1, HOT_PLUG_STS by writing 1
+ ///
+ if (PchSeries == PchLp) {
+ IoWrite32 (PmBase + R_PCH_ACPI_GPE0_STS_127_96, (UINT32) B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG);
+ } else if (PchSeries == PchH) {
+ IoWrite32 (PmBase + R_PCH_ACPI_GPE0a_STS, (UINT32) B_PCH_ACPI_GPE0a_STS_HOT_PLUG);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 8.9
+ /// BIOS should mask the reporting of Completion timeout (CT) errors byerrors by setting
+ /// the uncorrectable Error Mask register D28:F0~7:Reg 108h[14].
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = B_PCH_PCIE_UEM_CT;
+ MmioOr32 (RPBase + R_PCH_PCIE_UEM, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_UEM),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+
+ if (DeviceFound == TRUE || (RootPortConfig->HotPlug == PCH_DEVICE_ENABLE)) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+}
+
+/**
+ This is the function to enable the clock gating for PCI Express ports.
+
+ @param[in] BusNumber The Bus Number of the PCH device
+ @param[in] PchPlatformPolicy PCH Platform Policy protocol
+ @param[in] RpEnableMask Bit Mask indicating the enabled root ports
+ @param[in] RpHiddenMask Bit Mask indicating the root ports used for other > x1 root ports
+ @param[in] RootComplexBar Root complex base address
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieEnableClockGating (
+ IN UINT8 BusNumber,
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RpEnableMask,
+ IN UINT32 RpHiddenMask,
+ IN UINT32 RootComplexBar,
+ IN UINT32 NandPort
+ )
+{
+ UINTN RPBase;
+ UINT32 PortIndex;
+ UINT8 Data8Or;
+ UINT8 Data8And;
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ UINT16 GpioBase;
+ BOOLEAN ClkreqPerPortSupported;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ GpioBase = 0;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10 Enabling Clock Gating
+ /// 2.1
+ /// For each enabled PCI Express* root port, program D28:F0~F7:Reg E1h[1:0] to 3h to enable dynamic clock gating.
+ /// System BIOS also require to set D28:F0~F7:Reg E8h[0] = 1b
+ /// 2.2
+ /// Additionally, if port 0 is in x2 mode, these bits should not be set for port 1.
+ /// Likewise, if port 0 is in x4 mode, these bits should not be set for ports 1, 2, or 3
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ ClkreqPerPortSupported = FALSE;
+ if (PchSeries == PchLp) {
+ GpioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE)
+ ) & B_PCH_LPC_GPIO_BASE_BAR;
+ Data32Or = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + PortIndex))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ if (Data32Or == 0) {
+ ClkreqPerPortSupported = TRUE;
+ }
+ }
+ if (((RpEnableMask & (1 << PortIndex)) != 0) && ((RpHiddenMask & (1 << PortIndex)) == 0)) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn (RootComplexBar, (UINT8) PortIndex),
+ 0
+ );
+
+ Data8Or = B_PCH_PCIE_RPDCGEN_RPDLCGEN | B_PCH_PCIE_RPDCGEN_RPDBCGEN;
+ Data8And = 0xFF;
+ MmioOr8 (
+ RPBase + R_PCH_PCIE_RPDCGEN,
+ Data8Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ &Data8Or, // Data to be ORed
+ &Data8And // Data to be ANDed
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// 2.3
+ /// Program D28:F0~F5:E2h[6] to 1b
+ ///
+ Data8Or = B_PCH_PCIE_RPPGEN_PTOTOP;
+ Data8And = (UINT8)~B_PCH_PCIE_RPPGEN_PTOTOP;
+ MmioOr8 (
+ RPBase + R_PCH_PCIE_RPPGEN,
+ Data8Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPPGEN),
+ &Data8Or, // Data to be ORed
+ &Data8And // Data to be ANDed
+ );
+
+ ///
+ /// 2.4
+ /// Program D28:F0~F5:E8h[3:2] to 10b before setting D28:F0~F5:E8h[1:0]
+ ///
+ Data8Or = BIT3;
+ Data8And = (UINT8)~(V_PCH_PCIE_PECR1_FIELD_3);
+ MmioAndThenOr8 (
+ RPBase + R_PCH_PCIE_PECR1,
+ Data8And,
+ Data8Or
+ );
+ }
+
+ Data32And = 0xFFFFFFFF;
+ Data32Or = (UINT32) BIT0;
+ MmioOr32 (RPBase + R_PCH_PCIE_PECR1, Data32Or);
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PECR1),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// Step 2.6
+ /// Set B0:D28:F0~F7 + 324h[5] = 1b
+ ///
+ MmioOr32 (RPBase + R_PCH_PCIE_PEETM, (UINT32) (BIT5));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PEETM),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_PEETM)
+ );
+//for Denlow SVR, refer Inel doc 493798, c state communication
+#ifdef PCH_DENLOW_SERVER_SUPPORT
+ /// Set B0:D28:F0~F7 + 324h[3] = 1b
+ ///
+ MmioOr32 (RPBase + R_PCH_PCIE_PEETM, (UINT32) (BIT3));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PEETM),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_PEETM)
+ );
+#endif
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Program D28:F0~F5:E2h[5:4] to 11b prior to function disable the port
+ /// Program D28:F0~F5:420h[31] to 1b prior to function disable the port
+ ///
+ if ((RpEnableMask & (1 << PortIndex)) == 0) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn (RootComplexBar, (UINT8) PortIndex),
+ 0
+ );
+ Data8Or = (B_PCH_PCIE_RPPGEN_LMSDOCGE | B_PCH_PCIE_RPPGEN_SEOCGE);
+ Data8And = (UINT8)~(B_PCH_PCIE_RPPGEN_LMSDOCGE | B_PCH_PCIE_RPPGEN_SEOCGE);
+ MmioOr8 (
+ RPBase + R_PCH_PCIE_RPPGEN,
+ Data8Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPPGEN),
+ &Data8Or, // Data to be ORed
+ &Data8And // Data to be ANDed
+ );
+ Data32Or = (B_PCH_PCIE_PCIEPMECTL_FDPGE);
+ Data32And = (UINT32)~(B_PCH_PCIE_PCIEPMECTL_FDPGE);
+ MmioOr32 (
+ RPBase + R_PCH_PCIE_PCIEPMECTL,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PCIEPMECTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ ///
+ /// Program D28:F0~F5:420h[30:29] to 111b
+ ///
+ if (ClkreqPerPortSupported) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn (RootComplexBar, (UINT8) PortIndex),
+ 0
+ );
+ Data32Or = (B_PCH_PCIE_PCIEPMECTL_DLSULPGE | B_PCH_PCIE_PCIEPMECTL_DLSULDLSD);
+ Data32And = (UINT32)~(B_PCH_PCIE_PCIEPMECTL_DLSULPGE | B_PCH_PCIE_PCIEPMECTL_DLSULDLSD);
+ MmioOr32 (
+ RPBase + R_PCH_PCIE_PCIEPMECTL,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (RPBase + R_PCH_PCIE_PCIEPMECTL),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ }
+ }
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 2.4
+ /// Program D28:F0,F4&F5:Reg E1h[5:2] to 1111b
+ /// Program D28:F0,F4&F5:Reg E1h[7] to 1b
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex ++) {
+ if ((PortIndex == 0 || PortIndex == 4 || PortIndex == 5) && !(NandPort & (0x1 << PortIndex))) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn (RootComplexBar, (UINT8) PortIndex),
+ 0
+ );
+ Data8Or =
+ (
+ B_PCH_PCIE_RPDCGEN_LCLKREQEN |
+ B_PCH_PCIE_RPDCGEN_BBCLKREQEN |
+ B_PCH_PCIE_RPDCGEN_SRDLCGEN |
+ B_PCH_PCIE_RPDCGEN_SRDBCGEN
+ );
+
+ MmioOr8 (RPBase + R_PCH_PCIE_RPDCGEN, Data8Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN)
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 2.5
+ /// If PCIe root ports 0-3 are all disabled, set B0:D28:F0 + E2h [0] = 1b and E1h [7] = 1b.
+ /// If PCIe root port 4 is disabled, set B0:D28:F4 + E2h [0] = 1b and E1h [7] = 1b.
+ /// If PCIe root port 5 is disabled, set B0:D28:F5 + E2h [0] = 1b and E1h [7] = 1b.
+ ///
+ if (((!(RpEnableMask & 0xF)) && (PortIndex == 0)) || ((!(RpEnableMask & (0x1 << PortIndex))) && (PortIndex >= 4))) {
+ MmioOr8 ((RPBase + 0xE2), BIT0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xE2),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xE2)
+ );
+
+ MmioOr8 (RPBase + R_PCH_PCIE_RPDCGEN, B_PCH_PCIE_RPDCGEN_RPSCGEN);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN)
+ );
+ }
+ }
+ }
+ ///
+ /// Additional steps
+ /// If all PCIe root ports are disabled, set B0:D28:F0 + E1h[6] to 1b
+ ///
+ if ((RpEnableMask & 0x3F) == 0) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn(RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ 0
+ );
+ MmioOr8 (
+ RPBase + R_PCH_PCIE_RPDCGEN,
+ B_PCH_PCIE_RPDCGEN_POCGE
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN)
+ );
+ }
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, section 19.10
+ /// Step 2.3
+ /// Program D28:F0&F4:Reg E1h[5:2] to 1111b
+ ///
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex += 4) {
+ if (((RpHiddenMask & (1 << PortIndex)) == 0) && !(NandPort & (0x1 << PortIndex))) {
+ RPBase = MmPciAddress (
+ 0,
+ BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ GetPchPcieRpfn (RootComplexBar, (UINT8) PortIndex),
+ 0
+ );
+ Data8Or =
+ (
+ B_PCH_PCIE_RPDCGEN_LCLKREQEN |
+ B_PCH_PCIE_RPDCGEN_BBCLKREQEN |
+ B_PCH_PCIE_RPDCGEN_SRDLCGEN |
+ B_PCH_PCIE_RPDCGEN_SRDBCGEN
+ );
+ MmioOr8 (RPBase + R_PCH_PCIE_RPDCGEN, Data8Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, section 19.10
+ /// Step 2.4
+ /// If PCIe root ports 0-3 are all disabled, set B0:D28:F0 + E2h [0] = 1b and E1h [7] = 1b.
+ /// If PCIe root ports 4-7 are all disabled, set B0:D28:F4 + E2h [0] = 1b and E1h [7] = 1b.
+ ///
+ if (!(RpEnableMask & (0xF << PortIndex))) {
+ MmioOr8 ((RPBase + 0xE2), BIT0);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + 0xE2),
+ 1,
+ (VOID *) (UINTN) (RPBase + 0xE2)
+ );
+
+ MmioOr8 (RPBase + R_PCH_PCIE_RPDCGEN, B_PCH_PCIE_RPDCGEN_RPSCGEN);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN),
+ 1,
+ (VOID *) (UINTN) (RPBase + R_PCH_PCIE_RPDCGEN)
+ );
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c
new file mode 100644
index 0000000..56021ca
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSata.c
@@ -0,0 +1,1547 @@
+/** @file
+ Configures PCH Sata Controller
+
+@copyright
+ Copyright (c) 2008 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+
+EFI_STATUS
+ConfigureSataAhci (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar,
+ UINT16 GpioBase
+ );
+
+EFI_STATUS
+ConfigureSataSpeedIde (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINTN PciDevFuncRegBase,
+ UINTN MaxPorts
+ );
+
+EFI_STATUS
+DisableSataController (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN OUT UINT32 *FuncDisableReg
+ );
+
+/**
+ Configures PCH Sata Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in, out] FuncDisableReg Function Disable Register
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSata (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg,
+ IN UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINT16 WordReg;
+ UINT16 SataGcReg;
+ UINTN PciD31F2RegBase;
+ PCH_SATA_CONFIG *SataConfig;
+ UINT16 SataPortsEnabled;
+ UINT16 SataModeSelect;
+ UINTN PciD31F5RegBase;
+ UINTN PciDevFuncRegBase;
+ UINTN MaxPorts;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "ConfigureSata() Start\n"));
+
+ PchSeries = GetPchSeries();
+ SataConfig = PchPlatformPolicy->SataConfig;
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ PciD31F5RegBase = 0;
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 5, 0);
+ }
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ Status = EFI_SUCCESS;
+
+ ///
+ /// Check to disable SATA controller
+ ///
+ if (PchPlatformPolicy->DeviceEnabling->Sata == PCH_DEVICE_DISABLE) {
+ Status = DisableSataController (PchPlatformPolicy, FuncDisableReg);
+ return Status;
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 12
+ /// Program D31:F2:9Ch[5] to 1b (Note: this must be programmed together with D31:F2:9Ch[7:6]
+ /// in word write)
+ ///
+ SataGcReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_SCLKGC);
+ SataGcReg |= BIT5;
+
+ switch (SataModeSelect) {
+#ifdef TRAD_FLAG
+ case V_PCH_SATA_MAP_SMS_IDE:
+ if (PchSeries == PchH) {
+ ///
+ /// Set Native IDE decoding
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 14.1.3 Set the Programming Interface
+ /// Using native IDE is only possible when the SATA controller is operating in IDE mode.
+ /// The programming interface is selected by setting the programming interface register
+ /// (PI = Reg: 09h) appropriately. There are two native mode enabling bits in the
+ /// PI register to control the primary and secondary channels of SATA1.
+ ///
+ /// Only D31:F2 needs to be set. D31:F5 is readonly
+ ///
+ if (SataConfig->LegacyMode == PCH_DEVICE_ENABLE) {
+ MmioAnd8 (
+ PciD31F2RegBase + R_PCH_SATA_PI_REGISTER,
+ (UINT8)~(B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE)
+ );
+ } else {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PI_REGISTER,
+ (UINT8) B_PCH_SATA_PI_REGISTER_PNE | B_PCH_SATA_PI_REGISTER_SNE
+ );
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PI_REGISTER),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PI_REGISTER)
+ );
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMP), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_TIMP);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMP),
+ 1,
+ &WordReg
+ );
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMS), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_TIMS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_TIMS),
+ 1,
+ &WordReg
+ );
+ }
+ break;
+#endif // TRAD_FLAG
+
+ case V_PCH_SATA_MAP_SMS_RAID:
+ ///
+ /// When RAID alternate ID is enabled, the Device ID will change to 30XX from 282X in RAID mode
+ ///
+ if (SataConfig->RaidAlternateId == PCH_DEVICE_ENABLE) {
+ SataGcReg &= ~B_PCH_SATA_SCLKGC_AIES;
+ SataGcReg |= B_PCH_SATA_SCLKGC_AIE;
+ }
+#ifdef PCH_SVR_WS_SKU
+ SataGcReg &= ~B_PCH_SATA_SCLKGC_AIE;
+ SataGcReg |= B_PCH_SATA_SCLKGC_AIES;
+#endif
+ break;
+ }
+ ///
+ /// Unconditional write is necessary to lock the register
+ ///
+ MmioWrite16 (PciD31F2RegBase + R_PCH_SATA_SCLKGC, SataGcReg);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKGC),
+ 1,
+ &SataGcReg
+ );
+
+ ///
+ /// Set legacy IDE decoding
+ /// These bits also effect with AHCI mode when PCH is using legacy mechanisms.
+ ///
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMP), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_TIMP);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMP),
+ 1,
+ &WordReg
+ );
+
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMS), (UINT16) (B_PCH_SATA_TIM_IDE));
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_TIMS);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_TIMS),
+ 1,
+ &WordReg
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.2
+ /// D31:F2 PCS: Enable the port in any of below condition:
+ /// Hot plug is enabled
+ /// A device is attached
+ /// Test mode is enabled
+ /// Configured as eSATA port
+ ///
+ SataPortsEnabled = 0;
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if ((SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) ||
+ (WordReg & (BIT0 << (8 + Index))) ||
+ (SataConfig->TestMode == PCH_DEVICE_ENABLE) ||
+ (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE)) {
+ SataPortsEnabled |= (SataConfig->PortSettings[Index].Enable << Index);
+ }
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// D31:F5 PCS: Enable the port in any of below condition:
+ /// Hot plug is enabled
+ /// A device is attached
+ /// Test mode is enabled
+ ///
+ /// Note: In IDE mode, SATA Port 4/5 enable status needs to be checked before setting D31:F2 MAP[13:8].
+ /// It's because:
+ /// (1) SataPortsEnabled [5:4] will be set while it is configured as eSATA port that is not
+ /// supported in IDE mode.
+ /// (2) D31:F2 MAP[12] setting needs to sync up with D31:F5 MAP[8] setting.
+ /// D31:F2 MAP[13] setting needs to sync up with D31:F5 MAP[9] setting.
+ ///
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Clear SataPortsEnabled [5:4] before checking SATA Port 4/5 enable status
+ ///
+ SataPortsEnabled &= ~(BIT5 | BIT4);
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_PCS);
+ for (Index = 4; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// D31:F5 PCS[9:8] = Port 4/5 Present bit
+ ///
+ if ((SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) ||
+ (WordReg & (BIT0 << (4 + Index))) ||
+ (SataConfig->TestMode == PCH_DEVICE_ENABLE)) {
+ ///
+ /// SataPortsEnabled [5:4] = Sata Port 4/5 enable status
+ ///
+ SataPortsEnabled |= (SataConfig->PortSettings[Index].Enable << Index);
+ }
+ }
+ }
+ }
+
+ ///
+ /// Set MAP register for PCH H
+ /// Set D31:F2 MAP[13:8] to 1b if SATA Port 0/1/2/3/4/5 is disabled
+ /// SataPortsEnabled [5:0] = Sata Port 0/1/2/3/4/5 enable status
+ /// MAP.SPD (D31:F2:Reg90h[13:8]) is Write Once
+ ///
+ /// Set MAP register for PCH LP
+ /// Set D31:F2 MAP[11:8] to 1b if SATA Port 0/1/2/3 is disabled
+ /// SataPortsEnabled [3:0] = Sata Port 0/1/2/3 enable status
+ /// MAP.SPD (D31:F2:Reg90h[11:8]) is Write Once
+ ///
+ switch (PchSeries) {
+ case PchLp:
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 8) & (UINT16) B_PCH_LP_SATA_MAP_SPD));
+ break;
+
+ case PchH:
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 8) & (UINT16) B_PCH_H_SATA_MAP_SPD));
+ break;
+
+ default:
+ break;
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_MAP)
+ );
+
+ //
+ // D31:F2 PCS[5:0] = Port 0~5 Enabled bit
+ // as per SataPortsEnabled value.
+ //
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS), (UINT16) (SataPortsEnabled));
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ ///
+ /// Set D31:F5 MAP[9:8] and D31:F5 PCS[1:0]
+ ///
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Set D31:F5 MAP[9:8] to 1b if SATA Port 4/5 is disabled
+ /// SataPortsEnabled [5:4] = Sata Port 4/5 enable status
+ /// MAP.SPD (D31:F5:Reg90h[9:8]) is Write Once
+ ///
+ MmioOr16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP), ((~SataPortsEnabled << 4) & (UINT16) B_PCH_SATA2_MAP_SPD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_MAP)
+ );
+ ///
+ /// D31:F5 PCS[1:0] = Port 4/5 Enabled bit
+ ///
+ MmioAndThenOr16 (
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ (UINT16) (~(B_PCH_SATA2_PCS_PORT5_EN | B_PCH_SATA2_PCS_PORT4_EN)),
+ (UINT16) (SataPortsEnabled >> 4)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS)
+ );
+ }
+ }
+#endif // TRAD_FLAG
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.2
+ /// After configuring Port and Control Status (PCS) Register Port x Enabled (PxE) bits accordingly,
+ /// wait 1.4 micro second
+ ///
+ PchPmTimerStall (0x02);
+ SCRIPT_STALL (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, 0x02);
+
+ ///
+ /// After programming the PCS.PxE, check if it is zero.
+ /// If no port enabled, terminate the SATA configuration and disable the SATA controller.
+ ///
+ WordReg = MmioRead16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS));
+ WordReg &= (UINT16) ((1 << GetPchMaxSataPortNum ()) - 1);
+#ifdef TRAD_FLAG
+ if (WordReg == 0) {
+ if ((PchSeries == PchH) && (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE)) {
+ WordReg = MmioRead16 ((UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS));
+ WordReg &= (UINT16) (B_PCH_SATA2_PCS_PORT5_EN |
+ B_PCH_SATA2_PCS_PORT4_EN);
+ }
+ }
+#endif // TRAD_FLAG
+ if (WordReg == 0) {
+ Status = DisableSataController (PchPlatformPolicy, FuncDisableReg);
+ return Status;
+ }
+
+ if (PchSeries == PchLp) {
+ ///
+ /// If Listen Mode support is not required, program D31:F2:98h[24] to 1b.
+ ///
+ if ((SataConfig->PortSettings[0].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[1].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[2].HotPlug == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[3].HotPlug == PCH_DEVICE_DISABLE)) {
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x98), (UINT32) (BIT24));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + 0x98),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + 0x98)
+ );
+ }
+ }
+
+ ///
+ /// Configure AHCI
+ ///
+ if (PchSeries == PchLp) {
+ if (SataModeSelect != V_PCH_SATA_MAP_SMS_LOOBACK_TESTMODE) {
+ Status = ConfigureSataAhci (PchPlatformPolicy, RootComplexBar, GpioBase);
+ }
+ } else if (PchSeries == PchH) {
+ if (SataModeSelect != V_PCH_SATA_MAP_SMS_IDE) {
+ Status = ConfigureSataAhci (PchPlatformPolicy, RootComplexBar, GpioBase);
+ } else {
+ ///
+ /// If it is IDE mode
+ ///
+ if(PchPlatformPolicy->SataConfig->SpeedSupport != PchSataSpeedSupportDefault){
+ PciDevFuncRegBase = 0;
+ MaxPorts = 0;
+ for (Index = 0; Index < GetPchMaxSataControllerNum (); Index++) {
+ switch (Index) {
+ case 0:
+ PciDevFuncRegBase = PciD31F2RegBase;
+ MaxPorts = PCH_IDE_1_MAX_PORTS;
+ break;
+
+ case 1:
+ PciDevFuncRegBase = PciD31F5RegBase;
+ MaxPorts = PCH_IDE_2_MAX_PORTS;
+ break;
+ }
+ Status = ConfigureSataSpeedIde (PchPlatformPolicy, PciDevFuncRegBase, MaxPorts);
+ }
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, section 19.10
+ /// Step 4.1
+ /// Set bits D31:F2:Reg 94h[29:24] to 3Fh as part of the chipset initialization and before disabling the
+ /// SATA function if the SATA interface is not supported. BIOS can also set PCD bits for the un-routed ports
+ /// on the platform to disable clocks for the unused ports
+ /// Set the PCD [port x] = 1 if the corresponding PCS.PxE = 0 (either have a device attached or have
+ /// hot plug enabled)
+ ///
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG), (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD << Index));
+ }
+ }
+
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, 14.1.6 Power Optimizer Configuration
+ /// System BIOS must execute the following steps as part of System BIOS initialization
+ /// of the PCH SATA controller on both cold boot (G3/S5) and S3/S4 resume path. Please
+ /// refer to the PCH EDS, section 14.1.35.1 for the SATA initialization settings and
+ /// the actual register indexes/values to be programmed.
+ ///
+ if (PchPlatformPolicy->PwrOptConfig->PchPwrOptSata == PCH_DEVICE_ENABLE) {
+ ///
+ /// Step 1
+ /// Set D31:F2 + SIR Index 64h[31:0] = 883C9001h
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x64);
+ if (PchSeries == PchH) {
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x883C9001);
+ }
+ if (PchSeries == PchLp) {
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_STRD, 0x883C9003);
+ }
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 2
+ /// Set D31:F2 + SIR Index 68h[15:0] = 880Ah
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x68);
+ Data32And = 0xFFFF0000;
+ Data32Or = 0x0000880A;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 3
+ /// Set D31:F2 + SIR Index 60h[3] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFF7;
+ Data32Or = 0x00000008;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 4
+ /// Set D31:F2 + SIR Index 60h[0] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFFE;
+//for Denlow SVR, refer Inel doc 493798, c state communication
+#ifdef PCH_DENLOW_SERVER_SUPPORT
+ /// Set D31:F2 + SIR Index 60h[0] = 0b
+ Data32Or = 0x00000000;
+#else
+ Data32Or = 0x00000001;
+#endif
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ ///
+ /// Step 5
+ /// Set D31:F2 + SIR Index 60h[1] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x60);
+ Data32And = 0xFFFFFFFD;
+ Data32Or = 0x00000002;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SIRI)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD)
+ );
+ }
+
+#ifdef TRAD_FLAG
+ ///
+ /// For dual controller IDE mode, disable the individual controller if no port enabled.
+ /// For SATA2, the SATA configuration should be done through SATA1.
+ /// Therefore, disabling the SATA1/SATA2 after finishing SATA configuration.
+ ///
+ if (PchSeries == PchH) {
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ WordReg = MmioRead16 (PciD31F5RegBase + R_PCH_SATA_PCS);
+ WordReg &= (UINT16) (B_PCH_SATA2_PCS_PORT5_EN |
+ B_PCH_SATA2_PCS_PORT4_EN);
+ if (WordReg == 0) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA2;
+ }
+ WordReg = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_PCS);
+ WordReg &= (UINT16) (B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN);
+ if (WordReg == 0) {
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ }
+ }
+ }
+#endif // TRAD_FLAG
+
+ DEBUG ((EFI_D_INFO, "ConfigureSata() End\n"));
+
+ return Status;
+}
+
+/**
+ Program the Max speed suported in each ports while in IDE mode.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance.
+ @param[in] PciDevFuncRegBase Pci B/D/F/Reg Base for the Sata controler.
+ @param[in] MaxPorts Max Sata ports supported in the Controller.
+
+ @retval EFI_SUCESS The function exited sucessfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+**/
+EFI_STATUS
+ConfigureSataSpeedIde (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINTN PciDevFuncRegBase,
+ UINTN MaxPorts
+ )
+{
+ EFI_STATUS Status;
+#ifdef TRAD_FLAG
+ PCH_SATA_CONFIG *SataConfig;
+ EFI_PHYSICAL_ADDRESS IoBaseAddress;
+ UINT16 SidpBa;
+ UINT16 SidpBaSaveRestore;
+ UINT16 DevCmdSaveRestore;
+ UINT8 Data8;
+ UINT16 Data16;
+ UINTN PortIndex;
+
+ Data16 = 0;
+ Data8 = 0;
+
+ SataConfig = PchPlatformPolicy->SataConfig;
+
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAnySearchBottomUp,
+ EfiGcdIoTypeIo,
+ N_PCH_SATA_SIDP_BAR_ALIGNMENT,
+ V_PCH_SATA_SIDP_BAR_LENGTH,
+ &IoBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Set the SIDP BAR
+ ///
+ SidpBa = (UINT16) IoBaseAddress;
+ SidpBaSaveRestore = MmioRead16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR);
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR, SidpBa);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR),
+ 1,
+ &SidpBa
+ );
+ ///
+ /// Enable command register I/O space decoding
+ ///
+ DevCmdSaveRestore = MmioRead16 (PciDevFuncRegBase + R_PCH_SATA_COMMAND);
+ MmioOr16 ((UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND), (UINT16) B_PCH_SATA_COMMAND_IOSE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND)
+ );
+ ///
+ /// Configure for the max speed support 1.5Gb/s, 3.0Gb/s and 6.0Gb/s.
+ ///
+ for (PortIndex = 0; PortIndex < MaxPorts; PortIndex++) {
+ switch (PortIndex) {
+ case 0:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT0;
+ break;
+
+ case 1:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT1;
+ break;
+
+ case 2:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT2;
+ break;
+
+ case 3:
+ Data16 = V_PCH_SATA_AHCI_SINDX_RIDX_SCTL | V_PCH_SATA_AHCI_SINDX_PIDX_PORT3;
+ break;
+ }
+
+ IoWrite16 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SINDX), Data16);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SINDX),
+ 1,
+ &Data16
+ );
+
+ switch (SataConfig->SpeedSupport) {
+ case PchSataSpeedSupportGen1:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN1;
+ break;
+
+ case PchSataSpeedSupportGen2:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN2;
+ break;
+
+ case PchSataSpeedSupportGen3:
+ Data8 = V_PCH_SATA_SIDPBA_SDATA_GEN3;
+ break;
+ }
+
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ Data16 = MmioRead16 ((UINTN) (PciDevFuncRegBase + R_PCH_SATA_PCS)) >> 8;
+ if(((Data16 >> PortIndex) & BIT0)){
+ Data8 = (IoRead8 (SidpBa + R_PCH_SATA_SIDPBA_SDATA) & ~B_PCH_SATA_SIDPBA_SCTL_DET) + V_PCH_SATA_SIDPBA_SCTL_DET_COMRST;
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ PchPmTimerStall (1000);
+ SCRIPT_STALL (EFI_ACPI_S3_RESUME_SCRIPT_TABLE, 1000);
+ Data8 = (IoRead8 (SidpBa + R_PCH_SATA_SIDPBA_SDATA) & ~B_PCH_SATA_SIDPBA_SCTL_DET) + V_PCH_SATA_SIDPBA_SCTL_DET_NOINT;
+ IoWrite8 ((UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA), Data8);
+ SCRIPT_IO_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (SidpBa + R_PCH_SATA_SIDPBA_SDATA),
+ 1,
+ &Data8
+ );
+ }
+ }
+ ///
+ /// Restore command register I/O space decoding
+ ///
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_COMMAND, DevCmdSaveRestore);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_COMMAND),
+ 1,
+ &DevCmdSaveRestore
+ );
+ ///
+ /// Restore the SIDP BAR
+ ///
+ MmioWrite16 (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR, SidpBaSaveRestore);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciDevFuncRegBase + R_PCH_SATA_SIDP_BAR),
+ 1,
+ &SidpBaSaveRestore
+ );
+ ///
+ /// Free allocated resources
+ ///
+ gDS->FreeIoSpace (IoBaseAddress, (UINT64) V_PCH_SATA_SIDP_BAR_LENGTH);
+#else
+ Status = EFI_SUCCESS;
+#endif // TRAD_FLAG
+
+ return Status;
+}
+
+/**
+ Program AHCI PI register for Enabled ports
+ Handle hotplug, and interlock switch setting,
+ and config related GPIOs.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] GpioBase GPIO base address of this PCH device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureSataAhci (
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ UINT32 RootComplexBar,
+ UINT16 GpioBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemBaseAddress;
+ UINT32 AhciBar;
+ UINT32 CapRegister;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 DwordReg;
+ UINT32 PxCMDRegister;
+ UINT16 SataPortsEnabled;
+ UINT8 Index;
+ UINTN PciD31F2RegBase;
+ UINT16 WordReg;
+ UINT8 ByteReg;
+ PCH_SATA_CONFIG *SataConfig;
+ UINT16 SataModeSelect;
+ PCH_SERIES PchSeries;
+ UINT8 SataResetGpio[LPTH_AHCI_MAX_PORTS] = {
+ PCH_GPIO_SATA_PORT0_RESET,
+ PCH_GPIO_SATA_PORT1_RESET,
+ PCH_GPIO_SATA_PORT2_RESET,
+ PCH_GPIO_SATA_PORT3_RESET,
+ PCH_GPIO_SATA_PORT4_RESET,
+ PCH_GPIO_SATA_PORT5_RESET,
+ };
+
+ UINT16 SataResetLpGpio[LPTLP_AHCI_MAX_PORTS] = {
+ PCH_LP_GPIO_SATA_PORT0_RESET,
+ PCH_LP_GPIO_SATA_PORT1_RESET,
+ PCH_LP_GPIO_SATA_PORT2_RESET,
+ PCH_LP_GPIO_SATA_PORT3_RESET,
+ };
+
+ DEBUG ((EFI_D_INFO, "ConfigureSataAhci() Start\n"));
+ PchSeries = GetPchSeries();
+ SataConfig = PchPlatformPolicy->SataConfig;
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ DwordReg = 0;
+
+ ///
+ /// Allocate the AHCI BAR
+ ///
+ MemBaseAddress = 0x0ffffffff;
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_SATA_AHCI_BAR_ALIGNMENT, // 2^11: 2K Alignment
+ V_PCH_SATA_AHCI_BAR_LENGTH, // 2K Length
+ &MemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Set the AHCI BAR
+ ///
+ AhciBar = (UINT32) MemBaseAddress;
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR, AhciBar);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR),
+ 1,
+ &AhciBar
+ );
+
+ ///
+ /// Enable command register memory space decoding
+ ///
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND), (UINT16) B_PCH_SATA_COMMAND_MSE);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_COMMAND)
+ );
+
+ ///
+ /// Assert if the memory data of AhciBar is invalid.
+ ///
+ ASSERT (MmioRead32 (AhciBar) != 0xFFFFFFFF);
+
+ ///
+ /// Get Port Settings
+ ///
+ SataPortsEnabled = MmioRead16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS));
+ if (PchSeries == PchH) {
+ SataPortsEnabled &= (UINT16) (B_PCH_SATA_PCS_PORT5_EN |
+ B_PCH_SATA_PCS_PORT4_EN |
+ B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN );
+ } else if (PchSeries == PchLp) {
+ SataPortsEnabled &= (UINT16) (B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN );
+ }
+
+ ///
+ /// Read the default value of the Host Capabilites Register
+ /// NOTE: many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ CapRegister = MmioRead32 (AhciBar + R_PCH_SATA_AHCI_CAP);
+ CapRegister &= (UINT32)~(B_PCH_SATA_AHCI_CAP_SIS | B_PCH_SATA_AHCI_CAP_SSS | B_PCH_SATA_AHCI_CAP_SALP |
+ B_PCH_SATA_AHCI_CAP_PMS | B_PCH_SATA_AHCI_CAP_SSC | B_PCH_SATA_AHCI_CAP_PSC |
+ B_PCH_SATA_AHCI_CAP_SXS);
+ if (PchSeries == PchLp) {
+ CapRegister &= (UINT32)~(B_PCH_SATA_AHCI_CAP_SAM);
+ }
+
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// Check PCS.PxE to know if the SATA Port x is disabled.
+ ///
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ continue;
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// Program AhciBar + 0h[18] = 1b
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SAM;
+ }
+
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ ///
+ /// Mechanical Presence Switch is Enabled for at least one of the ports
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SIS;
+ }
+
+ if ((SataConfig->PortSettings[Index].SpinUp == PCH_DEVICE_ENABLE) ||
+ (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.4 Initialize Registers in AHCI Memory-Mapped Space
+ /// Step 1.4
+ /// Set SSS (ABAR + 00h[27]) to enable SATA controller supports staggered
+ /// spin-up on its ports, for use in balancing power spikes
+ /// SATA Port Spin up is supported at least one of the ports
+ /// If this is an extra eSATA port. It needs to be hotpluggable but it's usually empty anyway
+ /// so LPM is not available but Listen Mode is available, so it will have good power management.
+ /// If Sata Test Mode enabled, then uncoditonally clear SSS (ABAR + 00h[27])
+ /// to resolve Spin-donw issue with the test equiepment
+ ///
+ if (SataConfig->TestMode == PCH_DEVICE_ENABLE ) {
+ CapRegister &= ~B_PCH_SATA_AHCI_CAP_SSS;
+ } else {
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SSS;
+ }
+ }
+
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ ///
+ /// External SATA is supported at least one of the ports
+ ///
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SXS;
+ }
+ }
+ ///
+ /// Enable Enabled SATA ports,
+ /// If BIOS accesses any of the port specific AHCI address range before setting PI bit,
+ /// BIOS is required to read the PI register before the initial write to the PI register.
+ /// NOTE: many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ Data32And = (UINT32) (~B_PCH_H_SATA_PORT_MASK);
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32) (~B_PCH_LP_SATA_PORT_MASK);
+ }
+ Data32Or = (UINT32) (SataPortsEnabled);
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ Data32And,
+ Data32Or
+ );
+ SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // Data to be ORed
+ &Data32And // Data to be ANDed
+ );
+ ///
+ /// After BIOS issues initial write to this register, BIOS is requested to issue two
+ /// reads to this register.
+ ///
+ Data32Or = MmioRead32 (AhciBar + R_PCH_SATA_AHCI_PI);
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+ SCRIPT_MEM_POLL (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_PI),
+ &Data32Or, // BitMask
+ &Data32Or, // BitValue
+ 1, // Duration
+ 1 // LoopTimes
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.4 Initialize Registers in AHCI Memory-Mapped Space
+ /// Step 1
+ /// For Lynx Point
+ /// Set PSC (ABAR + 00h[13]). This bit informs the Windows software driver that the AHCI
+ /// Controller supports the partial low-power state.
+ /// Set SSC (ABAR + 00h[14]). This bit informs the Windows software driver that the AHCI
+ /// Controller supports the slumber low-power state.
+ /// Set SALP (ABAR + 00h[26]) to enable Aggressive Link Power Management (LPM) support.
+ ///
+ CapRegister |= (B_PCH_SATA_AHCI_CAP_SSC | B_PCH_SATA_AHCI_CAP_PSC);
+
+ if (SataConfig->SalpSupport == PCH_DEVICE_ENABLE) {
+ CapRegister |= B_PCH_SATA_AHCI_CAP_SALP;
+ }
+ ///
+ /// Support Command List Override & PIO Multiple DRQ Block
+ ///
+ CapRegister |= (B_PCH_SATA_AHCI_CAP_SCLO | B_PCH_SATA_AHCI_CAP_PMD);
+
+ ///
+ /// Configure for the max speed support 1.5Gb/s, 3.0Gb/s and 6.0Gb/s.
+ ///
+ CapRegister &= ~B_PCH_SATA_AHCI_CAP_ISS_MASK;
+
+ switch (SataConfig->SpeedSupport) {
+ case PchSataSpeedSupportGen1:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_1_5_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+
+ case PchSataSpeedSupportGen2:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_3_0_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+
+ case PchSataSpeedSupportGen3:
+ case PchSataSpeedSupportDefault:
+ CapRegister |= (V_PCH_SATA_AHCI_CAP_ISS_6_0_G << N_PCH_SATA_AHCI_CAP_ISS);
+ break;
+ }
+ ///
+ /// Update the Host Capabilites Register and save for S3 resume
+ /// NOTE: Many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ MmioWrite32 (AhciBar + R_PCH_SATA_AHCI_CAP, CapRegister);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP),
+ 1,
+ &CapRegister
+ );
+
+ if (PchSeries == PchLp) {
+ ///
+ /// Set ABAR + 24h[5] to 1b
+ /// Set ABAR + 24h[4:2] to 111b
+ ///
+ Data32Or = B_PCH_SATA_AHCI_CAP2_DESO;
+ Data32Or |= B_PCH_SATA_AHCI_CAP2_SDS | B_PCH_SATA_AHCI_CAP2_SADM | B_PCH_SATA_AHCI_CAP2_APST;
+ MmioOr32 (AhciBar + R_PCH_SATA_AHCI_CAP2, Data32Or);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP2),
+ 1,
+ (VOID *) (UINTN) (AhciBar + R_PCH_SATA_AHCI_CAP2)
+ );
+ }
+
+ ///
+ /// Port[Max:0] Command Register update
+ /// NOTE: this register must be updated after Port Implemented and Capabilities register,
+ /// Many of the bits in this register are R/WO (Read/Write Once)
+ ///
+ for (Index = 0; Index < GetPchMaxSataPortNum (); Index++) {
+ ///
+ /// Check PCS.PxE to know if the SATA Port x is disabled.
+ ///
+ if ((SataPortsEnabled & (B_PCH_SATA_PCS_PORT0_EN << Index)) == 0) {
+ continue;
+ }
+ ///
+ /// Initial to zero first
+ ///
+ PxCMDRegister = 0;
+
+ if (SataConfig->PortSettings[Index].HotPlug == PCH_DEVICE_ENABLE) {
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_DISABLE) {
+ ///
+ /// Hot Plug of this port is enabled
+ ///
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_HPCP;
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ ///
+ /// Mechanical Switch of this port is Attached
+ ///
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_MPSP;
+ ///
+ /// Check the GPIO Pin is set as used for native function not a normal GPIO
+ ///
+ if (PchSeries == PchH) {
+ DwordReg = IoRead32 (
+ (UINTN)
+ (GpioBase + R_PCH_GPIO_USE_SEL +
+ (SataResetGpio[Index] / 32 * (R_PCH_GPIO_USE_SEL2 - R_PCH_GPIO_USE_SEL))));
+ DwordReg = (DwordReg & (1 << SataResetGpio[Index] % 32));
+ }
+
+ if (PchSeries == PchLp) {
+ DwordReg = IoRead32 (
+ (UINTN)
+ (GpioBase + SataResetLpGpio[Index]));
+ DwordReg = (DwordReg & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+ }
+
+ if(DwordReg != 0) {
+ if (PchSeries == PchH) {
+ DEBUG ((EFI_D_ERROR,
+ "BIOS must set the SATA%0xGP / GPIO%0d to native function if Inter Lock Switch is enabled!\n",
+ Index,
+ SataResetGpio[Index]));
+ ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+ }
+
+ if (PchSeries == PchLp) {
+ DEBUG ((EFI_D_ERROR,
+ "BIOS must set the SATA%0xGP / GPIO%0d to native function if Inter Lock Switch is enabled!\n",
+ Index,
+ SataResetLpGpio[Index]));
+ ASSERT_EFI_ERROR (EFI_DEVICE_ERROR);
+ }
+ }
+ }
+ }
+ } else {
+ ///
+ /// When "Mechanical Switch Attached to Port" (PxCMD[19]) is set, it is expected that HPCP (PxCMD[18]) is also set.
+ ///
+ if (SataConfig->PortSettings[Index].InterlockSw == PCH_DEVICE_ENABLE) {
+ DEBUG ((EFI_D_ERROR, "Hot-Plug function of Port%d should be enabled while the Inter Lock Switch of it is enabled!\n",
+ Index));
+ }
+ }
+
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_ESP;
+ }
+
+ if (SataConfig->PortSettings[Index].SpinUp == PCH_DEVICE_ENABLE) {
+ PxCMDRegister |= B_PCH_SATA_AHCI_PxCMD_SUD;
+ }
+
+ ///
+ /// eSATA port support only up to Gen2
+ ///
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD);
+ Data32Or = (V_PCH_SATA_AHCI_PXSCTL_SPD_2);
+ if (PchSeries == PchLp) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PXSCTL_SPD | B_PCH_SATA_AHCI_PXSCTL_IPM);
+ Data32Or = (V_PCH_SATA_AHCI_PXSCTL_SPD_2);
+ }
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ Data32And,
+ Data32Or
+ );
+
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ }
+
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))),
+ (UINT32)~(B_PCH_SATA_AHCI_PxCMD_MASK),
+ (UINT32) PxCMDRegister
+ );
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0CMD + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ if ((PchSeries == PchLp)) {
+ ///
+ /// Set ABAR + 144h[1], ABAR + 1C4h[1], ABAR + 244h[1], ABAR + 2C4[1] to 0b as default
+ /// Board rework is required to enable DevSlp.
+ /// POR settings are ABAR + 144h[1], ABAR + 1C4h[1], ABAR + 244h[1] = 1b, ABAR + 2C4[1] to 0b
+ ///
+ if (SataConfig->PortSettings[Index].DevSlp == PCH_DEVICE_ENABLE) {
+ Data32And = (UINT32)~(B_PCH_SATA_AHCI_PxDEVSLP_DITO_MASK | B_PCH_SATA_AHCI_PxDEVSLP_DM_MASK);
+ Data32Or = (B_PCH_SATA_AHCI_PxDEVSLP_DSP | V_PCH_SATA_AHCI_PxDEVSLP_DM_16 | V_PCH_SATA_AHCI_PxDEVSLP_DITO_625);
+ if (SataConfig->PortSettings[Index].EnableDitoConfig == PCH_DEVICE_ENABLE) {
+ Data32Or &= Data32And;
+ Data32Or |= ((SataConfig->PortSettings[Index].DitoVal << 15) | (SataConfig->PortSettings[Index].DmVal << 25));
+ }
+ MmioAndThenOr32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ Data32And,
+ Data32Or
+ );
+ } else {
+ MmioAnd32 (
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ (UINT32) ~(B_PCH_SATA_AHCI_PxDEVSLP_DSP)
+ );
+ }
+ DwordReg = MmioRead32 (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index)));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0DEVSLP + (0x80 * Index))),
+ 1,
+ &DwordReg
+ );
+ }
+
+ ///
+ /// eSATA port support only up to Gen2.
+ /// Save and restore Port Speed limitation
+ ///
+ if (SataConfig->PortSettings[Index].External == PCH_DEVICE_ENABLE) {
+ ByteReg = MmioRead8 (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index)));
+ ByteReg &= (UINT8) ~(B_PCH_SATA_AHCI_PXSCTL_SPD);
+ ByteReg |= (UINT8) V_PCH_SATA_AHCI_PXSCTL_SPD_2;
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint8,
+ (UINTN) (AhciBar + (R_PCH_SATA_AHCI_P0SCTL + (0x80 * Index))),
+ 1,
+ &ByteReg
+ );
+ }
+ }
+ if ((PchSeries == PchLp)) {
+ ///
+ /// DevSlp on Port 0 and Port 3 are mutual exclusive. Assert if otherwise.
+ ///
+ ASSERT (!((SataConfig->PortSettings[0].DevSlp) && (SataConfig->PortSettings[3].DevSlp)));
+ if ((SataConfig->PortSettings[0].DevSlp == PCH_DEVICE_DISABLE) &&
+ (SataConfig->PortSettings[3].DevSlp == PCH_DEVICE_ENABLE)) {
+ MmioOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) B_PCH_SATA_SCLKCG_POP3_DEVSLP
+ );
+ DwordReg = MmioRead32 (PciD31F2RegBase + R_PCH_SATA_SCLKCG);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ &DwordReg
+ );
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.1.5.2 Enable Flexible RAID OROM Features
+ /// Lynx Point with RAID capable sku is able to customize the RAID features through setting the
+ /// Intel RST Feature Capabilities (RSTF) register before loading the RAID Option ROM. The RAID
+ /// OROM will enable the desired features based on the setting in that register, please refer to
+ /// PCH EDS for more details.
+ /// For example, if the platform desired features are RAID0, RAID1, RAID5, RAID10 and
+ /// RST Smart Storage caching. System BIOS should set RSTF (ABAR + C8h [15:0]) to 022Fh before
+ /// loading RAID OROM.
+ ///
+ WordReg = 0;
+
+ if (SataConfig->HddUnlock == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", indicates that the HDD password unlock in the OS is enabled
+ /// while SATA is configured as RAID mode.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_HDDLK;
+ }
+
+ if (SataConfig->LedLocate == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", indicates that the LED/SGPIO hardware is attached and ping to
+ /// locate feature is enabled on the OS while SATA is configured as RAID mode.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_LEDL;
+ }
+
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_RAID) {
+ if (SataConfig->Raid0 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID0 is enabled in Flexible RAID Option ROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R0E;
+ }
+
+ if (SataConfig->Raid1 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID1 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R1E;
+ }
+
+ if (SataConfig->Raid10 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID10 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R10E;
+ }
+
+ if (SataConfig->Raid5 == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then RAID5 is enabled in FD-OROM.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_R5E;
+ }
+
+ if (SataConfig->Irrt == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then Intel Rapid Recovery Technology is enabled.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_RSTE;
+ }
+
+ if (SataConfig->OromUiBanner == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1" then the OROM UI is shown. Otherwise, no OROM banner or information
+ /// will be displayed if all disks and RAID volumes are Normal.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_IRSTOROM;
+ }
+
+ if (SataConfig->IrrtOnly == PCH_DEVICE_ENABLE) {
+ ///
+ /// If set to "1", then only IRRT volumes can span internal and eSATA drives. If cleared
+ /// to "0", then any RAID volume can span internal and eSATA drives.
+ ///
+ WordReg |= B_PCH_SATA_AHCI_RSTF_IROES;
+ }
+ ///
+ /// Enable the RST Smart Storage caching bit to support Smart Storage caching.
+ ///
+ if (SataConfig->SmartStorage == PCH_DEVICE_ENABLE) {
+ WordReg |= B_PCH_SATA_AHCI_RSTF_SEREQ;
+ }
+ ///
+ /// Program the delay of the OROM UI Splash Screen in a normal status.
+ ///
+ WordReg |= (UINT16) (SataConfig->OromUiDelay << N_PCH_SATA_AHCI_RSTF_OUD);
+ }
+ ///
+ /// RSTF(RST Feature Capabilities) is a Write-Once register.
+ ///
+ MmioWrite16 ((UINTN) (AhciBar + R_PCH_SATA_AHCI_RSTF), WordReg);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (AhciBar + R_PCH_SATA_AHCI_RSTF),
+ 1,
+ &WordReg
+ );
+
+ ///
+ /// Set Ahci Bar to zero
+ ///
+ AhciBar = 0;
+ MmioWrite32 (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR, AhciBar);
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_AHCI_BAR),
+ 1,
+ &AhciBar
+ );
+
+ ///
+ /// Free the GCD pool
+ ///
+ gDS->FreeMemorySpace (
+ MemBaseAddress,
+ V_PCH_SATA_AHCI_BAR_LENGTH
+ );
+ DEBUG ((EFI_D_INFO, "ConfigureSataAhci() End\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable Sata Controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in, out] FuncDisableReg Function Disable Register
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+DisableSataController (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ UINTN PciD31F2RegBase;
+ UINTN PciD31F5RegBase;
+ UINT16 SataModeSelect;
+ PCH_SERIES PchSeries;
+
+ PciD31F2RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 2, 0);
+ PciD31F5RegBase = 0;
+ SataModeSelect = MmioRead16 (PciD31F2RegBase + R_PCH_SATA_MAP) & B_PCH_SATA_MAP_SMS_MASK;
+ PchSeries = GetPchSeries();
+
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.2 SATA Controller Disabling
+ /// Step 1
+ /// Set D31:F2:92h [3:0] to 0000b
+ ///
+ MmioAnd16 (PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT3_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+ ///
+ /// Step 3
+ /// Set Sata Port Clock Disable bits D31:F2:94h[27:24] to Fh
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD | B_PCH_SATA_SCLKCG_PORT1_PCD | B_PCH_SATA_SCLKCG_PORT2_PCD |
+ B_PCH_SATA_SCLKCG_PORT3_PCD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// Step 4
+ /// Disabling SATA Device by programming RCBA + 3418h [2][25]
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ }
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (0, PchPlatformPolicy->BusNumber, 31, 5, 0);
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 14.2 SATA Controller Disabling
+ /// Step 1
+ /// Set D31:F2:92h [5:0] to 000000b
+ ///
+ MmioAnd16 (PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT3_EN | B_PCH_SATA_PCS_PORT4_EN | B_PCH_SATA_PCS_PORT5_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS)
+ );
+ if (SataModeSelect == V_PCH_SATA_MAP_SMS_IDE) {
+ ///
+ /// Step 2
+ /// Set D31:F5:92h [1:0] to 00b if SATA is in IDE mode
+ ///
+ MmioAnd16 (PciD31F5RegBase + R_PCH_SATA_PCS,
+ (UINT16) ~(B_PCH_SATA_PCS_PORT0_EN | B_PCH_SATA_PCS_PORT1_EN));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS),
+ 1,
+ (VOID *) (UINTN) (PciD31F5RegBase + R_PCH_SATA_PCS)
+ );
+ }
+ ///
+ /// Step 3
+ /// Set Sata Port Clock Disable bits D31:F2:94h[29:24] to 3Fh
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ (UINT32) (B_PCH_SATA_SCLKCG_PORT0_PCD | B_PCH_SATA_SCLKCG_PORT1_PCD | B_PCH_SATA_SCLKCG_PORT2_PCD |
+ B_PCH_SATA_SCLKCG_PORT3_PCD | B_PCH_SATA_SCLKCG_PORT4_PCD | B_PCH_SATA_SCLKCG_PORT5_PCD));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ 1,
+ (VOID *) (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG)
+ );
+ ///
+ /// Step 4
+ /// Disabling SATA Device by programming RCBA + 3418h [2][25]
+ ///
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA1;
+ *FuncDisableReg |= B_PCH_RCRB_FUNC_DIS_SATA2;
+ }
+#endif // TRAD_FLAG
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c
new file mode 100644
index 0000000..16e23a6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchSerialIo.c
@@ -0,0 +1,997 @@
+/** @file
+ Initializes the PCH Serial IO Controllers.
+
+@copyright
+ Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+
+#ifdef SERIAL_IO_FLAG
+#include "PchAslUpdateLib.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (AcpiTable)
+
+
+
+#define SERIAL_IO_ADDRESS_AREA 0xFE101000;
+
+//
+// Resource Group Header
+//
+typedef struct {
+ UINT32 ResourceGroupLength;
+ UINT32 VendorId;
+ UINT32 SubVendorId;
+ UINT16 DeviceId;
+ UINT16 SubDeviceId;
+ UINT16 Revision;
+ UINT16 Reserved;
+ UINT32 SharedInfoLength;
+} EFI_ACPI_5_0_CSRT_RESOURCE_GROUP_HEADER;
+
+//
+// Resource Group1 Share Info
+//
+typedef struct {
+ UINT16 MajorVersion1;
+ UINT16 MinorVersion0;
+ UINT32 MmioBaseL;
+ UINT32 MmioBaseH;
+ UINT32 InterruptGSI;
+ UINT8 InterruptPolarity;
+ UINT8 InterruptMode;
+ UINT8 NumberofChannels;
+ UINT8 DMAAddressWidth;
+ UINT16 BaseRequestLine;
+ UINT16 NumberofHandshakeSignals;
+ UINT32 MaximumBlockTransferSize;
+} EFI_ACPI_5_0_RESOURCE_GROUP1_SHARED_INFO;
+
+//
+// Resource Descriptor Header
+//
+typedef struct {
+ UINT32 ResourceDescriptorLength;
+ UINT16 ResourceType;
+ UINT16 ResourceSubType;
+ UINT32 UID;
+} EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER;
+
+//
+// Core System Resources Table Structure (CSRT)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ EFI_ACPI_5_0_CSRT_RESOURCE_GROUP_HEADER ResourceGroup1;
+ EFI_ACPI_5_0_RESOURCE_GROUP1_SHARED_INFO ResourceGroup1SharedInfo;
+ EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER ControllerResourceDescriptor1;
+ EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER ChannelResourceDescriptor1[8];
+} EFI_ACPI_5_0_CORE_SYSTEM_RESOURCES_TABLE;
+
+typedef enum {
+ INDEX_DMA,
+ INDEX_I2C0,
+ INDEX_I2C1,
+ INDEX_SPI0,
+ INDEX_SPI1,
+ INDEX_UART0,
+ INDEX_UART1,
+ INDEX_SDIO,
+ MAX_SIO_INDEX
+} SIO_DEVICE;
+
+typedef struct {
+ UINT8 DevNum;
+ UINT8 FuncNum;
+ UINT32 DisableAddr;
+ UINT32 AcpiSwitchAddr;
+ UINT32 DeviceModeSwitchBit; // turns device into ACPI mode by hiding its PCI config space
+ UINT32 IrqModeSwitchBit; // turns device's interrupts into ACPI mode
+ UINT32 Signature;
+ UINT8 IrqPin;
+ UINT32 Bar0;
+ UINT32 Bar1;
+} SERIAL_IO_DEVICE_DESCRIPTOR;
+
+#define SERIAL_IO_DEVICE_QUANTITY 8
+
+SERIAL_IO_DEVICE_DESCRIPTOR SerialIoDevice [SERIAL_IO_DEVICE_QUANTITY] =
+{ {21, 0, 0xCE00AA07, 0xCB000240, BIT20, BIT21, EFI_SIGNATURE_32('S','D','M','A'), 2, 0xFE101000, 0xFE102000},
+ {21, 1, 0xCE00AA47, 0xCB000248, BIT20, BIT21, EFI_SIGNATURE_32('I','2','C','0'), 3, 0xFE103000, 0xFE104000},
+ {21, 2, 0xCE00AA87, 0xCB000250, BIT20, BIT21, EFI_SIGNATURE_32('I','2','C','1'), 3, 0xFE105000, 0xFE106000},
+ {21, 3, 0xCE00AAC7, 0xCB000258, BIT20, BIT21, EFI_SIGNATURE_32('S','P','I','0'), 3, 0xFE107000, 0xFE108000},
+ {21, 4, 0xCE00AB07, 0xCB000260, BIT20, BIT21, EFI_SIGNATURE_32('S','P','I','1'), 3, 0xFE109000, 0xFE10A000},
+ {21, 5, 0xCE00AB47, 0xCB000268, BIT20, BIT21, EFI_SIGNATURE_32('U','A','0','0'), 4, 0xFE10B000, 0xFE10C000},
+ {21, 6, 0xCE00AB87, 0xCB000270, BIT20, BIT21, EFI_SIGNATURE_32('U','A','0','1'), 4, 0xFE10D000, 0xFE10E000},
+ {23, 0, 0xCE00AE07, 0xCB000000, BIT4, BIT5, EFI_SIGNATURE_32('S','D','H','C'), 1, 0xFE110000, 0xFE112000}
+};
+
+EFI_STATUS
+InstallDmaAcpiTable (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+);
+
+BOOLEAN IsSerialIoDeviceEnabled (
+ SIO_DEVICE Device
+ )
+{
+ UINTN RegBase;
+ UINT32 VendorDeviceId;
+
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[Device].DevNum, SerialIoDevice[Device].FuncNum, 0);
+ VendorDeviceId = MmioRead32 (RegBase + R_PCH_LP_SERIAL_IO_VENDOR_ID);
+ if (VendorDeviceId == 0xFFFFFFFF) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+}
+
+/**
+ Disable Serial IO Controllers based on PchPlatformPolicy.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+VOID
+DisableSerialIoControllers (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 FunctionEnable[SERIAL_IO_DEVICE_QUANTITY];
+ UINTN Address;
+ UINT8 i;
+ BOOLEAN Func0Missing;
+
+ //
+ // Higher functions of a PCI device can't exist if there's no Function0
+ // This issue only applies in PCI mode, not in ACPI.
+ //
+ Func0Missing = PchPlatformPolicy->DeviceEnabling->SerialIoDma == PCH_DEVICE_DISABLE &&
+ PchPlatformPolicy->SerialIoConfig->SerialIoMode == PchSerialIoIsPci;
+
+ //
+ // DMA is useless without at least one SerialIo device
+ //
+ FunctionEnable[INDEX_DMA] = PchPlatformPolicy->DeviceEnabling->SerialIoDma &&
+ ( PchPlatformPolicy->DeviceEnabling->SerialIoI2c0 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoI2c1 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoSpi0 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoSpi1 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoUart0 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoUart1 ||
+ PchPlatformPolicy->DeviceEnabling->SerialIoSdio );
+
+ FunctionEnable[INDEX_I2C0] = PchPlatformPolicy->DeviceEnabling->SerialIoI2c0 && !Func0Missing;
+ FunctionEnable[INDEX_I2C1] = PchPlatformPolicy->DeviceEnabling->SerialIoI2c1 && !Func0Missing;
+ FunctionEnable[INDEX_SPI0] = PchPlatformPolicy->DeviceEnabling->SerialIoSpi0 && !Func0Missing;
+ FunctionEnable[INDEX_SPI1] = PchPlatformPolicy->DeviceEnabling->SerialIoSpi1 && !Func0Missing;
+ FunctionEnable[INDEX_UART0] = PchPlatformPolicy->DeviceEnabling->SerialIoUart0 && !Func0Missing;
+ FunctionEnable[INDEX_UART1] = PchPlatformPolicy->DeviceEnabling->SerialIoUart1 && !Func0Missing;
+ //
+ // SDIO doesn't care about DMA missing - it has its own device number
+ //
+ FunctionEnable[INDEX_SDIO] = PchPlatformPolicy->DeviceEnabling->SerialIoSdio;
+
+ DEBUG ((EFI_D_INFO, "DisableSerialIoControllers() Start\n"));
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.2 Disabling Serial IO Controllers
+ /// By default all controllers are enabled in hardware.
+ ///
+
+ for (i = 0; i < SERIAL_IO_DEVICE_QUANTITY; i++) {
+ if (FunctionEnable[i] == PCH_DEVICE_DISABLE) {
+ ///
+ /// Step 1
+ /// Set the Dx:Fx:84h[1:0] = 11b
+ ///
+ Address = MmPciAddress (0, 0, SerialIoDevice[i].DevNum, SerialIoDevice[i].FuncNum, R_PCH_LP_SERIAL_IO_PME_CTRL_STS);
+ MmioAndThenOr32WithScript(Address, (UINT32)~(B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST), BIT1 | BIT0 );
+ ///
+ /// Step 2
+ /// Program IOBP register CE00Axx7h[8] = 1b
+ ///
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[i].DisableAddr, (UINT32)~(BIT8), BIT8);
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "DisableSerialIoControllers() End\n"));
+}
+
+UINT8
+GetSerialIoIrqNumber(
+ UINT8 DeviceNumber,
+ UINT8 InterruptPin,
+ UINT8 InterruptMode
+)
+{
+ UINT32 IrqRoute;
+ UINT8 InterruptRoute;
+ UINT32 RootComplexBar;
+ UINT32 IrqRoutingRegister;
+
+ if (InterruptMode == PchSerialIoIsAcpi) {
+ //
+ // ACPI IRQs are wired to irq pins 5,6,7,13
+ //
+ switch(InterruptPin) {
+ case 0x1:
+ return 5;
+ break;
+ case 0x2:
+ return 6;
+ break;
+ case 0x3:
+ return 7;
+ break;
+ case 0x4:
+ return 13;
+ break;
+ case 0x0:
+ default:
+ return 0;
+ }
+ } else {
+ if(InterruptPin > 0) {
+ //
+ // PCI INTs are first routed to PIRQs according to R_PCH_RCRB_D21IR / R_PCH_RCRB_D23IR register
+ //
+ RootComplexBar = MmioRead32 (
+ MmPciAddress (0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_RCBA)
+ ) & B_PCH_LPC_RCBA_BAR;
+
+ if (DeviceNumber == 21) {
+ IrqRoutingRegister = R_PCH_RCRB_D21IR;
+ } else if (DeviceNumber == 23) {
+ IrqRoutingRegister = R_PCH_RCRB_D23IR;
+ } else {
+ ASSERT(FALSE);
+ return 0;
+ }
+ IrqRoute = MmioRead32 (RootComplexBar + IrqRoutingRegister);
+
+ InterruptRoute = ( IrqRoute >> (4* (InterruptPin-1) ) ) & 0x7;
+
+ //
+ // ...and PIRQs are wired to irq pins 16..23
+ // A 16, B 17, C 18, D 19, E 20, F 21, G 22, H 23
+ //
+ return (InterruptRoute + 16);
+ } else {
+ return 0;
+ }
+ }
+}
+
+
+/**
+ Update ASL definitions for SerialIo devices.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+UpdateSerialIoAcpiData (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+
+ EFI_STATUS Status;
+ UINTN RegBase;
+ UINT32 Data32;
+ UINT16 GpioBase;
+ UINT8 i;
+
+ Status = InitializePchAslUpdateLib();
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // ACPI code update for all devices
+ //
+ for (i=0; i<SERIAL_IO_DEVICE_QUANTITY; i++) {
+
+ if (!IsSerialIoDeviceEnabled(i)) {
+ continue;
+ }
+
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[i].DevNum, SerialIoDevice[i].FuncNum, 0);
+
+ Data32 = (MmioRead32(RegBase + R_PCH_LP_SERIAL_IO_BAR0) & B_PCH_LP_SERIAL_IO_BAR0_BAR);
+ UpdateResourceTemplateAslCode(SerialIoDevice[i].Signature,
+ EFI_SIGNATURE_32 ('R', 'B', 'U', 'F'),
+ AML_MEMORY32_FIXED_OP,
+ 1,
+ 0x04,
+ &Data32,
+ sizeof(Data32)
+ );
+ }
+
+ //
+ // Update GPIO device ACPI variables
+ //
+ RegBase = MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0);
+
+ GpioBase = (MmioRead16(RegBase + R_PCH_LPC_GPIO_BASE) & B_PCH_LPC_GPIO_BASE_BAR);
+
+ //
+ // Update _MIN[32:0] of the DWord Address Space Descriptor with GPIO BAR0
+ //
+ Data32 = (UINT32)GpioBase;
+ UpdateResourceTemplateAslCode((EFI_SIGNATURE_32 ('G', 'P', 'I', '0')),
+ (EFI_SIGNATURE_32 ('R', 'B', 'U', 'F')),
+ AML_DWORD_OP,
+ 1,
+ 0x0A,
+ &Data32,
+ sizeof(Data32)
+ );
+
+ //
+ // Update _MAX[32:0] of the DWord Address Space Descriptor with GPIO BAR0 + 3FFh
+ //
+ Data32 = (UINT32)GpioBase + 0x3FF;
+ UpdateResourceTemplateAslCode((EFI_SIGNATURE_32 ('G', 'P', 'I', '0')),
+ (EFI_SIGNATURE_32 ('R', 'B', 'U', 'F')),
+ AML_DWORD_OP,
+ 1,
+ 0x0E,
+ &Data32,
+ sizeof(Data32)
+ );
+
+
+ return Status;
+}
+
+/**
+ Hide PCI config space of Serial IO Controllers and do any final initialization.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PutSerialIoInAcpiMode (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ EFI_STATUS Status;
+ UINTN Bar1;
+ UINTN RegBase;
+ UINT32 Data32;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT8 i;
+
+ Status = EFI_SUCCESS;
+
+ Status = InitializePchAslUpdateLib();
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // ACPI code update for all devices
+ //
+ for (i=0; i<SERIAL_IO_DEVICE_QUANTITY; i++) {
+
+ if (!IsSerialIoDeviceEnabled(i)) {
+ continue;
+ }
+
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[i].DevNum, SerialIoDevice[i].FuncNum, 0);
+
+ Data32 = (MmioRead32(RegBase + R_PCH_LP_SERIAL_IO_BAR1) & B_PCH_LP_SERIAL_IO_BAR1_BAR);
+ UpdateResourceTemplateAslCode(EFI_SIGNATURE_32 ('S', 'I', 'R', 'C'),
+ EFI_SIGNATURE_32 ('B', 'U', 'F', ('1'+i)),
+ AML_MEMORY32_FIXED_OP,
+ 1,
+ 0x04,
+ &Data32,
+ sizeof(Data32)
+ );
+
+ Data32 = GetSerialIoIrqNumber(SerialIoDevice[i].DevNum, SerialIoDevice[i].IrqPin, PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode);
+ UpdateResourceTemplateAslCode(SerialIoDevice[i].Signature,
+ EFI_SIGNATURE_32 ('R', 'B', 'U', 'F'),
+ AML_INTERRUPT_DESC_OP,
+ 1,
+ 0x05,
+ &Data32,
+ sizeof(UINT8)
+ );
+
+ }
+
+ //
+ // Install DMA CSRT ACPI table as per ACPI5.0 spec
+ //
+ if(PchPlatformPolicy->DeviceEnabling->SerialIoDma == PCH_DEVICE_ENABLE) {
+ InstallDmaAcpiTable(PchPlatformPolicy);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.6 Enable Serial IO PCI Controllers ACPI Mode
+ ///
+
+ for (i = 0; i < SERIAL_IO_DEVICE_QUANTITY; i++) {
+ ///
+ /// Check if SerialIo device is present
+ ///
+ if (!IsSerialIoDeviceEnabled(i)) {
+ continue;
+ }
+
+ ///
+ /// Get BAR1 Address
+ ///
+ Bar1 = MmioRead32(
+ MmPciAddress (0,
+ PchPlatformPolicy->BusNumber,
+ SerialIoDevice[i].DevNum,
+ SerialIoDevice[i].FuncNum,
+ R_PCH_LP_SERIAL_IO_BAR1)
+ ) & B_PCH_LP_SERIAL_IO_BAR1_BAR;
+
+ ///
+ /// Step 1
+ /// Program Dx:Fx:04h[2:1] = 11b
+ /// (skipped - this was performed while assigning BARs)
+ ///
+
+ ///
+ /// Step 2
+ /// Program Dx:Fx to ACPI Mode
+ ///
+ Data32And = 0xFFFFFFFF;
+ Data32Or = SerialIoDevice[i].DeviceModeSwitchBit;
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[i].AcpiSwitchAddr, Data32And, Data32Or);
+
+ ///
+ /// Set D3Hot Power State via BAR1 Address, for all devices except DMA
+ ///
+ if(i != INDEX_DMA) {
+ Data32And = (UINT32) ~B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST;
+ Data32Or = B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST;
+
+ PCH_INIT_COMMON_SCRIPT_MEM_READ_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ Bar1 + R_PCH_LP_SERIAL_IO_PME_CTRL_STS,
+ &Data32Or,
+ &Data32And
+ );
+ }
+
+ }
+
+ return Status;
+}
+
+/**
+ Assigns MMIO addresses for SerialIO controllers from a predefined pool
+
+ @retval None
+**/
+EFI_STATUS
+AssignBARs (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+)
+{
+ EFI_PHYSICAL_ADDRESS Bar;
+ EFI_PHYSICAL_ADDRESS RegBase;
+ EFI_STATUS Status;
+ UINTN i;
+ UINT64 TotalSize;
+ UINT32 IrqNumber;
+
+ Bar = SERIAL_IO_ADDRESS_AREA;
+ TotalSize = 2 * ((SERIAL_IO_DEVICE_QUANTITY - 1) * V_PCH_LP_SERIAL_IO_BAR_SIZE + V_PCH_LP_SERIAL_SDIO_BAR_SIZE);
+
+ Status = gDS->AddMemorySpace (
+ EfiGcdMemoryTypeReserved,
+ Bar,
+ TotalSize,
+ 0
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeReserved,
+ N_PCH_LP_SERIAL_IO_BAR_ALIGNMENT,
+ TotalSize,
+ &Bar,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ for (i = 0; i < SERIAL_IO_DEVICE_QUANTITY; i++) {
+ if (!IsSerialIoDeviceEnabled(i)) {
+ continue;
+ }
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[i].DevNum, SerialIoDevice[i].FuncNum, 0);
+
+ MmioAndThenOr32WithScript(RegBase + R_PCH_LP_SERIAL_IO_BAR0, 0x0, SerialIoDevice[i].Bar0);
+ MmioAndThenOr32WithScript(RegBase + R_PCH_LP_SERIAL_IO_BAR1, 0x0, SerialIoDevice[i].Bar1);
+
+ MmioAndThenOr32WithScript(RegBase + R_PCH_LP_SERIAL_IO_COMMAND,
+ 0xFFFFFFFF,
+ B_PCH_LP_SERIAL_IO_COMMAND_BME | B_PCH_LP_SERIAL_IO_COMMAND_MSE
+ );
+ IrqNumber = GetSerialIoIrqNumber(SerialIoDevice[i].DevNum, SerialIoDevice[i].IrqPin, PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode);
+ MmioAndThenOr32WithScript(RegBase + R_PCH_PCIE_INTR, (UINT32)~B_PCH_PCIE_INTR_ILINE, IrqNumber);
+ }
+ return Status;
+
+}
+
+
+/**
+ Hides SerialIo controllers from Pci config space
+ This prevents BIOS Pci enumerator from assigning mmio resources
+ SerialIo controllers will receive addresses from a separate pool
+
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+VOID
+HideSerialIoDevices (
+ IN UINT32 RootComplexBar
+ )
+{
+ UINTN i;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+
+ for (i = 0; i < SERIAL_IO_DEVICE_QUANTITY; i++) {
+ Data32And = (UINT32) 0xFFFFFFFF;
+ Data32Or = (UINT32) SerialIoDevice[i].DeviceModeSwitchBit;
+
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[i].AcpiSwitchAddr, Data32And, Data32Or);
+ }
+}
+
+/**
+ Reveals SerialIo controllers' Pci config space
+ This allows BIOS to complete initialization for those devices
+
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+VOID
+RevealConfigSpace (
+ IN UINT32 RootComplexBar
+ )
+{
+ UINTN i;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+
+ for (i = 0; i < SERIAL_IO_DEVICE_QUANTITY; i++) {
+ Data32And = (UINT32)~(SerialIoDevice[i].DeviceModeSwitchBit);
+ Data32Or = (UINT32) 0x0;
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[i].AcpiSwitchAddr, Data32And, Data32Or);
+ }
+}
+
+
+/**
+ Configures Serial IO Controllers
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+EFI_STATUS
+ConfigureSerialIoDevices (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ UINT8 Index;
+ UINTN RegBase;
+ UINTN Bar0;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT8 i;
+
+ for (i = 0; i < INDEX_SDIO; i++) {
+ ///
+ /// Check if device is present
+ ///
+ if (!IsSerialIoDeviceEnabled(i)) {
+ continue;
+ }
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[i].DevNum, SerialIoDevice[i].FuncNum, 0);
+
+ Bar0 = MmioRead32 (RegBase + R_PCH_LP_SERIAL_IO_BAR0);
+
+ if(i != PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_DMA) {
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.3 Serial IO LTR Programming
+ /// Step 1: Program BAR0 + 808h[2] = 0b
+ /// Step 2: Program BAR0 + 804h[1:0] = 00b
+ /// Step 3: Program BAR0 + 804h[1:0] = 11b
+ ///
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_PPR_GEN, (UINT32)(~B_PCH_LP_SERIAL_IO_PPR_GEN_LTR_MODE), 0x0);
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_PPR_RST, (UINT32)(~(B_PCH_LP_SERIAL_IO_PPR_RST_FUNC | B_PCH_LP_SERIAL_IO_PPR_RST_APB)), 0);
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_PPR_RST, 0xFFFFFFFF, (UINT32)(B_PCH_LP_SERIAL_IO_PPR_RST_FUNC | B_PCH_LP_SERIAL_IO_PPR_RST_APB));
+
+ ///
+ /// Step 4
+ /// Program BAR0 + 814h with LTR value for each SerialIo controller
+ ///
+ MmioAndThenOr32WithScript(Bar0 + R_PCH_LP_SERIAL_IO_PPR_AUTO_LTR, 0, 0);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.7 Serial IO Power Management Programming
+ /// Step 4
+ /// Program IO Voltage Select for I2C0 & I2C1 as per platform policy
+ ///
+ if(i == PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_I2C0) {
+ if (PchPlatformPolicy->SerialIoConfig->I2c0VoltageSelect == PchSerialIoIs33V) {
+ MmioAndThenOr32WithScript(Bar0 + R_PCH_LP_SERIAL_IO_PPR_GEN, (UINT32)~(B_PCH_LP_SERIAL_IO_PPR_GEN_IO_VOLTAGE_SEL), 0);
+ } else {
+ MmioAndThenOr32WithScript(Bar0 + R_PCH_LP_SERIAL_IO_PPR_GEN, 0xFFFFFFFF, B_PCH_LP_SERIAL_IO_PPR_GEN_IO_VOLTAGE_SEL);
+ }
+ }
+
+ if(i== PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_I2C1) {
+ if (PchPlatformPolicy->SerialIoConfig->I2c1VoltageSelect == PchSerialIoIs33V) {
+ MmioAndThenOr32WithScript(Bar0 + R_PCH_LP_SERIAL_IO_PPR_GEN, (UINT32)~(B_PCH_LP_SERIAL_IO_PPR_GEN_IO_VOLTAGE_SEL), 0);
+ } else {
+ MmioAndThenOr32WithScript(Bar0 + R_PCH_LP_SERIAL_IO_PPR_GEN, 0xFFFFFFFF, B_PCH_LP_SERIAL_IO_PPR_GEN_IO_VOLTAGE_SEL);
+ }
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.4 Serial IO Interrupt Programming
+ /// Step 4
+ /// Program D21:Fx to PCI Interrupt Mode
+ ///
+ Data32And = (UINT32)~(SerialIoDevice[i].IrqModeSwitchBit);
+ if(PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode == PchSerialIoIsAcpi) {
+ Data32Or = SerialIoDevice[i].IrqModeSwitchBit;
+ } else {
+ Data32Or = 0x00;
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.7 Serial IO Power Management Programming
+ /// Step 5
+ /// Program D21:Fx FAB_PM_CAP_PRSNT_PORT0
+ ///
+ Data32Or |= BIT1;
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[i].AcpiSwitchAddr, Data32And, Data32Or);
+ }
+
+ ///
+ /// Check if SDIO device is present
+ ///
+ if (IsSerialIoDeviceEnabled(INDEX_SDIO)) {
+
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[INDEX_SDIO].DevNum, SerialIoDevice[INDEX_SDIO].FuncNum, 0);
+
+ Bar0 = MmioRead32 (RegBase + R_PCH_LP_SERIAL_IO_BAR0);
+
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_SDIO_SLAVE_DELAY_DDR50_MODE, 0, 0x00000306);
+
+
+ ///
+ /// PCH BIOS Spec Rev 0.3.0 Section 23.3 Serial IO LTR Programming
+ /// Step 5
+ /// Program BAR0 + 1008h[2] = 1b
+ ///
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_SDIO_PPR_GEN, 0xFFFFFFFF, B_PCH_LP_SERIAL_IO_SDIO_PPR_GEN_LTR_MODE);
+
+ ///
+ /// Step 6
+ /// Program BAR0 + 1010h = 0x00000000 for SDIO controller
+ ///
+ Data32And = 0x00000000;
+ MmioAndThenOr32WithScript (Bar0 + R_PCH_LP_SERIAL_IO_SDIO_PPR_SW_LTR, 0, 0);
+
+ ///
+ /// Program D23:F0 to PCI Interrupt Mode
+ ///
+ Data32And = (UINT32)~(SerialIoDevice[INDEX_SDIO].IrqModeSwitchBit);
+ if(PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode == PchSerialIoIsAcpi) {
+ Data32Or = SerialIoDevice[INDEX_SDIO].IrqModeSwitchBit;
+ } else {
+ Data32Or = 0x00;
+ }
+ ProgramIobpWithScript (RootComplexBar, SerialIoDevice[INDEX_SDIO].AcpiSwitchAddr, Data32And, Data32Or);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.7.0 Section 23.4 Serial IO Interrupt Programing
+ ///
+ if(PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode == PchSerialIoIsAcpi) {
+ ///
+ /// Enable ACPI IRQ for IRQ13, IRQ7, IRQ6, IRQ5 in RCRB
+ ///
+ Data32Or = (B_PCH_RCRB_INT_ACPIIRQEN_A13E | B_PCH_RCRB_INT_ACPIIRQEN_A7E | B_PCH_RCRB_INT_ACPIIRQEN_A6E | B_PCH_RCRB_INT_ACPIIRQEN_A5E);
+ MmioAndThenOr32WithScript((UINTN)(RootComplexBar + R_PCH_RCRB_INT_ACPIIRQEN), 0xFFFFFFFF, Data32Or);
+ }
+
+#ifdef ULT_FLAG
+ if (GetPchSeries() == PchLp) {
+ for (Index = 0; Index < (sizeof (PchSerialIoIntsLptLp) / sizeof (IOBP_MMIO_TABLE_STRUCT)); Index++) {
+ ///
+ /// Program IOBP register
+ ///
+ Data32And = PchSerialIoIntsLptLp[Index].AndMask;
+ Data32Or = PchSerialIoIntsLptLp[Index].OrMask;
+ ProgramIobpWithScript (RootComplexBar, PchSerialIoIntsLptLp[Index].Address, Data32And, Data32Or);
+ }
+ }
+#endif //ULT_FLAG
+
+ ///
+ /// PCH BIOS Spec Rev 0.3.0 Section 31.22.6 Serial IO Power Management Programming
+ /// Step 1
+ /// Program CB000154h[12,9:8,4:0] = 1001100011111b
+ ///
+ Data32And = (UINT32)~(BIT12 | BIT9 | BIT8 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+ Data32Or = (UINT32) (BIT12 | BIT9 | BIT8 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_6) {
+ if (PchPlatformPolicy->SerialIoConfig->Ddr50Support) {
+ Data32Or |= BIT6;
+ }
+ }
+
+ ProgramIobpWithScript (RootComplexBar, 0xCB000154, Data32And, Data32Or);
+
+ ///
+ /// Step 2
+ /// Programming done above
+ ///
+ /// Step 3
+ /// Program CB000180h[5:0] = 111111b
+ ///
+ Data32And = (UINT32)~(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+ Data32Or = (UINT32) (BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+ ProgramIobpWithScript (RootComplexBar, 0xCB000180, Data32And, Data32Or);
+
+#ifdef ULT_FLAG
+ if (GetPchSeries() == PchLp) {
+ ///
+ /// PCH BIOS Spec Rev 0.3.0 Section 23.8 Serial IO Snoop Programing
+ ///
+ for (Index = 0; Index < (sizeof (PchSerialIoSnoopLptLp) / sizeof (IOBP_MMIO_TABLE_STRUCT)); Index++) {
+ ///
+ /// Program IOBP register
+ ///
+ ProgramIobpWithScript (
+ RootComplexBar,
+ PchSerialIoSnoopLptLp[Index].Address,
+ PchSerialIoSnoopLptLp[Index].AndMask,
+ PchSerialIoSnoopLptLp[Index].OrMask
+ );
+ }
+ }
+#endif // ULT_FLAG
+
+ return EFI_SUCCESS;
+}
+
+VOID
+ConfigureSerialIoAtBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+ UINTN i;
+ UINT8 FunctionEnable[SERIAL_IO_DEVICE_QUANTITY];
+
+ if (PchPlatformPolicy->SerialIoConfig->SerialIoMode != PchSerialIoIsAcpi) {
+ return;
+ }
+
+ FunctionEnable[INDEX_I2C0] = PchPlatformPolicy->DeviceEnabling->SerialIoI2c0;
+ FunctionEnable[INDEX_I2C1] = PchPlatformPolicy->DeviceEnabling->SerialIoI2c1;
+ FunctionEnable[INDEX_SPI0] = PchPlatformPolicy->DeviceEnabling->SerialIoSpi0;
+ FunctionEnable[INDEX_SPI1] = PchPlatformPolicy->DeviceEnabling->SerialIoSpi1;
+ FunctionEnable[INDEX_UART0] = PchPlatformPolicy->DeviceEnabling->SerialIoUart0;
+ FunctionEnable[INDEX_UART1] = PchPlatformPolicy->DeviceEnabling->SerialIoUart1;
+ FunctionEnable[INDEX_SDIO] = PchPlatformPolicy->DeviceEnabling->SerialIoSdio;
+
+ for (i=INDEX_I2C0; i<MAX_SIO_INDEX; i++) {
+ if (!FunctionEnable[i]) {
+ continue;
+ }
+
+ ///
+ /// Set D3Hot Power State via BAR1 Address, for all devices except DMA
+ ///
+ if(i != INDEX_DMA) {
+ MmioAndThenOr32 (SerialIoDevice[i].Bar1 + R_PCH_LP_SERIAL_IO_PME_CTRL_STS,
+ (UINT32) ~B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST,
+ B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST
+ );
+ MmioRead32(SerialIoDevice[i].Bar1 + R_PCH_LP_SERIAL_IO_PME_CTRL_STS);
+ }
+ }
+}
+
+
+/**
+ Configures Serial IO Controllers after Pci Enum
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+EFI_STATUS
+ConfigureSerialIoBeforeBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+
+ RevealConfigSpace(RootComplexBar);
+ DisableSerialIoControllers(PchPlatformPolicy, RootComplexBar);
+ AssignBARs(PchPlatformPolicy);
+ ConfigureSerialIoDevices(PchPlatformPolicy, RootComplexBar);
+ UpdateSerialIoAcpiData(PchPlatformPolicy, RootComplexBar);
+
+ if (PchPlatformPolicy->SerialIoConfig->SerialIoMode == PchSerialIoIsAcpi) {
+ PutSerialIoInAcpiMode(PchPlatformPolicy, RootComplexBar);
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ConfigureSerialIo (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar
+ )
+{
+ HideSerialIoDevices(RootComplexBar);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallDmaAcpiTable (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+)
+{
+ UINTN AcpiTableKey;
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTable;
+ EFI_ACPI_5_0_CORE_SYSTEM_RESOURCES_TABLE *CoreSystemResourcesTable;
+ UINT64 Data64;
+ UINT32 Data32;
+ UINTN RegBase;
+ UINT8 Index;
+ EFI_STATUS Status;
+ UINT32 IrqNumber;
+
+ AcpiTable = NULL;
+ CoreSystemResourcesTable = NULL;
+ AcpiTableKey = 0;
+
+ //
+ // Locate ACPI support protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, &AcpiTable);
+ if( EFI_ERROR(Status) || AcpiTable == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Allocate Memory for Core System Resources Table
+ //
+ CoreSystemResourcesTable = AllocateZeroPool(sizeof(EFI_ACPI_5_0_CORE_SYSTEM_RESOURCES_TABLE));
+
+ if(CoreSystemResourcesTable == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CoreSystemResourcesTable->Header.Signature = EFI_SIGNATURE_32('C','S','R','T');
+ CoreSystemResourcesTable->Header.Length = sizeof(EFI_ACPI_5_0_CORE_SYSTEM_RESOURCES_TABLE);
+ CoreSystemResourcesTable->Header.Revision = 0x01;
+ CoreSystemResourcesTable->Header.Checksum = 0x00;
+ Data64 = EFI_SIGNATURE_64 ('I', 'N', 'T', 'L', 0, 0, 0, 0);
+ CopyMem (&CoreSystemResourcesTable->Header.OemId, &Data64, sizeof(CoreSystemResourcesTable->Header.OemId));
+ Data64 = EFI_SIGNATURE_64 ('H', 'S', 'W', 'U', 'L', 'T', '-', 'R');
+ CopyMem (&CoreSystemResourcesTable->Header.OemTableId, &Data64, sizeof(CoreSystemResourcesTable->Header.OemTableId));
+ CoreSystemResourcesTable->Header.OemRevision = 0x00000001;
+ CoreSystemResourcesTable->Header.CreatorId = EFI_SIGNATURE_32('I','N','T','L');
+ CoreSystemResourcesTable->Header.CreatorRevision = 0x20100528;
+
+ CoreSystemResourcesTable->ResourceGroup1.ResourceGroupLength = sizeof(EFI_ACPI_5_0_CORE_SYSTEM_RESOURCES_TABLE) - sizeof(EFI_ACPI_DESCRIPTION_HEADER);
+ CoreSystemResourcesTable->ResourceGroup1.VendorId = EFI_SIGNATURE_32('I','N','T','L');
+ CoreSystemResourcesTable->ResourceGroup1.SubVendorId = 0x00000000;
+ CoreSystemResourcesTable->ResourceGroup1.DeviceId = 0x9C60;
+ CoreSystemResourcesTable->ResourceGroup1.SubDeviceId = 0x0000;
+ CoreSystemResourcesTable->ResourceGroup1.Revision = 0x0001;
+ CoreSystemResourcesTable->ResourceGroup1.Reserved = 0x0000;
+ CoreSystemResourcesTable->ResourceGroup1.SharedInfoLength = 0x00000001C;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.MajorVersion1 = 0x001;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.MinorVersion0 = 0x000;
+
+ RegBase = MmPciAddress (0, 0, SerialIoDevice[INDEX_DMA].DevNum, SerialIoDevice[INDEX_DMA].FuncNum, 0);
+ Data32 = (MmioRead32(RegBase + R_PCH_LP_SERIAL_IO_BAR0) & B_PCH_LP_SERIAL_IO_BAR0_BAR);
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.MmioBaseL = Data32;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.MmioBaseH = 0x00000000;
+ //
+ // Match DMA interrupt value
+ //
+ IrqNumber = GetSerialIoIrqNumber(SerialIoDevice[INDEX_DMA].DevNum, SerialIoDevice[INDEX_DMA].IrqPin, PchPlatformPolicy->SerialIoConfig->SerialIoInterruptMode);
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.InterruptGSI = IrqNumber;
+
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.InterruptPolarity = 0x02;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.InterruptMode = 0x00;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.NumberofChannels = 0x08;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.DMAAddressWidth = 0x20;
+
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.BaseRequestLine = 0x0010;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.NumberofHandshakeSignals = 0x0010;
+ CoreSystemResourcesTable->ResourceGroup1SharedInfo.MaximumBlockTransferSize = 0x00000FFF;
+
+ CoreSystemResourcesTable->ControllerResourceDescriptor1.ResourceDescriptorLength = 0x0000000C;
+ CoreSystemResourcesTable->ControllerResourceDescriptor1.ResourceType = 0x0003;
+ CoreSystemResourcesTable->ControllerResourceDescriptor1.ResourceSubType = 0x0001;
+ CoreSystemResourcesTable->ControllerResourceDescriptor1.UID = 0x20495053;
+
+ Data32 = 0x30414843;
+ for(Index = 0; Index < 8; Index++) {
+ CoreSystemResourcesTable->ChannelResourceDescriptor1[Index].ResourceDescriptorLength = 0x0000000C;
+ CoreSystemResourcesTable->ChannelResourceDescriptor1[Index].ResourceType = 0x0003;
+ CoreSystemResourcesTable->ChannelResourceDescriptor1[Index].ResourceSubType = 0x0000;
+ CoreSystemResourcesTable->ChannelResourceDescriptor1[Index].UID = Data32;
+ Data32 += 0x1000000;
+ }
+ Status = AcpiTable->InstallAcpiTable (AcpiTable, CoreSystemResourcesTable, CoreSystemResourcesTable->Header.Length, &AcpiTableKey);
+ return Status;
+}
+
+
+
+#endif // SERIAL_IO_FLAG
+
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsb.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsb.c
new file mode 100644
index 0000000..ddf41a8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsb.c
@@ -0,0 +1,439 @@
+/** @file
+ Initializes PCH USB Controllers.
+
+@copyright
+ Copyright (c) 1999 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchInit.h"
+
+/**
+ Lock USB registers before boot
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy
+
+ @retval None
+**/
+VOID
+UsbInitBeforeBoot(
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+)
+{
+ EFI_STATUS Status;
+ UINT32 XhccCfg;
+ UINTN XhciPciMmBase;
+ UINT32 XhciMmioBase;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 PchSeries;
+ UINT16 OrgCommandWord;
+ BOOLEAN NeedGcdMemSpace;
+
+ Data32And = 0xFFFFFFFF;
+ Data32Or = 0x0;
+ NeedGcdMemSpace = FALSE;
+
+ if (PchPlatformPolicy->UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_OFF) {
+ return;
+ }
+
+ XhciPciMmBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+ XhciMmioBase = MmioRead32(XhciPciMmBase + R_PCH_XHCI_MEM_BASE) & ~(0x0F);
+ if(XhciMmioBase == 0){
+ ///
+ /// Allocate GCD mem space
+ ///
+ XhciMmioBase = 0xFFFFFFFF;
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_XHCI_MEM_ALIGN,
+ V_PCH_XHCI_MEM_LENGTH,
+ (EFI_PHYSICAL_ADDRESS *)&XhciMmioBase,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ NeedGcdMemSpace = TRUE;
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE, XhciMmioBase);
+ }
+ PchSeries = GetPchSeries();
+
+ ///
+ ///Restore xHCI MMIO Enable
+ ///
+ OrgCommandWord = MmioRead16 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER);
+ MmioOr16 (
+ XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER,
+ (UINT16) (B_PCH_XHCI_COMMAND_MSE | B_PCH_XHCI_COMMAND_BME)
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER)
+ );
+
+ ///
+ ///Restore xHCI BAR
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE)
+ );
+
+ if (PchSeries == PchH) {
+ ///
+ /// For LPT-H, Set xHCIBAR + 8144h[8, 7, 6] to 1b, 0b, 0b
+ ///
+ MmioAndThenOr32 (XhciMmioBase + 0x8144, (UINT32) ~(BIT7 | BIT6), (UINT32) (BIT8));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8144),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8144)
+ );
+ } else if (PchSeries == PchLp) {
+ ///
+ /// For LPT-LP, Set xHCIBAR + 8144h[8, 7, 6] to 1b, 1b, 1b
+ ///
+ MmioOr32 (XhciMmioBase + 0x8144, (UINT32) (BIT8 | BIT7 | BIT6));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x8144),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x8144)
+ );
+ ///
+ /// For LPT-LP, Set xHCIBAR + 816Ch[19:0] to 000E0038h
+ ///
+ Data32And = (UINT32) ~(0x000FFFFF);
+ Data32Or = (UINT32) (0x000E0038);
+ MmioAndThenOr32 (
+ (XhciMmioBase + 0x816C),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciMmioBase + 0x816C),
+ 1,
+ (VOID *) (UINTN) (XhciMmioBase + 0x816C)
+ );
+ ///
+ /// For LPT-LP, Set D20:F0:B0h[17,14,13] to 1b, 0b, 0b
+ ///
+ MmioAndThenOr32 (XhciPciMmBase + 0xB0, (UINT32) ~(BIT14 | BIT13), (UINT32) (BIT17));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + 0xB0),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0xB0)
+ );
+ }
+
+ ///
+ /// Set D20:F0:50h[28:0] to 0FCE2E5F for LPT-LP
+ /// Set D20:F0:50h[26:0] to 07886E9Fh for LPT-H B0 onward
+ ///
+ if (PchSeries == PchH) {
+ Data32And = (UINT32)~(0x07FFFFFF);
+ Data32Or = (UINT32) (0x07886E9F);
+ } else if (PchSeries == PchLp) {
+ Data32And = (UINT32) ~(0x1FFFFFFF);
+ Data32Or = (UINT32) (0x0FCE2E5F);
+ }
+ MmioAndThenOr32 (
+ (XhciPciMmBase + 0x50),
+ Data32And,
+ Data32Or
+ );
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + 0x50),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0x50)
+ );
+
+ if ((GetBootModeHob () == BOOT_ON_S4_RESUME) &&
+ (PchPlatformPolicy->UsbConfig->UsbPrecondition == PCH_DEVICE_ENABLE)) {
+ ///
+ /// For LPT-LP, Set xHCIBAR + 80E0[24] to 1h
+ ///
+ MmioOr32 (XhciMmioBase + 0x80E0, (UINT32) (BIT24));
+
+ ///
+ /// For LPT-LP, Set xHCIBAR + 80E0[24] to 0h
+ ///
+ MmioAnd32 (XhciMmioBase + 0x80E0, (UINT32) ~(BIT24));
+ }
+
+ ///
+ /// PCH BIOS Spec xHCI controller setup
+ /// Note:
+ /// D20:F0:40h is write once register.
+ /// Unsupported Request Detected bit is write clear
+ ///
+ XhccCfg = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_XHCC1);
+ XhccCfg &= (UINT32) ~(B_PCH_XHCI_XHCC1_URD);
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 13.2.4 Locking xHCI Register Settings
+ /// PCH BIOS Spec Locking xHCI Register settings
+ /// After xHCI is initialized, BIOS should lock the xHCI configuration registers to RO.
+ /// This prevent any unintended changes. There is also a lockdown feature for OverCurrent
+ /// registers. BIOS should set these bits to lock down the settings prior to end of POST.
+ /// 1. Set Access Control bit at D20:F0:40h[31] to 1b to lock xHCI register settings.
+ /// 2. Set OC Configuration Done bit at D20:F0:44h[31] to lock overcurrent mappings from
+ /// further changes.
+ ///
+ MmioOr32 (XhciPciMmBase + 0x44, (UINT32) (BIT31));
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + 0x44),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + 0x44)
+ );
+ XhccCfg |= (UINT32) (B_PCH_XHCI_XHCC1_ACCTRL);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_XHCC1, XhccCfg);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_XHCC1),
+ 1,
+ &XhccCfg
+ );
+
+ ///
+ ///restore xHCI original command byte
+ ///
+ MmioWrite16 ((XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER), OrgCommandWord);
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint16,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER)
+ );
+
+ if (NeedGcdMemSpace) {
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE, 0);
+ ///
+ ///clear xHCI BAR
+ ///
+ PCH_INIT_COMMON_SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE),
+ 1,
+ (VOID *) (UINTN) (XhciPciMmBase + R_PCH_XHCI_MEM_BASE)
+ );
+ ///
+ /// release GCD Mem space
+ ///
+ gDS->FreeMemorySpace (
+ XhciMmioBase,
+ V_PCH_XHCI_MEM_LENGTH
+ );
+ }
+
+}
+
+/**
+ Configures ports of the PCH USB3 (xHCI) controller
+ just before OS boot.
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+VOID
+ConfigureXhciAtBoot (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy
+ )
+{
+ UINTN PciD20F0RegBase;
+ UINT32 PortMask;
+
+ DEBUG ((EFI_D_INFO, "ConfigureXhciAtBoot() Start\n"));
+
+ PciD20F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicy->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0
+ /// When the BIOS does not have xHCI pre-boot software available:
+ /// Section 13.1.1.2 xHCI Enabled mode
+ /// BIOS should route the Ports to the EHCI controller and prior to OS boot
+ /// it should route the ports to the xHCI controller.
+ ///
+ if ((PchPlatformPolicy->UsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_ON) &&
+ (PchPlatformPolicy->UsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_DISABLE)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.2.6 Routing of switchable USB Ports to
+ /// xHCI Controller
+ /// Step 1
+ /// Done in GetXhciPortsNumber()
+ /// Step 2
+ /// Program D20:F0:D8h[5:0] to the value of xHCI D20:F0:DCh[5:0]
+ ///
+ PortMask = MmioRead32 (PciD20F0RegBase + R_PCH_XHCI_USB3PRM);
+
+ MmioAndThenOr32 (
+ PciD20F0RegBase + R_PCH_XHCI_USB3PR,
+ (UINT32)~B_PCH_XHCI_USB3PR_USB3SSEN,
+ PortMask
+ );
+ ///
+ /// Step 3
+ /// Program D20:F0:D0h[14:0] to the value of xHCI D20:F0:D4h[15:0]
+ ///
+ PortMask = MmioRead32 (PciD20F0RegBase + R_PCH_XHCI_USB2PRM);
+
+ MmioAndThenOr32 (
+ PciD20F0RegBase + R_PCH_XHCI_USB2PR,
+ (UINT32)~B_PCH_XHCI_USB2PR_USB2HCSEL,
+ PortMask
+ );
+ ///
+ /// Note: Registers USB3PR[5:0] and USB2PR[14:0] are located in SUS well so BIOS doesn't
+ /// need to restore them during S3 resume, but needs to restore corresponding mask
+ /// registers. For RapidStart resume from G3 state support, HC Switch driver will call
+ /// _OSC method to restore USB2PR and USB3PR.
+ }
+
+ DEBUG ((EFI_D_INFO, "ConfigureXhciAtBoot() End\n"));
+}
+
+/**
+ Configures PCH USB controller
+
+ @param[in] PchPlatformPolicy The PCH Platform Policy protocol instance
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+ @param[in, out] FuncDisableReg Function Disable Register
+
+ @retval EFI_INVALID_PARAMETER The parameter of PchPlatformPolicy is invalid
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ConfigureUsb (
+ IN DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy,
+ IN UINT32 RootComplexBar,
+ IN OUT UINT32 *FuncDisableReg
+ )
+{
+ EFI_STATUS Status;
+ UINT8 BusNumber;
+ PCH_USB_CONFIG *UsbConfig;
+ UINT32 UsbFuncDisable;
+ EFI_PHYSICAL_ADDRESS EhciMemBaseAddress;
+ EFI_PHYSICAL_ADDRESS XhciMemBaseAddress;
+
+ DEBUG ((EFI_D_INFO, "ConfigureUsb() Start\n"));
+
+ BusNumber = PchPlatformPolicy->BusNumber;
+ UsbConfig = PchPlatformPolicy->UsbConfig;
+ EhciMemBaseAddress = 0x0ffffffff;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_EHCI_MEM_ALIGN,
+ V_PCH_EHCI_MEM_LENGTH,
+ &EhciMemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ XhciMemBaseAddress = 0x0ffffffff;
+
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ N_PCH_XHCI_MEM_ALIGN,
+ V_PCH_XHCI_MEM_LENGTH,
+ &XhciMemBaseAddress,
+ mImageHandle,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+
+ gDS->FreeMemorySpace (
+ EhciMemBaseAddress,
+ V_PCH_EHCI_MEM_LENGTH
+ );
+
+ return Status;
+ }
+
+ UsbFuncDisable = *FuncDisableReg;
+
+ Status = CommonUsbInit (
+ UsbConfig,
+ (UINT32) EhciMemBaseAddress,
+ (UINT32) XhciMemBaseAddress,
+ BusNumber,
+ RootComplexBar,
+ &UsbFuncDisable,
+ PchPlatformPolicy->Revision
+ );
+ *FuncDisableReg = UsbFuncDisable;
+
+ //
+ // Free allocated resources
+ //
+ gDS->FreeMemorySpace (
+ EhciMemBaseAddress,
+ V_PCH_EHCI_MEM_LENGTH
+ );
+
+ gDS->FreeMemorySpace (
+ XhciMemBaseAddress,
+ V_PCH_XHCI_MEM_LENGTH
+ );
+ DEBUG ((EFI_D_INFO, "ConfigureUsb() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.c
new file mode 100644
index 0000000..ea8f794
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.c
@@ -0,0 +1,522 @@
+/** @file
+ PCH USB precondition feature support in DXE phase
+
+@copyright
+ Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInit.h"
+#include "PchUsbPrecondition.h"
+#include "PchUsbCommon.h"
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+//
+// Data referred by EHCI
+//
+extern USB_CONTROLLER EhciControllersMap[];
+
+//
+// Data referred by XHCI
+//
+UINTN *PORTSCxUSB2Ptr;
+UINTN *PORTSCxUSB3Ptr;
+
+//
+// Data referred by USB Precondition feature
+//
+EFI_USB_HC_PORT_PRECONDITION *mPrivatePreConditionList = NULL;
+
+//
+// This flag set when 50ms root port reset duration is satisified (Tdrstr). It is countered from
+// last root port reset.
+//
+BOOLEAN PchUsbRPortsRstDoneFlag = FALSE;
+
+//
+// All root ports reset continuously, so the reset starting time between first root port and last
+// root port should not exceed PCH ACPI timer High-to-Low transition frequency - 2.3435 seconds.
+//
+UINTN LastRPortResetTicks = 0;
+
+//
+// Tdrstr for all root portis satisfied as the following scenarios:
+//
+// |
+// |-> Reset all root ports of 1st HC, save tick_1 to LastRPortResetTicks
+// |
+// |-> Reset all root ports of 2nd HC, save tick_2 to LastRPortResetTicks
+// |
+// |-> IsRootPortReset () for is invoked by first call, wait until if delay for tick_2 is enough
+// | Set PchUsbRPortsRstDoneFlag = TRUE, return TRUE if the port is in the list
+// |
+// |-> IsRootPortReset () is invoked for the other HC, and PchUsbRPortsRstDoneFlag is set
+// | Return TRUE if the port is in the list
+//
+
+/**
+ Return current PCH PM1 timer value
+
+ @param[in] None
+
+ @retval PM1 timer value in 32 bit
+**/
+UINTN
+PchGetPchTimerTick (
+ VOID
+ )
+{
+ UINT16 AcpiBaseAddr;
+
+ AcpiBaseAddr = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ return IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+
+}
+
+/**
+ Check if the required delay condition is satisified
+ Note: The delay can't be larger than PCH ACPI timer High-to-Low
+ transition frequency - 2.3435 seconds.
+
+ @param[in] InitialTicks Initial PM1 tick value
+ @param[in] RequiredStallInUs Required delay in us
+
+ @retval TRUE The required delay is satisified
+ @retval FALSE The required delay is not satisified
+**/
+BOOLEAN
+UsbTimeout (
+ IN UINTN InitialTicks,
+ IN UINTN RequiredStallInUs
+ )
+{
+ UINTN CurrentTick;
+ UINTN ExpiredTick;
+
+ //
+ // The timer frequency is 3.579545 MHz, so 1 us corresponds 3.58 clocks
+ //
+ ExpiredTick = RequiredStallInUs * 358 / 100 + InitialTicks + 1;
+ CurrentTick = PchGetPchTimerTick ();
+
+ //
+ // The High-to-Low transition will occur every 2.3435 seconds.
+ //
+ if (CurrentTick < InitialTicks) {
+ CurrentTick += V_PCH_ACPI_PM1_TMR_MAX_VAL;
+ }
+
+ if (CurrentTick > ExpiredTick){
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/**
+ Initialize usb global data and flag for reference
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+UsbInitGlobalData (
+ VOID
+ )
+{
+
+ ///
+ /// Set the flag to false and start to count time.
+ ///
+ PchUsbRPortsRstDoneFlag = FALSE;
+
+ ///
+ /// This is the latest root port reset, record it to ensure the Tdrstr is satisified.
+ ///
+ LastRPortResetTicks = PchGetPchTimerTick();
+ return;
+}
+
+/**
+ Check if the delay is enough since last root port reset
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+UsbTdrstrDelayCheck (
+ VOID
+ )
+{
+ UINTN i;
+
+ ///
+ /// If the latest root port reset done, and then for all root ports reset by
+ /// this protocol is ready. If we are in scenario#3, wait until delay time is enough. The flag
+ /// is set either by timer event or the waitting loop.
+ ///
+ for (i = 0; (PchUsbRPortsRstDoneFlag != TRUE) && (i < USB_ROOT_PORT_RESET_STALL_US/ USB_TDRSTR_CHECK_INTERVAL_US); i++) {
+ if (UsbTimeout (LastRPortResetTicks, USB_ROOT_PORT_RESET_STALL_US)) {
+ PchUsbRPortsRstDoneFlag = TRUE;
+ LastRPortResetTicks = 0;
+ break;
+ }
+ PchPmTimerStall (USB_TDRSTR_CHECK_INTERVAL_US);
+ }
+
+ return ;
+}
+
+/**
+ Check if the queried port is reset by USB precondition feature or not
+
+ @param[in] This EFI_USB_HC_PORT_PRECONDITION instance
+ @param[in] PortNumber The root port number (started by zero) to be queried
+
+ @retval TRUE The root port is reset done
+ @retval FALSE The root port is not reset
+**/
+BOOLEAN
+EFIAPI
+IsEhcRootPortReset (
+ IN EFI_USB_HC_PORT_PRECONDITION *This,
+ IN UINT8 PortNumber
+ )
+{
+ USB_EHCI_PRECONDITION_DEV *EhcPreCondition;
+
+ EhcPreCondition = EHC_PRECONDITION_FROM_THIS (This);
+
+ ///
+ /// For the EHCI on PCH, the root port 0 is always RMH and existing.
+ /// PCH USB precondition feature resets the root port 0 on PCH EHCI only
+ /// If the signature, PortNumber, or PortResetBitMap is invalid, return
+ /// FALSE directly. Otherwise, return TRUE when required reset signal delay
+ /// is satisified.
+ ///
+ if ((EhcPreCondition->Signature != EHCI_PRECONDITION_DEV_SIGN) ||
+ (PortNumber != 0) ||
+ (EhcPreCondition->PortResetBitMap == 0)) {
+ return FALSE;
+ }
+
+ //
+ // Drive the reset signal on root port for at least 50ms(Tdrstr). Check USB 2.0 Spec
+ // section 7.1.7.5 for timing requirements.
+ //
+ if (!PchUsbRPortsRstDoneFlag) {
+ UsbTdrstrDelayCheck ();
+ }
+ return TRUE;
+}
+
+/**
+ Perform USB precondition on EHCI, it is the root port reset on
+ installed USB device in DXE phase
+
+ @param[in] Device The device number of the EHCI
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+
+ @retval None
+**/
+VOID
+EhciPrecondition (
+ IN UINT8 Device,
+ IN UINT32 EhciMmioBase
+ )
+{
+ UINTN i;
+ UINT32 Data32;
+ USB_EHCI_PRECONDITION_DEV *EhcPreCondition;
+ EFI_USB_HC_LOCATION EhcLocation = {0, 0, 0, 0};
+
+ //
+ // Check if all ports routed to this EHCI successfully, if not, exit directly
+ //
+ if ((MmioRead32 (EhciMmioBase + R_PCH_EHCI_CONFIGFLAG) & BIT0) == 0) {
+ return;
+ }
+
+ EhcPreCondition = AllocateZeroPool (sizeof (USB_EHCI_PRECONDITION_DEV));
+ if (EhcPreCondition == NULL) {
+ return;
+ }
+
+ ///
+ /// This is Intel RMH behind EHCI, and it is on root hub port 0. Reset the root hub port0.
+ ///
+ for (i = 0; i < (USB_HC_RESET_STALL_US/ 10); i++) {
+ if ((MmioRead32 (EhciMmioBase + R_PCH_EHCI_PORTSC0) & BIT0) == 0) {
+ //
+ // Root port 0 on EHCI is RMH, check the CCS bit before reset port.
+ // If the CCS bit is not true, wait and poll until timeout
+ //
+ PchPmTimerStall (10);
+ } else {
+ break;
+ }
+ }
+
+ Data32 = MmioRead32 (EhciMmioBase + R_PCH_EHCI_PORTSC0);
+
+ //
+ // Mask of the port change bits, they are WC (write clean).
+ // Set one to PortReset bit and must also set zero to PortEnable bit
+ //
+ Data32 &= ~B_PCH_EHCI_PORTSC0_CHANGE_ENABLE_MASK;
+ Data32 |= B_PCH_EHCI_PORTSC0_RESET;
+ MmioWrite32 ((EhciMmioBase + R_PCH_EHCI_PORTSC0), Data32);
+
+ UsbInitGlobalData ();
+ EhcPreCondition->Signature = EHCI_PRECONDITION_DEV_SIGN;
+
+ //
+ // RMH is at root hub port 0
+ //
+ EhcPreCondition->PortResetBitMap = BIT0;
+
+ //
+ // Suggest required delay time defined by specification per RMH implementation. Reserved so far
+ //
+ ZeroMem (&(EhcPreCondition->Protocol.Timing), sizeof (EFI_USB_PORT_ENUM_TIMING_TABLE));
+
+ EhcLocation.DeviceNumber = (UINTN) Device;
+ CopyMem (&(EhcPreCondition->Protocol.Location), &EhcLocation, sizeof (EFI_USB_HC_LOCATION));
+
+ EhcPreCondition->Protocol.IsRootPortReset = IsEhcRootPortReset;
+ EhcPreCondition->Protocol.Next = mPrivatePreConditionList;
+ mPrivatePreConditionList = &(EhcPreCondition->Protocol);
+}
+
+/**
+ Check if the queried port is reset by USB precondition feature or not. This service must be called when
+ XHC is in Run(R/S = '1') mode per XHCI specification requirement.
+
+ @param[in] This EFI_USB_HC_PORT_PRECONDITION instance
+ @param[in] PortNumber The root port number (started by zero) to be queried
+
+ @retval TRUE The root port is reset done
+ @retval FALSE The root port is not reset
+**/
+BOOLEAN
+EFIAPI
+IsXhcRootPortReset (
+ IN EFI_USB_HC_PORT_PRECONDITION *This,
+ IN UINT8 PortNumber
+ )
+{
+ UINT32 UsbPort;
+ UINT32 Data32;
+ UINT32 XhciMmioBase;
+ UINT32 XhciPciMmBase;
+ USB_XHCI_PRECONDITION_DEV *XhcPreCondition;
+ BOOLEAN ResumeFlag;
+
+ XhcPreCondition = XHC_PRECONDITION_FROM_THIS (This);
+
+ ///
+ /// If the signature, PortNumber, or PortResetBitMap is invalid, return
+ /// FALSE directly. Otherwise, return TRUE when required reset signal delay
+ /// is satisified.
+ ///
+ if ((XhcPreCondition->PortResetBitMap == 0) || (XhcPreCondition->Signature != XHCI_PRECONDITION_DEV_SIGN)) {
+ return FALSE;
+ }
+
+ ///
+ /// Resume all USB2 protocol ports by first call
+ ///
+ if (XhcPreCondition->PORTSCxResumeDoneFlag != TRUE) {
+ //
+ // Drive the reset signal on root port for at least 50ms(Tdrstr). Check USB 2.0 Spec
+ // section 7.1.7.5 for timing requirements.
+ //
+ if (!PchUsbRPortsRstDoneFlag) {
+ UsbTdrstrDelayCheck ();
+ }
+
+ XhciPciMmBase = (UINT32) MmPciAddress (
+ 0,
+ (UINT8) XhcPreCondition->Protocol.Location.BusNumber,
+ (UINT8) XhcPreCondition->Protocol.Location.DeviceNumber,
+ (UINT8) XhcPreCondition->Protocol.Location.FunctionNumber,
+ 0
+ );
+
+ XhciMmioBase = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE) & (~0xF);
+ ResumeFlag = FALSE;
+
+ ///
+ /// For USB2 protocol port on XHCI, the reset done port will enter U3 state once the HC is halted
+ /// To recovery the USB2 protocol port from U3 to U0, SW should:
+ /// 1. SW shall ensure that the XHC is in Run mode prior to transitioning a root hub port from Resume to
+ /// the U0 state.
+ /// 2. Write a "15" (Resume) to the PLS, XHC shall transmit the resume signaling within 1ms (Tursm)
+ /// 3. SW shall ensure that resume is signaled for at least 20 ms (Tdrsmdn) from the write of Resume
+ /// 4. After Tdrsmdn is complete, SW shall write a "0"(U0) to the PLS field
+ ///
+ for (UsbPort = 0; UsbPort < XhcPreCondition->HsPortCount; UsbPort++) {
+ if (((UINT32)(1 << UsbPort) & XhcPreCondition->PortResetBitMap) != 0) {
+ Data32 = MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]);
+ if ((Data32 & B_PCH_XHCI_PORTSCXUSB2_CCS) != 0) {
+ Data32 &= ~B_PCH_XHCI_PORT_CHANGE_ENABLE_MASK;
+ Data32 |= (B_PCH_XHCI_USB2_U3_EXIT + B_PCH_XHCI_PORTSCXUSB2_PP + B_PCH_XHCI_PORTSCXUSB2_LWS);
+ MmioWrite32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ Data32
+ );
+ ResumeFlag = TRUE;
+ } else {
+ //
+ // The CCS bit of this port disappears, it may be caused by the following reasons:
+ // 1. Link training is successfully now, the CCS shows on correct USB speed port, i.e. USB3
+ // speed if it is USB3 device.
+ // 2. The device is removed.
+ // Ignore this port due to there is no device on it now.
+ //
+ XhcPreCondition->PortResetBitMap &= ~(UINT32) (1 << UsbPort);
+ }
+ }
+ }
+
+ if (ResumeFlag) {
+ //
+ // There is one root port resuming from U3 at least.
+ //
+ PchPmTimerStall (20 * 1000);
+ for (UsbPort = 0; UsbPort < XhcPreCondition->HsPortCount; UsbPort++) {
+ if (((UINT32)(1 << UsbPort) & XhcPreCondition->PortResetBitMap) != 0 ) {
+ Data32 = (B_PCH_XHCI_PORTSCXUSB2_PP + B_PCH_XHCI_PORTSCXUSB2_LWS + B_PCH_XHCI_PORTSCXUSB2_CCS);
+ MmioWrite32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ Data32
+ );
+ }
+ }
+ }
+ XhcPreCondition->PORTSCxResumeDoneFlag = TRUE;
+ }
+
+ if (XhcPreCondition->PORTSCxResumeDoneFlag == TRUE) {
+ //
+ // If the signature, PortNumber, or PortResetBitMap is invalid, return
+ // FALSE directly. Otherwise, return TRUE when required reset signal delay
+ // is satisified.
+ //
+ if (((UINT32)(1 << PortNumber) & XhcPreCondition->PortResetBitMap) != 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Perform USB precondition on XHCI, it is the root port reset on
+ installed USB device in DXE phase
+
+ @param[in] BusNumber The Bus number of the XHCI
+ @param[in] Device The device number of the XHCI
+ @param[in] Function The function number of the XHCI
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciUSB2Ptr Pointer to USB2 protocol port register
+ @param[in] HsPortCount The number of USB2 protocol port supported by this XHCI
+
+ @retval None
+**/
+VOID
+XhciPrecondition (
+ IN UINT8 BusNumber,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 XhciMmioBase,
+ IN UINTN *XhciUSB2Ptr,
+ IN UINTN HsPortCount,
+ IN UINTN *XhciUSB3Ptr,
+ IN UINTN SsPortCount
+ )
+{
+ UINT32 UsbPort;
+ UINT32 Data32;
+ USB_XHCI_PRECONDITION_DEV *XhcPreCondition;
+ EFI_USB_HC_LOCATION XhcLocation = {0, 0, 0, 0};
+
+ XhcPreCondition = AllocateZeroPool (sizeof (USB_XHCI_PRECONDITION_DEV));
+ if (XhcPreCondition == NULL) {
+ return;
+ }
+
+ PORTSCxUSB2Ptr = XhciUSB2Ptr;
+ PORTSCxUSB3Ptr = XhciUSB3Ptr;
+ XhcPreCondition->Signature = XHCI_PRECONDITION_DEV_SIGN;
+
+ XhcPreCondition->HsPortCount = HsPortCount;
+
+ for (UsbPort = 0; UsbPort < HsPortCount; UsbPort++) {
+ Data32 = MmioRead32 (XhciMmioBase + PORTSCxUSB2Ptr[UsbPort]);
+ if ((Data32 & B_PCH_XHCI_PORTSCXUSB2_CCS) != 0) {
+ Data32 &= ~B_PCH_XHCI_PORTSCXUSB2_PED;
+ Data32 |= B_PCH_XHCI_PORTSCXUSB2_PR | B_PCH_XHCI_PORTSCXUSB2_PP;
+ MmioWrite32 (
+ XhciMmioBase + PORTSCxUSB2Ptr[UsbPort],
+ Data32
+ );
+ //
+ // PortSC registers in PCH XHCI is counted from HS ports
+ //
+ XhcPreCondition->PortResetBitMap |= (UINT32) (1 << UsbPort);
+ }
+ }
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "XhciPreconditionDxe - USB3PORTSC Start\n"));
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ DEBUG ((EFI_D_INFO, "USB3Port %x - %x\n", UsbPort, MmioRead32 (XhciMmioBase + XhciUSB3Ptr[UsbPort])));
+ }
+#endif
+
+ //
+ // Clear WRC bit for all USB3 PORTSC
+ //
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ MmioAndThenOr32 (
+ XhciMmioBase + PORTSCxUSB3Ptr[UsbPort],
+ (UINT32)~ (B_PCH_XHCI_PORTSCXUSB3_CHANGE_ENABLE_MASK),
+ B_PCH_XHCI_PORTSCXUSB3_WRC
+ );
+ }
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "XhciPreconditionDxe - USB3PORTSC Done\n"));
+ for (UsbPort = 0; UsbPort < SsPortCount; UsbPort++) {
+ DEBUG ((EFI_D_INFO, "USB3Port %x - %x\n", UsbPort, MmioRead32 (XhciMmioBase + XhciUSB3Ptr[UsbPort])));
+ }
+#endif
+ UsbInitGlobalData ();
+ XhcLocation.DeviceNumber = (UINTN) Device;
+ XhcLocation.FunctionNumber = (UINTN) Function;
+ CopyMem (&(XhcPreCondition->Protocol.Location), &XhcLocation, sizeof (EFI_USB_HC_LOCATION));
+ XhcPreCondition->Protocol.IsRootPortReset = IsXhcRootPortReset;
+ XhcPreCondition->PORTSCxResumeDoneFlag = FALSE;
+ XhcPreCondition->Protocol.Next = mPrivatePreConditionList;
+ mPrivatePreConditionList = &(XhcPreCondition->Protocol);
+}
+
+#endif // USB_PRECONDITION_ENABLE_FLAG
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.h
new file mode 100644
index 0000000..faaeda9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Dxe/PchUsbPrecondition.h
@@ -0,0 +1,54 @@
+/** @file
+ Header file for PCH USB precondition feature support in DXE phase
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _PCH_USB_PRECONDITION_H_
+#define _PCH_USB_PRECONDITION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchAccess.h"
+#include "UsbHcPortPrecondition.h"
+#endif
+
+#define USB_HC_RESET_STALL_US 10 * 1000 ///< 10ms
+#define USB_ROOT_PORT_RESET_STALL_US 50 * 1000 ///< 50ms
+#define USB_TDRSTR_CHECK_INTERVAL_US 100
+#define EHCI_PRECONDITION_DEV_SIGN EFI_SIGNATURE_32 ('e','p','r','e')
+#define EHC_PRECONDITION_FROM_THIS(a) CR(a, USB_EHCI_PRECONDITION_DEV, Protocol, EHCI_PRECONDITION_DEV_SIGN)
+
+typedef struct _USB_EHCI_PRECONDITION_DEV {
+ UINTN Signature;
+ EFI_USB_HC_PORT_PRECONDITION Protocol;
+ UINTN PortResetBitMap;
+} USB_EHCI_PRECONDITION_DEV;
+
+#define XHCI_PRECONDITION_DEV_SIGN EFI_SIGNATURE_32 ('x','p','r','e')
+#define XHC_PRECONDITION_FROM_THIS(a) CR(a, USB_XHCI_PRECONDITION_DEV, Protocol, XHCI_PRECONDITION_DEV_SIGN)
+
+typedef struct _USB_XHCI_PRECONDITION_DEV {
+ UINTN Signature;
+ EFI_USB_HC_PORT_PRECONDITION Protocol;
+ UINTN HsPortCount;
+ UINTN PortResetBitMap;
+ UINTN PortResetDoneBitMap;
+ BOOLEAN PORTSCxResumeDoneFlag;
+} USB_XHCI_PRECONDITION_DEV;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c
new file mode 100644
index 0000000..a53bf8b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchDmiPeim.c
@@ -0,0 +1,831 @@
+/** @file
+ This file contains functions for PCH DMI TC/VC programing and status polling
+
+@copyright
+ Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+// AMI_OVERRIDE >>>
+#ifdef AMI_RC_DEBUG
+#include "PeiLib.h"
+#endif
+// AMI_OVERRIDE <<<
+#include "PchInitPeim.h"
+#include "HeciRegs.h"
+#include "MeAccess.h"
+#include "ChipsetInitHob.h"
+
+//
+// GUID Definitions
+//
+EFI_GUID gChipsetInitHobGuid = CHIPSET_INIT_INFO_HOB_GUID;
+
+/**
+ Programing transaction classes of the corresponding virtual channel and Enable it
+
+ @param[in] RootComplexBar PCH Root Complex Base Address
+ @param[in] Vc The virtual channel number for programing
+ @param[in] VcId The Identifier to be used for this virtual channel
+ @param[in] VcMap The transaction classes are mapped to this virtual channel.
+ When a bit is set, this transaction class is mapped to the virtual channel
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PchSetDmiTcVcMapping (
+ IN UINT32 RootComplexBar,
+ IN UINT8 Vc,
+ IN UINT8 VcId,
+ IN UINT8 VcMap
+ )
+{
+ UINTN Address;
+ UINT32 VxCtlAnd;
+ UINT32 VxCtlOr;
+
+ Address = RootComplexBar;
+
+ VxCtlAnd = (UINT32) (~(B_PCH_RCRB_V1CTL_ID | V_PCH_RCRB_V1CTL_TVM_MASK));
+ VxCtlOr = (VcId << N_PCH_RCRB_V1CTL_ID) & B_PCH_RCRB_V1CTL_ID;
+ VxCtlOr |= VcMap;
+ VxCtlOr |= B_PCH_RCRB_V1CTL_EN;
+
+ switch (Vc) {
+ case DmiVcTypeVc0:
+ Address += R_PCH_RCRB_V0CTL;
+ break;
+
+ case DmiVcTypeVc1:
+ Address += R_PCH_RCRB_V1CTL;
+ break;
+
+ case DmiVcTypeVcp:
+ Address += R_PCH_RCRB_CIR2030;
+ break;
+
+ case DmiVcTypeVcm:
+ Address += R_PCH_RCRB_CIR2040;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MmioAndThenOr32 (Address, VxCtlAnd, VxCtlOr);
+ if ((Vc == DmiVcTypeVc1) || (Vc == DmiVcTypeVcp)) {
+ //
+ // Reads back for posted write to take effect
+ //
+ MmioRead32 (Address);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Polling negotiation status of the corresponding virtual channel
+
+ @param[in] RootComplexBar PCH Root Complex Base Address
+ @param[in] Vc The virtual channel number for programing
+
+ @retval EFI_INVALID_PARAMETER Invalid parameter.
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PchPollDmiVcStatus (
+ IN UINT32 RootComplexBar,
+ IN UINT8 Vc
+ )
+{
+ UINTN Address;
+
+ Address = RootComplexBar;
+
+ switch (Vc) {
+ case DmiVcTypeVc0:
+ Address += R_PCH_RCRB_V0STS;
+ break;
+
+ case DmiVcTypeVc1:
+ Address += R_PCH_RCRB_V1STS;
+ break;
+
+ case DmiVcTypeVcp:
+ Address += 0x2036;
+ break;
+
+ case DmiVcTypeVcm:
+ Address += 0x2046;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Wait for negotiation to complete
+ //
+ while ((MmioRead16 (Address) & B_PCH_RCRB_V1STS_NP) != 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The function performing TC/VC mapping program, and poll all PCH Virtual Channel
+ until negotiation completion
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+PchDmiTcVcProgPoll (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ PCH_DMI_TC_VC_PPI *PchDmiTcVcMapPpi;
+ UINT32 RootComplexBar;
+ UINT8 Index;
+ UINT8 VcMap[DmiVcTypeMax] = { 0 };
+
+ ///
+ /// Locate PchDmiTcVcMap Ppi
+ ///
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gPchDmiTcVcMapPpiGuid, 0, NULL, (VOID **)&PchDmiTcVcMapPpi);
+ ASSERT_EFI_ERROR (Status);
+ RootComplexBar = PCH_RCRB_BASE;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.5
+ /// Step 3.1
+ /// RCBA + Offset 50h[19] = 1b
+ /// Step 3.2
+ /// RCBA + Offset 50h[23:20] = 2h and RCBA + Offset 50h[17] = 1b,
+ /// ensure that D29/D26:F0:88h [2] = 0b (Done at PchMiscInit() on PchInitPeim.c)
+ ///
+ MmioAndThenOr32 (RootComplexBar + R_PCH_RCRB_CIR0050, (UINT32) (~0x00F00000), (UINT32) (0x00200000));
+
+ if (PchDmiTcVcMapPpi->DmiVc[DmiVcTypeVcp].Enable == PCH_DEVICE_ENABLE) {
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_CIR0050, BIT17 | BIT19);
+ }
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (RootComplexBar + R_PCH_RCRB_CIR0050);
+
+ ///
+ /// Step 3.3, Step 3.4, Step 3.5, Step 3,6, Set the TC/VC mappings
+ ///
+ for (Index = 0; Index < DmiTcTypeMax; Index++) {
+ DEBUG ((EFI_D_INFO, "TC:%0x VC:%0x!\n", Index, PchDmiTcVcMapPpi->DmiTc[Index].Vc));
+ VcMap[PchDmiTcVcMapPpi->DmiTc[Index].Vc] |= (BIT0 << Index);
+ }
+
+ for (Index = 0; Index < DmiVcTypeMax; Index++) {
+ DEBUG ((EFI_D_INFO, "VC:%0x VCID:%0x Enable:%0x!\n",Index, PchDmiTcVcMapPpi->DmiVc[Index].VcId, PchDmiTcVcMapPpi->DmiVc[Index].Enable));
+ if (PchDmiTcVcMapPpi->DmiVc[Index].Enable == PCH_DEVICE_ENABLE) {
+ PchSetDmiTcVcMapping (
+ RootComplexBar,
+ Index,
+ PchDmiTcVcMapPpi->DmiVc[Index].VcId,
+ VcMap[Index]
+ );
+ }
+ }
+ ///
+ /// Step 3.7
+ /// Set RCBA + Offset 50h[31] = 1b
+ /// Lock down the TC mapping if no further changes are required to bits [30:16]
+ ///
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_CIR0050, B_PCH_RCRB_CIR0_TCLOCKDN);
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (RootComplexBar + R_PCH_RCRB_CIR0050);
+
+ ///
+ /// Step 3.8
+ /// After both above and System Agent DMI TC/VC mapping are programmed,
+ /// poll VC negotiation pending status until is zero:
+ /// 3.8.1 RCBA + Offset 201Ah[1]
+ /// 3.8.2 RCBA + Offset 2026h[1]
+ /// 3.8.3 RCBA + Offset 2036h[1]
+ /// 3.8.4 RCBA + Offset 2046h[1]
+ ///
+ for (Index = 0; Index < DmiVcTypeMax; Index++) {
+ if (PchDmiTcVcMapPpi->DmiVc[Index].Enable == PCH_DEVICE_ENABLE) {
+ PchPollDmiVcStatus (RootComplexBar, Index);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The function set the Target Link Speed in PCH to DMI GEN 2.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchDmiGen2Prog (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+#ifdef TRAD_FLAG
+ UINT32 RootComplexBar;
+
+ if (GetPchSeries() == PchH) {
+ DEBUG ((EFI_D_INFO, "PchDmiGen2Prog() Start\n"));
+ RootComplexBar = PCH_RCRB_BASE;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.5
+ /// Step 2
+ /// Configure DMI Link Speed as early as possible
+ /// Step 2.1
+ /// Please refer to the System Agent BIOS Writer's Guide on Supported Link Speed
+ /// field in Link Capabilities register in CPU complex. (Done in SA code)
+ /// Step 2.2
+ /// If the Supported Link Speed in CPU complex is 0010b (Done in SA code)
+ /// and RCBA + Offset 21A4h[3:0] = 0010b
+ ///
+ if ((MmioRead32 (RootComplexBar + R_PCH_RCRB_LCAP) & B_PCH_RCRB_LCAP_MLS) == 0x02) {
+ ///
+ /// Step 2.2.1
+ /// Set RCBA + Offset 21B0h[3:0] = 0010b
+ ///
+ MmioAndThenOr8 (RootComplexBar + 0x21B0, (UINT8)~(BIT3 | BIT2 | BIT1 | BIT0), (UINT8) BIT1);
+ ///
+ /// Step 2.2.2
+ /// Please refer to the System Agent BIOS Writer's Guide to perform DMI Link Retrain after
+ /// configures new DMI Link Speed. (Done in SA code)
+ ///
+ }
+ DEBUG ((EFI_D_INFO, "PchDmiGen2Prog() End\n"));
+ }
+#endif // TRAD_FLAG
+}
+
+/**
+ The function program DMI miscellaneous registers.
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS The DMI required settings programmed correctly
+**/
+EFI_STATUS
+EFIAPI
+PchDmiMiscProg (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+ UINT32 RootComplexBar;
+ EFI_STATUS Status;
+ UINT16 LpcDeviceId;
+ UINTN PciD31F0RegBase;
+ UINTN PciD28F0RegBase;
+ UINTN PciD20F0RegBase;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT16 i;
+ UINT16 size;
+ UINT8 DeviceLaneOwner;
+ UINT32 StrpFuseCfg1;
+ UINT8 GbePort;
+#ifdef ULT_FLAG
+ UINTN RPBase;
+ UINT8 PortIndex;
+#endif // ULT_FLAG
+ PCH_SERIES PchSeries;
+ UINT8 PchSteppingValue;
+ UINT32 Msg;
+ UINT32 MsgTimeout;
+ UINT32 PchChipsetInitTableId;
+ UINT32 PchChipsetInitTableLength;
+ UINT8 *PchChipsetInitTable;
+ HECI_FWS_REGISTER MeHfs;
+ CHIPSET_INIT_INFO_HOB *ChipsetInitHob;
+ EFI_BOOT_MODE BootMode;
+#ifdef TRAD_FLAG
+ IOBP_MMIO_TABLE_STRUCT *PchDmiHsio;
+#endif // TRAD_FLAG
+ IOBP_MMIO_TABLE_STRUCT *PchUsb3Hsio;
+ IOBP_MMIO_TABLE_STRUCT *PchUsb3SharedHsio;
+ IOBP_MMIO_TABLE_STRUCT *PchGbeSharedHsio;
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RootComplexBar = PchPlatformPolicyPpi->Rcba;
+ PchChipsetInitTable = NULL;
+ PchChipsetInitTableLength = 0;
+ Msg = 0;
+ MsgTimeout = MAX_ME_MSG_ACK_TIMEOUT;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ PciD28F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,
+ 0
+ );
+ PciD20F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ PchSteppingValue = PchStepping();
+ //
+ // Get PchSeries and assign the appropriate ChipsetInit table
+ //
+ switch (PchSteppingValue) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ PchChipsetInitTable = PchChipsetInitTableLptLp_Bx;
+ PchChipsetInitTableLength = sizeof(PchChipsetInitTableLptLp_Bx);
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ PchChipsetInitTable = PchChipsetInitTableLptH_B0;
+ PchChipsetInitTableLength = sizeof(PchChipsetInitTableLptH_B0);
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ PchChipsetInitTable = PchChipsetInitTableLptH_Cx;
+ PchChipsetInitTableLength = sizeof(PchChipsetInitTableLptH_Cx);
+ break;
+#endif // TRAD_FLAG
+ default:
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+
+ //
+ // GetBoodMode, do not perform ChipsetInit check on S3 RESUME
+ //
+ Status = PeiServicesGetBootMode(&BootMode);
+ if(BootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Create Hob to send ChipsetInit table status to DXE phase.
+ //
+ DEBUG((EFI_D_INFO, "(Hsio) Creating HOB to adjust Hsio settings from DXE, if required.\n"));
+ Status = (**PeiServices).CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (CHIPSET_INIT_INFO_HOB),
+ &ChipsetInitHob
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize ChipsetInitHob
+ //
+ ChipsetInitHob->Header.Name = gChipsetInitHobGuid;
+ ChipsetInitHob->ChipsetInitTableLen = PchChipsetInitTableLength;
+ ChipsetInitHob->ChipsetInitTableUpdReq = 0;
+
+ //
+ // Set the Host To ME flag requestint the Hsio ChipsetInit Table Version applied by ME FW
+ //
+ HeciPciAndThenOr32(R_ME_H_GS, 0, (H2M_HSIO_MESSAGE | H2M_HSIO_CMD_GETHSIOVER));
+
+ //
+ // Wait for the acknowledge from the FW, once it completes data should be in the FWSTS register
+ // Wait max of 100ms for FW to acknowledge.
+ //
+ do {
+ //
+ // Delay 1us. Need to give some time for ME to respond.
+ //
+ PchPmTimerStall(1);
+ MeHfs.ul = HeciPciRead32(R_ME_HFS);
+ MsgTimeout--;
+ if (MsgTimeout == 0) {
+ DEBUG ((EFI_D_INFO, "(Hsio) ME FW failed to acknowledge the GETHsioVER command.\n"));
+ Status = EFI_TIMEOUT;
+ //
+ // Do not assert until a supporting ME FW is available
+ //
+ // ASSERT_EFI_ERROR(Status);
+ break;
+ }
+ } while (MeHfs.r.BiosMessageAck != M2H_HSIO_MSG_ACK);
+ if (MsgTimeout > 0) {
+ DEBUG ((EFI_D_INFO, "(Hsio) The GETHsioVER command was acknowledged by ME FW.\n"));
+ }
+
+ //
+ // If successfully got the ACK from ME, then the Hsio Version info should be in the FWSTATUS register
+ // Otherwise, just continue Hsio programming assuming the ChipsetInit settings programmed through other means.
+ //
+ if (Status == EFI_SUCCESS) {
+ //
+ // Receive the Hsio Version reported by ME FW.
+ //
+ Msg = HeciPciRead32(R_ME_HFS_5);
+ DEBUG((EFI_D_INFO, "(Hsio) ME Reported Hsio Version:%d CRC=0x%04X Response=%d us\n", (Msg>>16), (Msg&0xFFFF), MAX_ME_MSG_ACK_TIMEOUT - MsgTimeout));
+
+ //
+ // Send final message back to ME so that it can restore the FWSTS5 value (used for other messaging)
+ //
+ HeciPciAndThenOr32 (R_ME_H_GS, 0, H2M_HSIO_MESSAGE | H2M_HSIO_CMD_CLOSE);
+
+ //
+ // Get ChipsetInit table indentifier from the one found in the code
+ //
+ if(PchChipsetInitTable != NULL) {
+ PchChipsetInitTableId = *((UINT32*)PchChipsetInitTable);
+ DEBUG((EFI_D_INFO, "(Hsio) BIOS Hsio Version:%d CRC=0x%04X Length=%d bytes.\n", (PchChipsetInitTableId>>16),(PchChipsetInitTableId&0xFFFF), PchChipsetInitTableLength));
+
+ //
+ // If expected table id is not found, then skip the rest of the Hsio programming until it can be updated from DXE
+ //
+ if (Msg != PchChipsetInitTableId) {
+ //
+ // Pass the expected ChipsetInit table to the DXE code that will apply the settings to ME and reset.
+ //
+ ChipsetInitHob->ChipsetInitTableUpdReq = 1;
+ //
+ // Copy the ChipsetInit settings from local table into the HOB
+ //
+ if (sizeof(ChipsetInitHob->ChipsetInitTable) >= PchChipsetInitTableLength) {
+ CopyMem (ChipsetInitHob->ChipsetInitTable, PchChipsetInitTable, PchChipsetInitTableLength);
+ } else {
+ ASSERT(FALSE); // Table should always fit into HOB structure.
+ }
+
+ //
+ // Skip the Hsio programming, DMI setting in ChipsetInit table should be good enough to get through DMI init.
+ //
+ return Status;
+ }
+ } else {
+ ASSERT(FALSE);
+ }
+ }
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.5
+ /// Step 1.1
+ /// RCBA + Offset 2088h = 00109000h
+ ///
+ MmioWrite32 (
+ (RootComplexBar + R_PCH_RCRB_CIR2088),
+ 0x00109000
+ );
+ ///
+ /// Step 1.2
+ /// RCBA + offset 20ACh[30] = 1b
+ ///
+ MmioOr32 (RootComplexBar + R_PCH_RCRB_REC, BIT30);
+ if (PchSeries == PchH) {
+ ///
+ /// Step 1.3
+ /// Set RCBA + Offset 2340h[7:0] = 1Bh
+ ///
+ MmioWrite8 (RootComplexBar + 0x2340, 0x1B);
+ ///
+ /// Step 1.4
+ /// Set RCBA + Offset 2340h[23:16] = 3Ah
+ ///
+ Data32And = (UINT32) 0xFF00FFFF;
+ Data32Or = (UINT32) (0x3A << 16);
+
+ MmioAndThenOr32 (
+ RootComplexBar + 0x2340,
+ Data32And,
+ Data32Or
+ );
+ ///
+ /// Step 1.5
+ /// Program RCBA + Offset 2324[31:0] = 00854C74h
+ ///
+ MmioWrite32 (RootComplexBar + 0x2324, 0x00854C74);
+ }
+
+ ///
+ /// Program Hsio Setting
+ ///
+ DeviceLaneOwner = MmioRead8 (PciD28F0RegBase + 0x410);
+ StrpFuseCfg1 = MmioRead32 (PciD28F0RegBase + R_PCH_PCIE_STRPFUSECFG);
+#ifdef TRAD_FLAG
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 7.1.5
+ /// Step 6
+ /// Bios is required to program IOBP setting according to the following table:
+ /// Table 7-10 DMI Lane Setting
+ ///
+ if (PchSeries == PchH) {
+ switch (PchSteppingValue) {
+ case LptHB0:
+ size = (sizeof (PchDmiHsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchDmiHsio = PchDmiHsioLptH_B0;
+ break;
+ default:
+ PchDmiHsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchDmiHsio[i].Address,
+ PchDmiHsio[i].AndMask,
+ PchDmiHsio[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+#endif // TRAD_FLAG
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 7.1.5
+ /// Table 7-3 USB3 dedicated lane Setting
+ ///
+ switch (PchSteppingValue) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchUsb3HsioLptLp_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3Hsio = PchUsb3HsioLptLp_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ size = (sizeof (PchUsb3HsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3Hsio = PchUsb3HsioLptH_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchUsb3HsioLptH_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3Hsio = PchUsb3HsioLptH_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ PchUsb3Hsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchUsb3Hsio[i].Address,
+ PchUsb3Hsio[i].AndMask,
+ PchUsb3Hsio[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 7.1.5
+ /// Table 7-5 USB3 Shared laneSetting
+ ///
+ switch (PchSteppingValue) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchUsb3SharedHsioLptLp_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3SharedHsio = PchUsb3SharedHsioLptLp_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ size = (sizeof (PchUsb3SharedHsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3SharedHsio = PchUsb3SharedHsioLptH_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchUsb3SharedHsioLptH_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchUsb3SharedHsio = PchUsb3SharedHsioLptH_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ PchUsb3SharedHsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ if (PchSeries == PchLp) {
+ if ((((PchUsb3SharedHsio[i].Address & 0xFE00) == 0x2400) && ((DeviceLaneOwner & (BIT1 | BIT0)) != BIT1)) ||
+ (((PchUsb3SharedHsio[i].Address & 0xFE00) == 0x2600) && ((DeviceLaneOwner & (BIT3 | BIT2)) != BIT3))) {
+ continue;
+ }
+ } else if (PchSeries == PchH) {
+ if ((((PchUsb3SharedHsio[i].Address & 0xFE00) == 0x2C00) && ((DeviceLaneOwner & (BIT3 | BIT2)) != BIT3)) ||
+ (((PchUsb3SharedHsio[i].Address & 0xFE00) == 0x2E00) && ((DeviceLaneOwner & (BIT1 | BIT0)) != BIT1))) {
+ continue;
+ }
+ }
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchUsb3SharedHsio[i].Address,
+ PchUsb3SharedHsio[i].AndMask,
+ PchUsb3SharedHsio[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ ///
+ /// Table 7-9 Gbe Lane Setting
+ /// Bios should check the PCIE port that is assigned to Gbe and program the following address accordingly
+ ///
+ switch (PchSteppingValue) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ PchGbeSharedHsio = PchGbeSharedHsioLptLp_Bx;
+ size = (sizeof (PchGbeSharedHsioLptLp_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ PchGbeSharedHsio = PchGbeSharedHsioLptH_B0;
+ size = (sizeof (PchGbeSharedHsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ PchGbeSharedHsio = PchGbeSharedHsioLptH_Cx;
+ size = (sizeof (PchGbeSharedHsioLptH_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ break;
+#endif // TRAD_FLAG
+ default:
+ PchGbeSharedHsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+
+
+ if (PchGbeSharedHsio != NULL) {
+ if ((StrpFuseCfg1 & B_PCH_PCIE_STRPFUSECFG_GBE_PCIE_PEN) != 0) {
+ GbePort = (UINT8) ((StrpFuseCfg1 & B_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL) >> N_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL);
+ } else {
+ GbePort = 0xFF;
+ }
+
+ if (GbePort != 0xFF) {
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ if (GbePort <= 0x5) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchGbeSharedHsio[GbePort].Address,
+ PchGbeSharedHsio[GbePort].AndMask,
+ PchGbeSharedHsio[GbePort].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ if (GbePort == 0x0) {
+ if ((DeviceLaneOwner & (BIT1 | BIT0)) == BIT0) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchGbeSharedHsio[GbePort].Address,
+ PchGbeSharedHsio[GbePort].AndMask,
+ PchGbeSharedHsio[GbePort].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else if (GbePort == 0x1) {
+ if ((DeviceLaneOwner & (BIT3 | BIT2)) == BIT2) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchGbeSharedHsio[GbePort].Address,
+ PchGbeSharedHsio[GbePort].AndMask,
+ PchGbeSharedHsio[GbePort].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchGbeSharedHsio[GbePort].Address,
+ PchGbeSharedHsio[GbePort].AndMask,
+ PchGbeSharedHsio[GbePort].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+#endif // TRAD_FLAG
+ }
+ }
+ ///
+ /// Step 7
+ /// For LP, clear B0:D28:F0~F7:110h[13, 12, 8:6, 0] = 1b, 1b, 111b, 1b
+ /// For LP, clear B0:D28:F0~F7:104h[20, 18:14, 12, 4] = 1b, 11111b, 1b, 1b
+ ///
+#ifdef ULT_FLAG
+ if (GetPchSeries() == PchLp) {
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ RPBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ PortIndex,
+ 0
+ );
+ MmioOr32 (RPBase + R_PCH_PCIE_CES, (UINT32)(B_PCH_PCIE_CES_ANFES | B_PCH_PCIE_CES_RTT |
+ B_PCH_PCIE_CES_RNR | B_PCH_PCIE_CES_BD |
+ B_PCH_PCIE_CES_BT | B_PCH_PCIE_CES_RE));
+ MmioOr32 (RPBase + R_PCH_PCIE_UES, (UINT32)(B_PCH_PCIE_UES_URE | B_PCH_PCIE_UES_MT |
+ B_PCH_PCIE_UES_RO | B_PCH_PCIE_UES_UC |
+ B_PCH_PCIE_UES_CA | B_PCH_PCIE_UES_CT |
+ B_PCH_PCIE_UES_PT | B_PCH_PCIE_UES_DLPE));
+ }
+ }
+#endif //ULT_FLAG
+
+ ///
+ /// Step 8
+ /// Bios is required to program IOBP setting according to the table 7-7 to 7-8
+ /// using 7.1.4 IOSF SBI with OPCODE "PHY Configuration Register".
+ /// Done in PchSataInit().
+ ///
+ /// PCH BIOS Spec Rev 0.5.1, Section 7.1.5
+ /// Step 9
+ /// IOBP Programming:
+ /// For Mobile:
+ /// BIOS is required to program IOBP setting according to Table 7-11 and
+ /// Table 7-12 using settings in Section 7.1.4 with OPCODE "PHY Configuration Register".
+ /// For Desktop:
+ /// BIOS is required to program IOBP setting according to Table 7-13 and
+ /// Table 7-14 using settings in Section 7.1.4 with OPCODE "PHY Configuration Register".
+ /// Done in PchSataInit().
+ ///
+ /// Step 10, 11
+ /// Set D20:F0:B0h[7] to 0b
+ /// Set D20:F0:B0h[16] to 1b
+ ///
+ Data32And = (UINT32) ~(BIT7);
+ Data32Or = (UINT32) (BIT16);
+
+ MmioAndThenOr32 (
+ PciD20F0RegBase + 0xB0,
+ Data32And,
+ Data32Or
+ );
+ if (GetPchSeries() == PchLp) {
+ ///
+ /// Step 12
+ /// Sideband Minimum Duration. T_SB_MIN = 16ns
+ /// RCBA + Offset 260Ch[15:0]=0010h
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x260C),
+ 0x0010
+ );
+ ///
+ /// Step x
+ /// Program Iobp 0xEC000106 to 3100h
+ ///
+ Status = ProgramIobp (
+ RootComplexBar,
+ 0xEC000106,
+ (UINT32)~(0x00003100),
+ 0x00003100
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h
new file mode 100644
index 0000000..be59220
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitCommon.h
@@ -0,0 +1,73 @@
+/** @file
+ Header file for the PCH Common Init PEIM.
+
+@copyright
+ Copyright (c) 2009 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _PCH_INIT_COMMON_PEIM_H_
+#define _PCH_INIT_COMMON_PEIM_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include EFI_PPI_CONSUMER (PchPlatformPolicy)
+#include EFI_PPI_CONSUMER (PchUsbPolicy)
+#endif
+
+#define PCH_INIT_COMMON_SCRIPT_IO_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_IO_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_MEM_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_MEM_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_PCI_CFG_WRITE(TableName, Width, Address, Count, Buffer)
+
+#define PCH_INIT_COMMON_SCRIPT_PCI_CFG_READ_WRITE(TableName, Width, Address, Data, DataMask)
+
+#define PCH_INIT_COMMON_SCRIPT_STALL(TableName, Duration)
+
+#define PCH_INIT_COMMON_SCRIPT_SAVE_IOBP_S3_ITEM(RootComplexBar, Address, AndMask, OrMask) \
+ EFI_SUCCESS
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+///
+/// Execute function when running in PEI
+///
+#define USB_RUN_IN_PEI TRUE
+
+///
+/// Execute function when running in DXE
+/// It is always FALSE for PEI phase check
+///
+#define USB_RUN_IN_DXE FALSE
+
+///
+/// USB precondition policy check
+///
+#define USB_PRECONDITION_POLICY_SUPPORT(UsbPolicy) \
+ ((UsbPolicy)->UsbPrecondition)
+
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+///
+/// USB3 port setting policy check
+///
+#define USB3PORT_SETTING_POLICY_SUPPORT(Revision) \
+ ((Revision >= PCH_PLATFORM_POLICY_PPI_REVISION_3))
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c
new file mode 100644
index 0000000..12133c7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.c
@@ -0,0 +1,2232 @@
+/** @file
+ The PCH Init PEIM implements the PCH PEI Init PPI.
+
+@copyright
+ Copyright (c) 2004 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInitPeim.h"
+
+//
+// Global variables
+//
+static PCH_DMI_TC_VC_PPI mPchDmiTcVcMap = {
+ {
+ DmiVcTypeVc0,
+ DmiVcTypeVc1,
+ DmiVcTypeVcp,
+ DmiVcTypeVc0,
+ DmiVcTypeVc0,
+ DmiVcTypeVc0,
+ DmiVcTypeVc0,
+ DmiVcTypeVcm
+ },
+ {
+ {PCH_DEVICE_ENABLE, (UINT8) 0},
+ {PCH_DEVICE_ENABLE, (UINT8) 1},
+ {PCH_DEVICE_ENABLE, (UINT8) 2},
+ {PCH_DEVICE_ENABLE, (UINT8) 7}
+ }
+};
+
+static PCH_INIT_PPI mPchInitPpi = {
+ PchUsbInit,
+ PchDmiTcVcProgPoll,
+ PchDmiGen2Prog,
+ PchCpuStrapSet
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPchInitPpiGuid,
+ &mPchInitPpi
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiPchPeiInitDone = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPchPeiInitDonePpiGuid,
+ NULL
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPchPlatformPolicyPpiGuid,
+ PchInitialize
+};
+
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+static EFI_PEI_NOTIFY_DESCRIPTOR mPchS3ResumeNotifyDesc = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ PchS3ResumeAtEndOfPei
+};
+//
+// Functions
+//
+
+/**
+ Internal function performing SATA init needed in PEI phase
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS No platform reset action is taken. System can continue boot flow.
+ @retval Others Won't return if platform reset action is taken
+**/
+EFI_STATUS
+EFIAPI
+PchSataInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINTN PciD31F0RegBase;
+ UINT16 LpcDeviceId;
+ UINTN PciD31F2RegBase;
+ UINTN PciD28F0RegBase;
+ BOOLEAN SkipSataInit;
+ UINT16 i;
+ UINT16 GSpeed;
+ UINT16 PortId;
+ UINT8 RxEq;
+ UINT32 OrMask;
+ UINT16 size;
+ UINT32 RootComplexBar;
+ UINT8 DeviceLaneOwner;
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+ UINT32 PchSataTraceId;
+#ifdef TRAD_FLAG
+ IOBP_MMIO_TABLE_STRUCT *PchSataHsio;
+ IOBP_MMIO_TABLE_STRUCT *PchSataHsio_MB;
+ IOBP_MMIO_TABLE_STRUCT *PchSataHsio_DT;
+ IOBP_SATA_RXEQ_TABLE *PchSataRxEqHsio;
+#endif // TRAD_FLAG
+ IOBP_MMIO_TABLE_STRUCT *PchSataSharedHsio;
+ IOBP_MMIO_TABLE_STRUCT *PchSataSharedHsio_MB;
+ IOBP_MMIO_TABLE_STRUCT *PchSataSharedHsio_DT;
+ IOBP_SATA_RXEQ_TABLE *PchSataRxEqSharedHsio;
+
+ DEBUG ((EFI_D_INFO, "PchSataInit() - Start\n"));
+
+ PchSeries = GetPchSeries();
+ RootComplexBar = PCH_RCRB_BASE;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ PciD31F2RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SATA,
+ PCI_FUNCTION_NUMBER_PCH_SATA,
+ 0
+ );
+ PciD28F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,
+ 0
+ );
+ SkipSataInit = FALSE;
+
+ ///
+ /// Skip SATA init if any of SATA port0 ~ port3 is enabled
+ ///
+ if ((MmioRead8 (PciD31F2RegBase + R_PCH_SATA_PCS) & (UINT8) (B_PCH_SATA_PCS_PORT3_EN |
+ B_PCH_SATA_PCS_PORT2_EN |
+ B_PCH_SATA_PCS_PORT1_EN |
+ B_PCH_SATA_PCS_PORT0_EN)) != 0) {
+ SkipSataInit = TRUE;
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Skip SATA init if SATA port4 or port5 is enabled
+ ///
+ if ((MmioRead8 (PciD31F2RegBase + R_PCH_SATA_PCS) & (UINT8) (B_PCH_SATA_PCS_PORT5_EN |
+ B_PCH_SATA_PCS_PORT4_EN)) != 0) {
+ SkipSataInit = TRUE;
+ }
+ }
+ if (SkipSataInit == TRUE) {
+ if (PchSeries == PchH) {
+ ///
+ /// Any SATA port should not be enabled unless CPU only reset.
+ /// The value of 0xEA000AAC[5:4] is 10b after issuing CPU only reset.
+ /// Note:
+ /// The default value of 0xEA000AAC[5:4] is 00b.
+ /// The following "if" condition will need to update while the
+ /// BIOS recommended setting of 0xEA000AAC[5:4] is changed.
+ /// Asset if any SATA port is enabled before SATA Hsio initialization is done
+ ///
+ Status = ReadIobp (RootComplexBar, 0xEA000AAC, &Data32And);
+ if ((Data32And & (UINT32) (BIT4 | BIT5)) != 0x20) {
+ DEBUG ((EFI_D_ERROR, "Please do not enable any SATA port before SATA Hsio initialization is done.\n"));
+ ASSERT (0);
+ }
+ }
+ } else {
+ ///
+ /// Assume SATA mode will be AHCI, SATA Port 0 - Port 5 are all for D31:F2
+ ///
+ if (PchSeries == PchH) {
+ MmioAndThenOr8 (
+ PciD31F2RegBase + R_PCH_SATA_MAP,
+ (UINT8) (~B_PCH_SATA_MAP_SMS_MASK),
+ (UINT8) (V_PCH_SATA_MAP_SMS_AHCI | B_PCH_SATA_PORT_TO_CONTROLLER_CFG)
+ );
+ } else if (PchSeries == PchLp) {
+ MmioAndThenOr8 (
+ PciD31F2RegBase + R_PCH_SATA_MAP,
+ (UINT8) (~B_PCH_SATA_MAP_SMS_MASK),
+ (UINT8) (V_PCH_SATA_MAP_SMS_AHCI)
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 2
+ /// System BIOS must set D31:F2:Reg 94h[8:0] = 183h as part of the chipset initialization
+ /// prior to SATA configuration. These bits should be restored while resuming from a S3
+ /// sleep state.
+ ///
+ Data32And = (UINT32)~(BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0);
+ Data32Or = 0x183;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_SCLKCG),
+ Data32And,
+ Data32Or
+ );
+ ///
+ /// Step 3
+ /// D31:F2:Reg 92h[15] = 1b
+ /// Set OOB Retry Mode bit of Port Control and Status (PCS) register
+ /// These bits should be restored while resuming from a S3 sleep state
+ ///
+ MmioOr16 ((UINTN) (PciD31F2RegBase + R_PCH_SATA_PCS), (UINT16) (B_PCH_SATA_PCS_OOB_RETRY));
+ ///
+ /// Step 4
+ /// System BIOS must program SATA Hsio table as stated in Table 7-7 to 7-8 BEFORE the SATA
+ /// ports are enabled.
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 7.1.5
+ /// Step 8
+ /// Bios is required to program IOBP setting according to the table 7-7 to 7-8
+ /// using 7.1.4 IOSF SBI with OPCODE "PHY Configuration Register".
+ /// Table 7-7 SATA dedicated lane setting
+ ///
+ DeviceLaneOwner = MmioRead8 (PciD28F0RegBase + 0x410);
+#ifdef TRAD_FLAG
+ switch (PchStepping()) {
+ case LptHB0:
+ size = (sizeof (PchSataHsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio = PchSataHsioLptH_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataHsioLptH_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio = PchSataHsioLptH_Cx;
+ break;
+ default:
+ PchSataHsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+
+ for (i = 0; i < size; i++) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataHsio[i].Address,
+ PchSataHsio[i].AndMask,
+ PchSataHsio[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // TRAD_FLAG
+ ///
+ /// Table 7-8 SATA Shared lane setting
+ ///
+ switch (PchStepping()) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchSataSharedHsioLptLp_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio = PchSataSharedHsioLptLp_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ size = (sizeof (PchSataSharedHsioLptH_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio = PchSataSharedHsioLptH_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataSharedHsioLptH_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio = PchSataSharedHsioLptH_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ size = 0;
+ PchSataSharedHsio = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ if (PchSeries == PchLp) {
+ if ((((PchSataSharedHsio[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5)) ||
+ (((PchSataSharedHsio[i].Address & 0xFE00) == 0x2400) && ((DeviceLaneOwner & BIT6) == BIT6)) ||
+ (((PchSataSharedHsio[i].Address & 0xFE00) == 0x2600) && ((DeviceLaneOwner & BIT7) == BIT7))) {
+ continue;
+ }
+ } else if (PchSeries == PchH) {
+ if ((((PchSataSharedHsio[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5))) {
+ continue;
+ }
+ }
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataSharedHsio[i].Address,
+ PchSataSharedHsio[i].AndMask,
+ PchSataSharedHsio[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.1, Section 7.1.5
+ /// Step 9
+ /// IOBP Programming:
+ /// For Mobile:
+ /// BIOS is required to program IOBP setting according to Table 7-11 and
+ /// Table 7-12 using settings in Section 7.1.4 with OPCODE "PHY Configuration Register".
+ ///
+ if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
+#ifdef TRAD_FLAG
+ ///
+ /// Table 7-11 SATA Dedicated Lane Setting
+ ///
+ switch (PchStepping()) {
+ case LptHB0:
+ size = (sizeof (PchSataHsioLptH_MB_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio_MB = PchSataHsioLptH_MB_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataHsioLptH_MB_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio_MB = PchSataHsioLptH_MB_Cx;
+ break;
+ default:
+ size = 0;
+ PchSataHsio_MB = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataHsio_MB[i].Address,
+ PchSataHsio_MB[i].AndMask,
+ PchSataHsio_MB[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // TRAD_FLAG
+ ///
+ /// Table 7-12 SATA Shared Lane Setting
+ ///
+ switch (PchStepping()) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchSataSharedHsioLptLp_MB_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_MB = PchSataSharedHsioLptLp_MB_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ size = (sizeof (PchSataSharedHsioLptH_MB_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_MB = PchSataSharedHsioLptH_MB_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataSharedHsioLptH_MB_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_MB = PchSataSharedHsioLptH_MB_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ size = 0;
+ PchSataSharedHsio_MB = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ if (PchSeries == PchLp) {
+ if ((((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5)) ||
+ (((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2400) && ((DeviceLaneOwner & BIT6) == BIT6)) ||
+ (((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2600) && ((DeviceLaneOwner & BIT7) == BIT7))) {
+ continue;
+ }
+ } else if (PchSeries == PchH) {
+ if ((((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio_MB[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5))) {
+ continue;
+ }
+ }
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataSharedHsio_MB[i].Address,
+ PchSataSharedHsio_MB[i].AndMask,
+ PchSataSharedHsio_MB[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ ///
+ /// For Desktop:
+ /// BIOS is required to program IOBP setting according to Table 7-13 and
+ /// Table 7-14 using settings in Section 7.1.4 with OPCODE "PHY Configuration Register".
+ /// Table 7-13 SATA Dedicated Lane Setting
+ ///
+#ifdef TRAD_FLAG
+ switch (PchStepping()) {
+ case LptHB0:
+ size = (sizeof (PchSataHsioLptH_DT_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio_DT = PchSataHsioLptH_DT_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataHsioLptH_DT_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataHsio_DT = PchSataHsioLptH_DT_Cx;
+ break;
+ default:
+ size = 0;
+ PchSataHsio_DT = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataHsio_DT[i].Address,
+ PchSataHsio_DT[i].AndMask,
+ PchSataHsio_DT[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif // TRAD_FLAG
+ ///
+ /// Table 7-14 SATA Shared Lane Setting
+ ///
+ switch (PchStepping()) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchSataSharedHsioLptLp_DT_Bx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_DT = PchSataSharedHsioLptLp_DT_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHB0:
+ size = (sizeof (PchSataSharedHsioLptH_DT_B0) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_DT = PchSataSharedHsioLptH_DT_B0;
+ break;
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataSharedHsioLptH_DT_Cx) / sizeof (IOBP_MMIO_TABLE_STRUCT));
+ PchSataSharedHsio_DT = PchSataSharedHsioLptH_DT_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ size = 0;
+ PchSataSharedHsio_DT = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+ for (i = 0; i < size; i++) {
+ if (PchSeries == PchLp) {
+ if ((((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5)) ||
+ (((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2400) && ((DeviceLaneOwner & BIT6) == BIT6)) ||
+ (((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2600) && ((DeviceLaneOwner & BIT7) == BIT7))) {
+ continue;
+ }
+ } else if (PchSeries == PchH) {
+ if ((((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataSharedHsio_DT[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5))) {
+ continue;
+ }
+ }
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataSharedHsio_DT[i].Address,
+ PchSataSharedHsio_DT[i].AndMask,
+ PchSataSharedHsio_DT[i].OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ ///
+ /// Table 7-15 SATA RxEq Dedicated Lane Setting
+ ///
+ PchSataTraceId = 0;
+#ifdef TRAD_FLAG
+ switch (PchStepping()) {
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataRxEqHsioLptH_Cx) / sizeof (IOBP_SATA_RXEQ_TABLE));
+ PchSataRxEqHsio = PchSataRxEqHsioLptH_Cx;
+ break;
+ default:
+ PchSataRxEqHsio = NULL;
+ size = 0;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+
+ for(PortId = 0; PortId < GetPchMaxSataPortNum (); PortId++){
+ for(GSpeed = 0; GSpeed < 3; GSpeed++){
+ if(PchPlatformPolicyPpi->SataConfig->SataTraceConfig->PortRxEq[PortId].GenSpeed[GSpeed].Enable == PCH_DEVICE_ENABLE) {
+ PchSataTraceId = PCH_SATA_RXEQ_ID(PortId, GSpeed);
+ for (i = 0; i < size; i++) {
+ if(PchSataRxEqHsio[i].TraceId == PchSataTraceId) {
+ RxEq = PchPlatformPolicyPpi->SataConfig->SataTraceConfig->PortRxEq[PortId].GenSpeed[GSpeed].RxEq;
+ OrMask = (((UINT32) (((RxEq) << 24 ) + ((RxEq) << 16 ) + ((RxEq) << 8 ) + RxEq)) & ((UINT32)~(PchSataRxEqHsio[i].AndMask)));
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataRxEqHsio[i].Address,
+ PchSataRxEqHsio[i].AndMask,
+ OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+ }
+#endif // TRAD_FLAG
+
+ ///
+ /// Table 7-16 SATA RxEq Shared Lane Setting
+ ///
+ switch (PchStepping()) {
+#ifdef ULT_FLAG
+ case LptLpB0:
+ case LptLpB1:
+ case LptLpB2:
+ size = (sizeof (PchSataRxEqSharedHsioLptLp_Bx) / sizeof (IOBP_SATA_RXEQ_TABLE));
+ PchSataRxEqSharedHsio = PchSataRxEqSharedHsioLptLp_Bx;
+ break;
+#endif // ULT_FLAG
+#ifdef TRAD_FLAG
+ case LptHC0:
+ case LptHC1:
+ case LptHC2:
+ size = (sizeof (PchSataRxEqSharedHsioLptH_Cx) / sizeof (IOBP_SATA_RXEQ_TABLE));
+ PchSataRxEqSharedHsio = PchSataRxEqSharedHsioLptH_Cx;
+ break;
+#endif // TRAD_FLAG
+ default:
+ size = 0;
+ PchSataRxEqSharedHsio = NULL;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH Stepping\n"));
+ }
+
+ for(PortId = 0; PortId < GetPchMaxSataPortNum (); PortId++){
+ for(GSpeed = 0; GSpeed < 3; GSpeed++){
+ if(PchPlatformPolicyPpi->SataConfig->SataTraceConfig->PortRxEq[PortId].GenSpeed[GSpeed].Enable == PCH_DEVICE_ENABLE) {
+ PchSataTraceId = PCH_SATA_RXEQ_ID(PortId, GSpeed);
+ for (i = 0; i < size; i++) {
+ if(PchSataRxEqSharedHsio[i].TraceId == PchSataTraceId) {
+ if (PchSeries == PchLp) {
+ if ((((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5)) ||
+ (((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2400) && ((DeviceLaneOwner & BIT6) == BIT6)) ||
+ (((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2600) && ((DeviceLaneOwner & BIT7) == BIT7)))
+ {
+ continue;
+ }
+ } else if (PchSeries == PchH) {
+ if ((((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2000) && ((DeviceLaneOwner & BIT4) == BIT4)) ||
+ (((PchSataRxEqSharedHsio[i].Address & 0xFE00) == 0x2200) && ((DeviceLaneOwner & BIT5) == BIT5)))
+ {
+ continue;
+ }
+ }
+ RxEq = PchPlatformPolicyPpi->SataConfig->SataTraceConfig->PortRxEq[PortId].GenSpeed[GSpeed].RxEq;
+ OrMask = (((UINT32) (((RxEq) << 24 ) + ((RxEq) << 16 ) + ((RxEq) << 8 ) + RxEq)) & ((UINT32)~(PchSataRxEqSharedHsio[i].AndMask)));
+ Status = ProgramIobp (
+ RootComplexBar,
+ PchSataRxEqSharedHsio[i].Address,
+ PchSataRxEqSharedHsio[i].AndMask,
+ OrMask
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 5
+ /// Program D31:F2:98h[22] to 1b for desktop and mobile platform only.
+ ///
+ if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId) ||
+ IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
+ MmioOr32 (
+ (UINTN) (PciD31F2RegBase + 0x98),
+ (UINT32) (BIT22)
+ );
+ }
+ ///
+ /// Step 6
+ /// Program D31:F2:98h[19] = 1b
+ ///
+ MmioOr32 (
+ (UINTN) (PciD31F2RegBase + 0x98),
+ (UINT32) (BIT19)
+ );
+ ///
+ /// Step 7
+ /// Program D31:F2:98h[12:7] = 04h
+ ///
+ Data32And = (UINT32) (~(BIT7 | BIT8 | BIT10 | BIT11 | BIT12));
+ Data32Or = (UINT32) (BIT9);
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + 0x98),
+ Data32And,
+ Data32Or
+ );
+ ///
+ /// Step 8
+ /// Program D31:F2:98h[20] to 1b
+ ///
+ MmioOr32 ((UINTN) (PciD31F2RegBase + 0x98), (UINT32) (BIT20));
+ ///
+ /// Step 9
+ /// Program D31:F2:98h[6:5] to 01b
+ ///
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + 0x98),
+ (UINT32) (~(BIT6 | BIT5)),
+ BIT5
+ );
+ ///
+ /// Step 10
+ /// Program D31:F2:98h [18] to 1b
+ ///
+ Data32Or = (UINT32) (BIT18);
+ MmioOr32 (
+ (UINTN) (PciD31F2RegBase + 0x98),
+ Data32Or
+ );
+ ///
+ /// Step 11
+ /// Program D31:F2:98h[29] to 1b
+ /// Done in PchInitBeforeBoot()
+ ///
+ /// Step 12
+ /// Program D31:F2:9Ch[5] to 1b (Note: this must be programmed together with D31:F2:9Ch[7:6]
+ /// in word write)
+ /// Done in ConfigureSata ()
+ ///
+ /// Step 13
+ /// When SATA in IDE mode
+ /// a. Program D31:F2:34h [7:0] to 70h
+ /// b. Program D31:F2:70h [15:8] to 0h
+ /// Done in PchMiscInit ()
+ ///
+ /// Step 14
+ /// Program D31:F2:9Ch[31] to 1b at the End of Post
+ /// Done in PchInitBeforeBoot()
+ ///
+ /// Enable the SATA port0 ~ port3.
+ ///
+ if (PchSeries == PchH) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) (B_PCH_SATA_PCS_PORT3_EN | B_PCH_SATA_PCS_PORT2_EN | B_PCH_SATA_PCS_PORT1_EN | B_PCH_SATA_PCS_PORT0_EN)
+ );
+ }
+ if (PchSeries == PchLp) {
+ ///
+ /// If D28:F0:410h[7] = 1b, System BIOS should not enable the SATA port0
+ /// If D28:F0:410h[6] = 1b, System BIOS should not enable the SATA port1
+ /// If D28:F0:410h[5] = 1b, System BIOS should not enable the SATA port2
+ /// If D28:F0:410h[4] = 1b, System BIOS should not enable the SATA port3
+ ///
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT7) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT0_EN
+ );
+ }
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT6) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT1_EN
+ );
+ }
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT5) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT2_EN
+ );
+ }
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT4) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT3_EN
+ );
+ }
+ }
+ if (PchSeries == PchH) {
+ ///
+ /// Enable the SATA port4 and port5.
+ /// Step 1.a
+ /// If D28:F0:410h[4] = 1b, System BIOS should not enable the SATA port4
+ /// Step 1.b
+ /// If D28:F0:410h[5] = 1b, System BIOS should not enable the SATA port5
+ ///
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT4) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT4_EN
+ );
+ }
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT5) == 0) {
+ MmioOr8 (
+ PciD31F2RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA_PCS_PORT5_EN
+ );
+ }
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "PchSataInit() - End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The function is used while doing CPU Only Reset, where PCH may be required
+ to initialize strap data before soft reset.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+ @param[in] Operation Get/Set Cpu Strap Set Data
+ @param[in, out] CpuStrapSet Cpu Strap Set Data
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @exception EFI_UNSUPPORTED The function is not supported.
+**/
+EFI_STATUS
+EFIAPI
+PchCpuStrapSet (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CPU_STRAP_OPERATION Operation,
+ IN OUT UINT16 *CpuStrapSet
+ )
+{
+ UINT32 RootComplexBar;
+
+ DEBUG ((EFI_D_INFO, "PchCpuStrapSet() - Start\n"));
+
+ RootComplexBar = PCH_RCRB_BASE;
+
+ switch (Operation) {
+ case GetCpuStrapSetData:
+ ///
+ /// Get CPU Strap Settings select. 0 = from descriptor, 1 = from PCH
+ ///
+ if ((MmioRead8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDC)) & B_PCH_SPI_SRDC_SRDS) == 0) {
+ ///
+ /// Read Strap from Flash Descriptor
+ ///
+ *CpuStrapSet = 0;
+ return EFI_SUCCESS;
+ } else {
+ ///
+ /// Read Strap from PCH Soft Strap.
+ ///
+ *CpuStrapSet = MmioRead16 ((UINTN) (RootComplexBar + R_PCH_SPI_SRD));
+ }
+ break;
+
+ case SetCpuStrapSetData:
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 4.3 Soft Reset Control
+ /// 2. If there are CPU configuration changes, program the strap setting into the
+ /// Soft Reset Data register located at SPIBAR Offset F8h [15:0] (RCBA + Offset 38F8h [15:0])
+ /// and follow the steps outlined in the "CPU Only Reset BIOS Flow" section of the Processor
+ /// BIOS Writer's Guide and skip steps 3 and 4.
+ /// a. Program Soft Reset Data Register SPIBAR + F8h [13:0] (RCBA + 38F8h [13:0])
+ /// (details in Processor BIOS Writer's Guide)
+ /// b. Set RCBA + Offset 38F4h[0] = 1b
+ /// c. Set RCBA + Offset 38F0h[0] = 1b
+ /// d. Skip steps 3 and 4.
+ ///
+ MmioWrite16 ((UINTN) (RootComplexBar + R_PCH_SPI_SRD), *CpuStrapSet);
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDC), B_PCH_SPI_SRDC_SRDS);
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDL), B_PCH_SPI_SRDL_SSL);
+ break;
+
+ case LockCpuStrapSetData:
+ MmioOr8 ((UINTN) (RootComplexBar + R_PCH_SPI_SRDL), B_PCH_SPI_SRDL_SSL);
+ break;
+
+ default:
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "PchCpuStrapSet() - End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function may trigger platform reset depending on the current GbE status,
+ the intended GbE enabling, and current ME status. (When ME is enabled, this function
+ may trigger a Global reset.)
+ This function may not return if it triggers an platform reset and the BIOS boot flow
+ restarts.
+ If this function returns EFI_SUCCESS it indicates there is no need for platform
+ reset in this boot, and boot flow continues.
+ If this function returns EFI_DEVICE_ERROR, something error happens.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS No platform reset action is taken. System can continue boot flow.
+ @retval Others Won't return if platform reset action is taken
+**/
+EFI_STATUS
+EFIAPI
+PchGbeMandatedReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+ UINT8 RegData8;
+ UINTN PciD25F0RegBase;
+ UINT32 GbEMemBar;
+ UINT32 TempGbEMemBar;
+ UINT16 CmdReg;
+ BOOLEAN ResetRequired;
+ BOOLEAN GbeRegion;
+ PCH_RESET_PPI *PchResetPpi;
+ EFI_STATUS Status;
+ PCH_RESET_TYPE PchResetType;
+
+ PciD25F0RegBase = 0;
+ GbEMemBar = 0;
+ ResetRequired = FALSE;
+
+ ///
+ /// Read the BUC register
+ ///
+ RegData8 = MmioRead8 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_BUC);
+
+ GbeRegion = PchIsGbeRegionValid (PchPlatformPolicyPpi->Rcba);
+
+ ///
+ /// If no change of status, just return success
+ ///
+ if (((RegData8 & B_PCH_RCRB_BUC_LAN_DIS) &&
+ !PchPlatformPolicyPpi->GbeConfig->EnableGbe) ||
+ (!(RegData8 & B_PCH_RCRB_BUC_LAN_DIS) &&
+ PchPlatformPolicyPpi->GbeConfig->EnableGbe)) {
+ return EFI_SUCCESS;
+ }
+
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gPchResetPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PchResetPpi
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Before modifying LAN Disable bit, make sure it's not locked.
+ /// If it's locked, issus a GlobalReset to unlock it.
+ ///
+ RegData8 = MmioRead8 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FDSW);
+ if (RegData8 & B_PCH_RCRB_FDSW_FDSWL) {
+ DEBUG ((EFI_D_ERROR, "PchGbeMandatedReset: resetting the board via CF9 to unlock LAN Disable register...\n"));
+ PchResetPpi->Reset (PchResetPpi, GlobalReset);
+ ///
+ /// Shouldn't reach here
+ ///
+ return EFI_SUCCESS;
+ }
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2.1/10.2.2 Enable/Disable the GbE Clock Gating
+ /// Step 3
+ /// Set RCBA + 341Ch[23]
+ /// Done in ConfigureClockGating()
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2 Enabling / Disabling the Internal GbE Controller
+ /// In PCH systems, changing the internal GbE controller from disabled to enabled
+ /// during POST requires a system reset (IO port CF9h = 0Eh) immediately after clearing the LAN disable
+ /// bit in the BUC register, RCBA + 3414[5]. If ME is enabled and the LAN disable bit
+ /// has changed, then system BIOS must set D31:F0:Reg 0ACh[20] prior to issuing a platform reset (IO port CF9h = 0x6 or 0xE).
+ ///
+ /// Therefore, the flow is as below:
+ /// When LAN changes from disabled to enabled
+ /// If ME is not existed, require a power cycle reset.
+ /// If ME is enabled, require a global reset.
+ /// When LAN changes from enabled to disabled
+ /// If ME is not existed, no power cycle reset is required.
+ /// If ME is enabled, and Me is using Gbe (by checking GBEBAR+0x5B54[15]=1), require a global reset.
+ ///
+
+ ///
+ /// Set the BUC register
+ ///
+ if (PchPlatformPolicyPpi->GbeConfig->EnableGbe) {
+ ///
+ /// Change internal Gbe from disabled to enabled
+ ///
+ if (GbeRegion == TRUE) {
+ ResetRequired = TRUE;
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2.1 Enable the Internal GbE Controller
+ /// Step 1
+ /// Set RCBA + 3414h[5] = 0b
+ ///
+ MmioAnd8 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_BUC, (UINT8) (~B_PCH_RCRB_BUC_LAN_DIS));
+ }
+ } else {
+ ///
+ /// Change internal Gbe from enabled to disabled
+ ///
+ if (GbeRegion == TRUE) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2.2 Disable the Internal GbE Controller
+ /// Step 1a
+ /// If Intel ME enable then detect if it supports GBe. Read FWSM_S[15] bit in MBARA + offset 5B54h register.
+ ///
+ PciD25F0RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LAN,
+ PCI_FUNCTION_NUMBER_PCH_LAN,
+ 0
+ );
+ ///
+ /// Store current value of PCH_LAN_MEM_BASE_A
+ ///
+ TempGbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A);
+ ///
+ /// As PCI enumeration has not been done, set PCH_LAN_MBARB per the platform policy
+ ///
+ MmioWrite32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A, PchPlatformPolicyPpi->PlatformData->TempMemBaseAddr);
+ ///
+ /// Store the setting of R_PCH_LAN_CMD
+ ///
+ CmdReg = MmioRead16 (PciD25F0RegBase + R_PCH_LAN_CMD);
+ ///
+ /// Enable memory space decoding in command register
+ ///
+ MmioOr16 (PciD25F0RegBase + R_PCH_LAN_CMD, (UINT16) B_PCH_LAN_CMD_MSE);
+ ///
+ /// Check if GbE device exists
+ ///
+ GbEMemBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A) & B_PCH_LAN_MBARA_BA;
+
+ if (GbEMemBar != 0xFFFFFFFF) {
+ if ((MmioRead16 (GbEMemBar + 0x5B54)) & BIT15) {
+ ResetRequired = TRUE;
+ }
+ }
+ ///
+ /// Restore the setting of R_PCH_LAN_CMD
+ ///
+ MmioWrite16 (PciD25F0RegBase + R_PCH_LAN_CMD, CmdReg);
+ ///
+ /// Restore the value of PCH_LAN_MEM_BASE_A
+ ///
+ MmioWrite32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A, TempGbEMemBar);
+ }
+ ///
+ /// Step 1
+ /// Set RCBA + 3414h[5] = 1b
+ ///
+ MmioOr8 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_BUC, (UINT8) B_PCH_RCRB_BUC_LAN_DIS);
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 10.2.1 & 10.2.2
+ /// Step 2
+ /// Read back for posted write to take effect
+ ///
+ MmioRead8 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_BUC);
+
+ if (!ResetRequired) {
+ return EFI_SUCCESS;
+ }
+
+ DEBUG ((EFI_D_ERROR, "PchGbeMandatedReset: resetting the board via CF9...\n"));
+ if ((MmioRead32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FD2) & B_PCH_RCRB_FD2_MEI1D) == 0) {
+ if (PchPlatformPolicyPpi->PlatformData->EcPresent) {
+ PchResetType = GlobalResetWithEc;
+ } else {
+ PchResetType = GlobalReset;
+ }
+ } else {
+ PchResetType = PowerCycleReset;
+ }
+
+ PchResetPpi->Reset (PchResetPpi, PchResetType);
+ ///
+ /// Shouldn't reach here
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ Internal function performing miscellaneous init needed in early PEI phase
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+PchMiscInit (
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINTN PciD31F2RegBase;
+ UINTN PciD31F5RegBase;
+ UINTN PciD28F0RegBase;
+ UINTN PciD31F0RegBase;
+ UINT16 LpcDeviceId;
+ PCH_HPET_CONFIG *HpetConfig;
+ UINT16 Data16;
+ UINT32 Data32;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINTN RPBase;
+ BOOLEAN RpSpeedChanged;
+ UINT32 RootComplexBar;
+
+ const USB_CONTROLLER EhciControllersMap[PchEhciControllerMax] = {
+ {
+ PCI_DEVICE_NUMBER_PCH_USB,
+ PCI_FUNCTION_NUMBER_PCH_EHCI
+ },
+ {
+ PCI_DEVICE_NUMBER_PCH_USB_EXT,
+ PCI_FUNCTION_NUMBER_PCH_EHCI2
+ }
+ };
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ PciD31F2RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_SATA,
+ PCI_FUNCTION_NUMBER_PCH_SATA,
+ 0
+ );
+ PciD31F5RegBase = 0;
+ if (PchSeries == PchH) {
+ PciD31F5RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SATA,
+ PCI_FUNCTION_NUMBER_PCH_SATA2,
+ 0
+ );
+ }
+ PciD28F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1,
+ 0
+ );
+ HpetConfig = PchPlatformPolicyPpi->HpetConfig;
+ ///
+ /// Set B0:D31:F0 + ACh[20] = 0 at early boot
+ ///
+ MmioAnd32 (PciD31F0RegBase + R_PCH_LPC_PMIR, (UINT32)~(B_PCH_LPC_PMIR_CF9GR));
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// NOTE: Detection of Non-Complaint PCI Express Devices in Gen2 Ports
+ /// Some non-graphics PCI Express devices do not follow PCI Express Specification and currently report
+ /// the incorrect Gen capability or link width. This may cause the improper detection of the card
+ /// by the Intel Gen2 PCI Express port.
+ /// The following settings may improve the ability of an Intel Gen2 PCI Express port to detect
+ /// these non-compliant PCI Express devices.
+ /// If BIOS cannot detect or train the device: Set B0:D28:F0~F7 + 70h [3:0]= 1h
+ /// Wait 100 ms for link to train up
+ /// Please note the above setting is "as-is" as Intel cannot verify all non-compliant devices.
+ /// You need to ensure that the workaround works with devices you are planning to use.
+ ///
+ RpSpeedChanged = FALSE;
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ Index,
+ 0
+ );
+ if (MmioRead16 (RPBase + R_PCH_PCIE_VENDOR_ID) == 0xFFFF) {
+ continue;
+ }
+
+ switch (PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index]) {
+ case PchPcieGen1:
+ Data16 = BIT0;
+ break;
+ case PchPcieGen2:
+ case PchPcieAuto:
+ default:
+ Data16 = BIT1;
+ break;
+ }
+ if ((MmioRead16 (RPBase + R_PCH_PCIE_LCTL2) & (UINT16) (B_PCH_PCIE_LCTL2_TLS)) != Data16) {
+ MmioAndThenOr16 (RPBase + R_PCH_PCIE_LCTL2, (UINT16)~(B_PCH_PCIE_LCTL2_TLS), Data16);
+ RpSpeedChanged = TRUE;
+ }
+ }
+ //
+ // Merge all delay for change link speed of RPs together to reduce the delay time.
+ //
+ if (RpSpeedChanged) {
+ PchPmTimerStall (100 * 1000);
+ }
+
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ RPBase = MmPciAddress (
+ 0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ Index,
+ 0
+ );
+ if (MmioRead16 (RPBase + R_PCH_PCIE_VENDOR_ID) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 8.2
+ /// Else if the port is hot-plug enable, do not disable the port. If BIOS wants to disable the port,
+ /// BIOS should not enable the hot plug capability or must disable the hot plug capability of the port.
+ /// Set B0:D28:Fn + 338h [26] = 0b at early POST.
+ ///
+ MmioAnd32 ((RPBase + 0x338), (UINT32) ~BIT26);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 1
+ /// Before MRC execution, system BIOS must program the following register.
+ /// B0:D28:F0 + F4h[6:5] = 0b
+ /// B0:D28:F0 + F4h[7] = 1b
+ ///
+ if (Index == 0) {
+ MmioAndThenOr8 ((RPBase + 0xF4), (UINT8) ~(BIT5 | BIT6), BIT7);
+ }
+ }
+
+ for (Index = 0; Index < GetPchEhciMaxControllerNum (); Index++) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 7.1.5 Additional PCH DMI Programming Steps
+ /// Step 3.2
+ /// RCBA + Offset 50h[23:20] = 2h and RCBA + Offset 50h[17] = 1b (Done at
+ /// PchDmiTcVcProgPoll() on PchDmiPeim.c)
+ /// and also ensure that D29/D26:F0:88h [2] = 0b
+ ///
+ Data32 = MmioRead32 (
+ (UINTN) MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ EhciControllersMap[Index].Device,
+ EhciControllersMap[Index].Function,
+ 0x88)
+ );
+ Data32 &= (UINT32) (~BIT2);
+ MmioWrite32 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ EhciControllersMap[Index].Device,
+ EhciControllersMap[Index].Function,
+ 0x88),
+ Data32
+ );
+ }
+ ///
+ /// Initial and enable HPET High Precision Timer memory address for basic usage
+ ///
+ if (HpetConfig->Enable == PCH_DEVICE_ENABLE) {
+ MmioAndThenOr32 (
+ (UINTN) (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_HPTC),
+ (UINT32)~B_PCH_RCRB_HPTC_AS,
+ (UINT32) (((HpetConfig->Base >> N_PCH_HPET_ADDR_ASEL) & B_PCH_RCRB_HPTC_AS) | B_PCH_RCRB_HPTC_AE)
+ );
+ ///
+ /// Read back for posted write to take effect
+ ///
+ MmioRead32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_HPTC);
+ ///
+ /// Set HPET Timer enable to start counter spinning
+ ///
+ MmioOr32 (HpetConfig->Base + 0x10, 0x1);
+ }
+
+ if (PchPlatformPolicyPpi->Port80Route == PchReservedPageToLpc) {
+ MmioAnd32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_GCS, (UINT32) (~B_PCH_RCRB_GCS_RPR));
+ } else {
+ MmioOr32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_GCS, (UINT32) B_PCH_RCRB_GCS_RPR);
+ }
+ ///
+ /// Read back for posted write to take effect
+ ///
+ MmioRead32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_GCS);
+
+#ifdef TRAD_FLAG
+ if (PchSeries == PchH) {
+ if (PchPlatformPolicyPpi->SataConfig->SataMode == PchSataModeIde) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// Step 13
+ /// When SATA in IDE mode
+ /// a. Program D31:F2:34h [7:0] to 70h
+ ///
+ Data32And = (UINT32) ~(0xFF);
+ Data32Or = (UINT32) (0x70);
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + 0x34),
+ Data32And,
+ Data32Or
+ );
+ ///
+ /// b. Program D31:F2:70h [15:8] to 0h
+ ///
+ Data32And = (UINT32) ~(0xFF00);
+ MmioAnd32 (
+ (UINTN) (PciD31F2RegBase + 0x70),
+ Data32And
+ );
+ ///
+ /// IDE mode, SATA Port 0 - Port 3 are for D31:F2, Port4 and Port 5 are for D31:F5
+ ///
+ MmioAnd8 (
+ PciD31F2RegBase + R_PCH_SATA_MAP,
+ (UINT8)~(B_PCH_SATA_MAP_SMS_MASK | B_PCH_SATA_PORT_TO_CONTROLLER_CFG)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 section 14.1.7 Additional Programming Requirements during
+ /// SATA Initialization
+ /// Step 1
+ /// If D28:F0:410h[5:4] = 11b, System BIOS must disable D31:F5 by setting SAD2 bit,
+ /// RCBA + 3418[25]
+ ///
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & (UINT8) (BIT5 | BIT4)) == (UINT8) (BIT5 | BIT4)) {
+ MmioOr32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FUNC_DIS, (UINT32) B_PCH_RCRB_FUNC_DIS_SATA2);
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FUNC_DIS);
+ } else {
+ ///
+ /// Enable the SATA port4 and port5.
+ /// Step 1.a
+ /// If D28:F0:410h[4] = 1b, System BIOS should not enable the SATA port4
+ /// Step 1.b
+ /// If D28:F0:410h[5] = 1b, System BIOS should not enable the SATA port5
+ ///
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT4) == 0) {
+ MmioOr8 (
+ PciD31F5RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA2_PCS_PORT4_EN
+ );
+ }
+ if ((MmioRead8 (PciD28F0RegBase + 0x410) & BIT5) == 0) {
+ MmioOr8 (
+ PciD31F5RegBase + R_PCH_SATA_PCS,
+ (UINT8) B_PCH_SATA2_PCS_PORT5_EN
+ );
+ }
+ }
+ } else {
+ MmioOr32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FUNC_DIS, (UINT32) B_PCH_RCRB_FUNC_DIS_SATA2);
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32 (PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_FUNC_DIS);
+ }
+ }
+#endif //TRAD_FLAG
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ if (PchPlatformPolicyPpi->SataConfig->SataMode == PchSataModeLoopbackTest) {
+ ///
+ /// Set D31:F2:90h[7:6] to 00b
+ ///
+ MmioAnd8 (
+ PciD31F2RegBase + R_PCH_SATA_MAP,
+ (UINT8)~(B_PCH_SATA_MAP_SMS_MASK)
+ );
+ ///
+ /// Set D31:F2 + SIR Index 00h[15] = 1b
+ ///
+ MmioWrite8 (PciD31F2RegBase + R_PCH_SATA_SIRI, 0x00);
+ Data32And = 0xFFFF7FFF;
+ Data32Or = 0x00008000;
+ MmioAndThenOr32 (
+ (UINTN) (PciD31F2RegBase + R_PCH_SATA_STRD),
+ Data32And,
+ Data32Or
+ );
+ }
+ }
+#endif // ULT_FLAG
+ if (PchPlatformPolicyPpi->SataConfig->SataMode == PchSataModeRaid) {
+ LpcDeviceId = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_DEVICE_ID);
+ if (IS_PCH_LPT_RAID_AVAILABLE (LpcDeviceId)) {
+ MmioAndThenOr8 (
+ PciD31F2RegBase + R_PCH_SATA_MAP,
+ (UINT8) (~B_PCH_SATA_MAP_SMS_MASK),
+ (UINT8) (V_PCH_SATA_MAP_SMS_RAID)
+ );
+ } else {
+ DEBUG ((EFI_D_INFO, "PCH Device ID : 0x%x\n", LpcDeviceId));
+ DEBUG ((EFI_D_ERROR, "This SKU doesn't support RAID feature. Set to AHCI mode.\n"));
+ }
+ }
+
+ //
+ // The following three ICC isCLK settings must be done for S3/S4/S5 before ICC HW is locked.
+ // For S3 path, the ICC HW is locked just after DID message. So program those in PEI.
+ //
+ if (PchSeries == PchLp) {
+ RootComplexBar = PchPlatformPolicyPpi->Rcba;
+ ///
+ /// Set the isCLK PLL lock speed in the ICC HW.
+ /// Set bits 13:12 and bits 10:8, clear bit 11, fast lock time = 11us
+ /// NOTE: Lock occurs after EOP message sent, and this write will fail until core well reset. On write failure
+ /// expectation is that the register was previously programmed and values are maintained in HW registers.
+ ///
+ Status = ProgramIobp(RootComplexBar, 0xED00015C, (UINT32)~(BIT11), (BIT13|BIT12|BIT10|BIT9|BIT8));
+
+ ///
+ /// Set the isCLK freeze timer in the ICC HW.
+ /// Set bits 23:22, Clk timer = 1 clk
+ /// NOTE: Lock occurs after EOP message sent, and this write will fail until core well reset. On write failure
+ /// expectation is that the register was previously programmed and values are maintained in HW registers.
+ ///
+ Status = ProgramIobp(RootComplexBar, 0xED000118, (UINT32)0xFFFFFFFF, (UINT32) (BIT23|BIT22));
+
+ ///
+ /// Set bit 21 and 18, expand Vcont Window
+ ///
+ Status = ProgramIobp(RootComplexBar, 0xED000120, (UINT32)0xFFFFFFFF, (UINT32) (BIT21|BIT18));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Perform Thermal Management Support initialization
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+PchThermalInit (
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+ UINTN PciD31F6RegBase;
+ UINTN PciD0F0RegBase;
+ UINT32 ThermalBaseB;
+ PCH_MEMORY_THROTTLING *MemoryThrottling;
+ UINT32 Data32And;
+ UINT32 Data32Or;
+ UINT32 Softstrap15;
+
+ PciD31F6RegBase = MmPciAddress (
+ 0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_THERMAL,
+ PCI_FUNCTION_NUMBER_PCH_THERMAL,
+ 0
+ );
+ PciD0F0RegBase = MmPciAddress (0, 0, 0, 0, 0);
+
+ MemoryThrottling = PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling;
+ ThermalBaseB = PchPlatformPolicyPpi->PlatformData->TempMemBaseAddr;
+
+ ///
+ /// D31:F6:Reg 44h[31:0], with a 64-bit BAR for BIOS.
+ /// Enable the BAR by setting the SPTYPEN bit, D31:F6:Reg 40h[0].
+ ///
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBARB, ThermalBaseB);
+ MmioWrite32 (PciD31F6RegBase + R_PCH_THERMAL_TBARBH, 0);
+ MmioOr32 (PciD31F6RegBase + R_PCH_THERMAL_TBARB, (UINT32) B_PCH_THERMAL_SPTYPEN);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, 17.2 Thermal Subsystem Device Initialization
+ /// The System BIOS must perform the following steps to initialize the PCH thermal subsystem device, D31:F6.
+ /// Step 1
+ /// Enable Thermal Subsystem device by making sure FD.TTD is cleared.
+ /// The default value of FD.TTD is cleared.
+ ///
+ /// Step 2
+ /// Optionally program Device 31 Interrupt Pin/Route registers
+ /// Left this to platform code
+ ///
+ /// Step 3
+ /// Go through general PCI enumeration and assign standard PCI resource, including TBARB, TBARBH, etc.
+ /// Left this to platform code
+ ///
+ /// Step 4
+ /// Initialize relevant Thermal subsystems for the desired features.
+ ///
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 17.3.1 Initializing Lynx Point Thermal Sensors
+ /// Step 1
+ /// Set various trip points based on the particular usage model. Note that Cat Trip must always be programmed.
+ /// - CTT must be programmed for Cat Trip, CTT must never be changed while the TS enable is set.
+ /// This rule prevents a spurious trip from occurring and causing a system shutdown.
+ /// TSC must then be written to 0x81 to enable the power down and lock the register.
+ /// TSC programming is done in PchPm.c ThermalLockDown()
+ /// - TAHV and TAHL may be programmed if the BIOS or driver wish to force a SW notification for PCH temperature
+ /// - If TAHL/TAHV programmed much later in the flow when a driver is loaded, this means that the TS had been
+ /// enabled long before this, the thermal sensor must be disabled when TAHL/TAHV are programmed, and then
+ /// re-enabled.
+ /// - TSPIEN or TSGPEN may be programmed to cause either an interrupt or SMI/SCI.
+ /// - It is recommended that TAHV, TALV, TSPIEN and TSGPEN be left at their default value, unless there is a
+ /// specific usage that requires these to be programmed.
+ ///
+ if (GetPchSeries() == PchLp) {
+ MmioWrite16 (ThermalBaseB + R_PCH_TBARB_CTT, V_PCH_TBARB_CTT_LPTLP);
+ } else {
+ MmioWrite16 (ThermalBaseB + R_PCH_TBARB_CTT, V_PCH_TBARB_CTT_LPTH);
+ }
+
+ ///
+ /// Step 2
+ /// Clear trip status from TSS/TAS. BIOS should write 0xFF to clear any bit that was inadvertently set while programming
+ /// the TS. This write of 0xFF should be done before continuing to the next steps.
+ ///
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSS, 0xFF);
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TAS, 0xFF);
+
+ ///
+ /// Step 3
+ /// Enable the desired thermal trip alert methods, i.e. GPE (TSGPEN), SMI (TSMIC) or Interrupt (TSPIEN).
+ /// Only one of the methods should be enabled and the method will be depending on the platform implementation.
+ /// - TSGPEN: BIOS should leave this as default 00h, unless it is required to enable GPE.
+ /// - TSMIC: BIOS should leave TSMIC[7:0] as default 00h, unless the SMI handler is loaded
+ /// and it's safe to enable SMI for these events.
+ /// - TSPIEN: BIOS should leave this as default 0x00, so that a driver can enable later
+ ///
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSGPEN, 0x00);
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSPIEN, 0x00);
+
+ ///
+ /// If PCHSTRP15[14] is 1, PMC will set up SML1 for temp reporting to an EC
+ ///
+ MmioAndThenOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)),
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP15)
+ );
+
+ Softstrap15 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ if ((Softstrap15 & R_PCH_SPI_STRP15_SML1_THRMSEL) != 0) {
+ ///
+ /// Step 4
+ /// If thermal reporting to an EC over SMBus is supported, then write 0x01 to TSREL, else leave at default.
+ ///
+ MmioWrite8 (ThermalBaseB + R_PCH_TBARB_TSREL, 0x01);
+ }
+
+ ///
+ /// Step 5
+ /// If the PCH_Hot pin reporting is supported, then write the temperature value and set the enable in PHL.
+ /// Done in PchPm.c ThermalLockDown()
+ ///
+ /// Step 6
+ /// If thermal throttling is supported, then set the desired values in TL.
+ /// Done in PchPm.c ThermalLockDown()
+ ///
+ /// Step 7
+ /// Enable thermal sensor by programming TSEL register to 0x01.
+ /// Done in PchPm.c ThermalLockDown()
+ ///
+ /// Step 8
+ /// Lock down the thermal reporting to prevent outside agents from changing the values
+ /// Done in PchPm.c ThermalLockDown()
+ ///
+
+ ///
+ /// Clear BAR and disable access
+ ///
+ MmioAnd32 ((UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARB), (UINT32)~B_PCH_THERMAL_SPTYPEN);
+ MmioWrite32 ((UINTN) (PciD31F6RegBase + R_PCH_THERMAL_TBARB), 0);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 17.5.1 Memory Bandwidth Throttling
+ /// If the platform supports an external memory thermal sensor (TS-on-DIMM or TS-on-Board),
+ /// system BIOS needs to program the registers bellow.
+ /// Here are the settings used in the Intel CRB:
+ /// 1. Program RCBA + 33D4h [31:28] = 1100b, for GPIO_D and GPIO_C to PM_SYNC Enable
+ /// 2. Program RCBA + 33D4h [15:12] = 1100b, for GPIO_D and GPIO_C C0 Transmit Enable.
+ /// 3. Program RCBA + 33C8h [11:8] = 0100b to select GPIO 4 to GPIO_C (EXTTS#0) and
+ /// GPIO 5 to GPIO_D (EXTTS#1)
+ /// GPIOBASE + 00h [5:4] = 11b (Done in platform code)
+ ///
+ if (MemoryThrottling->Enable == PCH_DEVICE_ENABLE) {
+ Data32And = 0x0FFF0FFF;
+ Data32Or = 0;
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable == PCH_DEVICE_ENABLE) {
+ Data32Or |= BIT30;
+ }
+
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable == PCH_DEVICE_ENABLE) {
+ Data32Or |= BIT31;
+ }
+
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable == PCH_DEVICE_ENABLE) {
+ Data32Or |= BIT14;
+ }
+
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable == PCH_DEVICE_ENABLE) {
+ Data32Or |= BIT15;
+ }
+
+ MmioAndThenOr32 (
+ PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_CIR33D4,
+ Data32And,
+ Data32Or
+ );
+
+ Data32And = 0xFFFFF0FF;
+ Data32Or = 0;
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection == 1) {
+ Data32Or |= B_PCH_RCRB_PMSYNC_GPIO_C_SEL;
+ }
+
+ if (MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection == 1) {
+ Data32Or |= B_PCH_RCRB_PMSYNC_GPIO_D_SEL;
+ }
+
+ MmioAndThenOr32 (
+ PchPlatformPolicyPpi->Rcba + R_PCH_RCRB_PMSYNC,
+ Data32And,
+ Data32Or
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize IOAPIC according to IoApicConfig policy of the PCH
+ Platform Policy PPI
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+PchIoApicInit (
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ )
+{
+ UINT32 RootComplexBar;
+ PCH_IOAPIC_CONFIG *IoApicConfig;
+ UINT32 IoApicAddress;
+ UINT32 IoApicId;
+
+ RootComplexBar = PchPlatformPolicyPpi->Rcba;
+ IoApicConfig = PchPlatformPolicyPpi->IoApicConfig;
+
+ if (IoApicConfig->ApicRangeSelect != MmioRead8 (RootComplexBar + R_PCH_RCRB_OIC)) {
+ ///
+ /// Program APIC Range Select bits that define address bits 19:12 for the IOxAPIC range.
+ /// This value must not be changed unless the IOxAPIC Enable bit is cleared.
+ ///
+ MmioAnd16 ((UINTN) (RootComplexBar + R_PCH_RCRB_OIC), (UINT16)~(B_PCH_RCRB_OIC_AEN));
+ ///
+ /// Program APIC Range Select bits at RCBA + 31FEh[7:0]
+ ///
+ MmioAndThenOr16 (
+ RootComplexBar + R_PCH_RCRB_OIC,
+ (UINT16)~(V_PCH_RCRB_OIC_ASEL),
+ (UINT16) IoApicConfig->ApicRangeSelect
+ );
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 6.6.2.1
+ /// 1. Enable the IOAPIC by setting the APIC Enable bit, RCBA + offset 31FFh, Bit[0] if the
+ /// system needs to use the IOxAPIC. The APIC Enable bits needs read back after the bit is written.
+ ///
+ MmioOr16 ((UINTN) (RootComplexBar + R_PCH_RCRB_OIC), (UINT16) B_PCH_RCRB_OIC_AEN);
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead16 (RootComplexBar + R_PCH_RCRB_OIC);
+
+ ///
+ /// Get current IO APIC ID
+ ///
+ IoApicAddress = (UINT32) (MmioRead8 (RootComplexBar + R_PCH_RCRB_OIC) << N_PCH_IO_APIC_ASEL);
+ MmioWrite8 ((UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress), 0);
+ IoApicId = MmioRead32 ((UINTN) (R_PCH_IO_APIC_DATA | IoApicAddress)) >> 24;
+ ///
+ /// IO APIC ID is at APIC Identification Register [27:24]
+ ///
+ if ((IoApicConfig->IoApicId != IoApicId) && (IoApicConfig->IoApicId < 0x10)) {
+ ///
+ /// Program APIC ID
+ ///
+ MmioWrite8 ((UINTN) (R_PCH_IO_APIC_INDEX | IoApicAddress), 0);
+ MmioWrite32 ((UINTN) (R_PCH_IO_APIC_DATA | IoApicAddress), (UINT32) (IoApicConfig->IoApicId << 24));
+ }
+
+ if (GetPchSeries() == PchLp) {
+ if (IoApicConfig->IoApicEntry24_39 == PCH_DEVICE_DISABLE) {
+ ///
+ /// Program IOAPIC Entry 24-39 Disable bit at RCBA + 31FEh[11]
+ ///
+ MmioOr16 (RootComplexBar + R_PCH_RCRB_OIC, (UINT16) B_PCH_RCRB_OIC_OA24_39_D);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function performs basic initialization for PCH in PEI phase.
+ If any of the base address arguments is zero, this function will disable the corresponding
+ decoding, otherwise this function will enable the decoding.
+ This function locks down the PMBase.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+PchInitialize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data8Or;
+ UINT8 Data8And;
+ PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi;
+#ifdef EFI_DEBUG
+ UINT8 Index;
+#endif
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ EFI_BOOT_MODE BootMode;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ UINTN AcpiBarAddress;
+ UINTN GpioBarAddress;
+
+ DEBUG ((EFI_D_INFO, "PchInitialize() - Start\n"));
+
+ ///
+ /// Get platform policy settings through the PchPlatformPolicy PPI
+ ///
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPchPlatformPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PchPlatformPolicyPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "\n------------------------ PchPlatformPolicyPpi Dump Begin -----------------\n"));
+ DEBUG ((EFI_D_INFO, "Revision : 0x%x\n", PchPlatformPolicyPpi->Revision));
+ DEBUG ((EFI_D_INFO, "BusNumber : 0x%x\n", PchPlatformPolicyPpi->BusNumber));
+ DEBUG ((EFI_D_INFO, "Rcba : 0x%x\n", PchPlatformPolicyPpi->Rcba));
+ DEBUG ((EFI_D_INFO, "PmBase : 0x%x\n", PchPlatformPolicyPpi->PmBase));
+ DEBUG ((EFI_D_INFO, "GpioBase : 0x%x\n", PchPlatformPolicyPpi->GpioBase));
+
+ DEBUG ((EFI_D_INFO, "PCH GBE Configuration --- \n"));
+ DEBUG ((EFI_D_INFO, " EnableGbe : 0x%x\n", PchPlatformPolicyPpi->GbeConfig->EnableGbe));
+
+ DEBUG ((EFI_D_INFO, "\n------------------------ PCH THERMAL Configuration -----------------\n"));
+ DEBUG ((EFI_D_INFO, "PCH MEMORY THERMAL MANAGEMENT --- \n"));
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->Enable : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->Enable)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection)
+ );
+ DEBUG (
+ (EFI_D_INFO,
+ "MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection : 0x%x\n",
+ PchPlatformPolicyPpi->ThermalMgmt->MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection)
+ );
+
+ DEBUG ((EFI_D_INFO, "PCH HPET Configuration --- \n"));
+ DEBUG ((EFI_D_INFO, " Enable : 0x%x\n", PchPlatformPolicyPpi->HpetConfig->Enable));
+ DEBUG ((EFI_D_INFO, " Base : 0x%x\n", PchPlatformPolicyPpi->HpetConfig->Base));
+
+ DEBUG ((EFI_D_INFO, "PCH RESERVED PAGE ROUTE --- \n"));
+ if (PchPlatformPolicyPpi->Port80Route == PchReservedPageToLpc) {
+ DEBUG ((EFI_D_INFO, " Port80Route : PchReservedPageToLpc\n"));
+ } else if (PchPlatformPolicyPpi->Port80Route == PchReservedPageToPcie) {
+ DEBUG ((EFI_D_INFO, " Port80Route : PchReservedPageToPciE\n"));
+ }
+
+ DEBUG ((EFI_D_INFO, "PCH SATA Mode --- \nSataMode : "));
+ switch (PchPlatformPolicyPpi->SataConfig->SataMode) {
+ case PchSataModeIde:
+ DEBUG ((EFI_D_INFO, "PchSataModeIde"));
+ break;
+ case PchSataModeAhci:
+ DEBUG ((EFI_D_INFO, "PchSataModeAhci"));
+ break;
+ case PchSataModeRaid:
+ DEBUG ((EFI_D_INFO, "PchSataModeRaid"));
+ break;
+ case PchSataModeLoopbackTest:
+ DEBUG ((EFI_D_INFO, "PchSataModeLoopbackTest"));
+ break;
+ default:
+ break;
+ }
+
+ DEBUG ((EFI_D_INFO, "\nPCH IO APIC Configuration --- \n"));
+ DEBUG ((EFI_D_INFO, " IoApicId : 0x%x\n", PchPlatformPolicyPpi->IoApicConfig->IoApicId));
+ DEBUG ((EFI_D_INFO, " ApicRangeSelect : 0x%x\n", PchPlatformPolicyPpi->IoApicConfig->ApicRangeSelect));
+
+ DEBUG ((EFI_D_INFO, "PCH PCIE Speed--- \n"));
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ if (PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] == PchPcieGen1) {
+ DEBUG ((EFI_D_INFO, " PCIE Port %x Speed: PchPcieGen1\n", Index));
+ } else if (PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] == PchPcieGen2) {
+ DEBUG ((EFI_D_INFO, " PCIE Port %x Speed: PchPcieGen2\n", Index));
+ } else if (PchPlatformPolicyPpi->PcieConfig->PcieSpeed[Index] == PchPcieAuto) {
+ DEBUG ((EFI_D_INFO, " PCIE Port %x Speed: PchPcieAuto\n", Index));
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "Platform Data Configuration --- \n"));
+ DEBUG ((EFI_D_INFO, " EcPresent : %x\n", PchPlatformPolicyPpi->PlatformData->EcPresent));
+ DEBUG ((EFI_D_INFO, " SmmBwp : %x\n", PchPlatformPolicyPpi->PlatformData->SmmBwp));
+
+ DEBUG ((EFI_D_INFO, "\n------------------------ PchPlatformPolicyPpi Dump End -----------------\n"));
+#endif
+ ///
+ /// Set Rcba
+ ///
+ ASSERT ((PchPlatformPolicyPpi->Rcba & (UINT32) (~B_PCH_LPC_RCBA_BAR)) == 0);
+ MmioAndThenOr32 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_RCBA),
+ (UINT32) (~B_PCH_LPC_RCBA_BAR),
+ PchPlatformPolicyPpi->Rcba | B_PCH_LPC_RCBA_EN
+ );
+
+ ///
+ /// Set PM Base
+ ///
+ AcpiBarAddress = MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE
+ );
+ MmioWrite32 (AcpiBarAddress, PchPlatformPolicyPpi->PmBase);
+ ASSERT ((MmioRead32 (AcpiBarAddress) & B_PCH_LPC_ACPI_BASE_BAR) == PchPlatformPolicyPpi->PmBase);
+ if (PchPlatformPolicyPpi->PmBase != 0) {
+ ///
+ /// Enable PM Base
+ ///
+ MmioOr8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_CNT),
+ (UINT8) B_PCH_LPC_ACPI_CNT_ACPI_EN
+ );
+ } else {
+ ///
+ /// Disable PM Base
+ ///
+ MmioAnd8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_CNT),
+ (UINT8) (~B_PCH_LPC_ACPI_CNT_ACPI_EN)
+ );
+ }
+ ///
+ /// Lock down the PM Base
+ ///
+ MmioOr8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_LOCK),
+ (UINT8) (B_PCH_LPC_GEN_PMCON_LOCK_ABASE_LK)
+ );
+
+ ///
+ /// Set GPIO Base
+ ///
+ GpioBarAddress = MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_BASE
+ );
+ MmioWrite32 (GpioBarAddress, PchPlatformPolicyPpi->GpioBase);
+ ASSERT ((MmioRead32 (GpioBarAddress) & B_PCH_LPC_GPIO_BASE_BAR) == PchPlatformPolicyPpi->GpioBase);
+ if (PchPlatformPolicyPpi->GpioBase != 0) {
+ ///
+ /// Enable GPIO Base
+ ///
+ MmioOr8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_CNT),
+ (UINT8) B_PCH_LPC_GPIO_CNT_GPIO_EN
+ );
+ } else {
+ ///
+ /// Disable GPIO Base
+ ///
+ MmioAnd8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GPIO_CNT),
+ (UINT8) (~B_PCH_LPC_GPIO_CNT_GPIO_EN)
+ );
+ }
+
+ if (PchPlatformPolicyPpi->PlatformData->SmmBwp == 0) {
+ ///
+ /// Clear SMM_BWP bit (D31:F0:RegDCh[5])
+ ///
+ Data8And = (UINT8) ~B_PCH_LPC_BIOS_CNTL_SMM_BWP;
+ Data8Or = 0x00;
+ } else {
+ ///
+ /// Set SMM_BWP and BLE bit (D31:F0:RegDCh[5][1])
+ ///
+ Data8And = 0xFF;
+ Data8Or = (UINT8) (B_PCH_LPC_BIOS_CNTL_SMM_BWP + B_PCH_LPC_BIOS_CNTL_BLE);
+ }
+
+ MmioAndThenOr8 (
+ MmPciAddress (0,
+ PchPlatformPolicyPpi->BusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ Data8And,
+ Data8Or
+ );
+
+ Status = PchSataInit (PeiServices, PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PchDmiMiscProg (PeiServices, PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PchGbeMandatedReset (PeiServices, PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PchMiscInit (PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+ Status = PchThermalInit (PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+ Status = PchIoApicInit (PchPlatformPolicyPpi);
+ ASSERT_EFI_ERROR (Status);
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ if (PchPlatformPolicyPpi->Revision > PCH_PLATFORM_POLICY_PPI_REVISION_1) {
+ ///
+ /// If it is in S3 boot path or recovery mode, do nothing
+ ///
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (!EFI_ERROR (Status)) {
+ if ((BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_IN_RECOVERY_MODE)) {
+ if (PchPlatformPolicyPpi->UsbConfig->UsbPrecondition) {
+
+ ///
+ /// Initialize PCH USB when USB_PRECONDITION feature is enabled by USB_CONFIG policy
+ /// Initialize PCH EHCI and XHCI by the same MMIO resource one by one
+ ///
+ Status = PchStartUsbInit (
+ PchPlatformPolicyPpi->UsbConfig,
+ PchPlatformPolicyPpi->PlatformData->TempMemBaseAddr,
+ PchPlatformPolicyPpi->PlatformData->TempMemBaseAddr,
+ PchPlatformPolicyPpi->Revision
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ DEBUG ((EFI_D_INFO, "PchInitialize() - End\n"));
+
+ ///
+ /// Install the PCH PEI Init Done PPI
+ ///
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiPchPeiInitDone);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Internal function performing miscellaneous init needed in very early PEI phase
+
+ @param[in] RootComplexBar RootComplexBar address of this PCH device
+
+ @retval None
+**/
+VOID
+PchMiscEarlyInit (
+ IN UINT32 RootComplexBar
+ )
+{
+ UINTN PciD31F0RegBase;
+ UINT8 Nmi;
+ UINT8 Data8;
+ UINT32 Data32Or;
+
+ DEBUG ((EFI_D_INFO, "PchMiscEarlyInit() - Start\n"));
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.3 PCH Display Port Enable
+ /// Step 1
+ /// Set RCBA + 3424h = 0010h
+ ///
+ MmioWrite16 ((UINTN) (RootComplexBar + R_PCH_RCRB_DISPBDF), (UINT16) 0x10);
+
+ ///
+ /// Step 2
+ /// Set RCBA + 3428h[0] = 1b
+ ///
+ Data32Or = B_PCH_RCRB_FD2_DBDFEN;
+ MmioOr32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FD2), Data32Or);
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.3 Power Failure Considerations
+ /// RTC_PWR_STS bit, GEN_PMCON_3 (D31:F0:A4h[2])
+ /// When the RTC_PWR_STS bit is set, it indicates that the RTCRST# signal went low.
+ /// Software should clear this bit. For example, changing the RTC battery sets this bit.
+ /// System BIOS should reset CMOS to default values if the RTC_PWR_STS bit is set.
+ /// The System BIOS should execute the sequence below if the RTC_PWR_STS bit is set
+ /// before memory initialization. This will ensure that the RTC state machine has been
+ /// initialized.
+ /// 1. If the RTC_PWR_STS bit is set which indicates a new coin-cell battery insertion or a
+ /// battery failure, steps 2 through 5 should be executed.
+ /// 2. Set RTC Register 0Ah[6:4] to 110b or 111b
+ /// 3. Set RTC Register 0Bh[7].
+ /// 4. Set RTC Register 0Ah[6:4] to 010b
+ /// 5. Clear RTC Register 0Bh[7].
+ ///
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+
+ if ((MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3) &
+ (UINT16) B_PCH_LPC_GEN_PMCON_RTC_PWR_STS) != 0) {
+ ///
+ /// Enable Alternate Access Mode
+ /// Note: The RTC Index field (including the NMI mask at bit7) is write-only
+ /// for normal operation and can only be read in Alt Access Mode.
+ ///
+ PchAlternateAccessMode (RootComplexBar, TRUE);
+ ///
+ /// Read NMI Enable bit
+ ///
+ Nmi = IoRead8 (R_PCH_NMI_EN) & (UINT8) B_PCH_NMI_EN_NMI_EN;
+ ///
+ /// Disable Alternate Access Mode
+ ///
+ PchAlternateAccessMode (RootComplexBar, FALSE);
+ ///
+ /// 2. Set RTC Register 0Ah[6:4] to 110b or 111b
+ ///
+ IoWrite8 (R_PCH_RTC_INDEX, (UINT8) (R_PCH_RTC_REGA | Nmi));
+ Data8 = IoRead8 (R_PCH_RTC_TARGET) & (UINT8) ~(BIT6 | BIT5 | BIT4);
+ Data8 |= (UINT8) (BIT6 | BIT5);
+ IoWrite8 (R_PCH_RTC_TARGET, Data8);
+ ///
+ /// 3. Set RTC Register 0Bh[7].
+ ///
+ IoWrite8 (R_PCH_RTC_INDEX, (UINT8) (R_PCH_RTC_REGB | Nmi));
+ IoOr8 (R_PCH_RTC_TARGET, (UINT8) B_PCH_RTC_REGB_SET);
+ ///
+ /// 4. Set RTC Register 0Ah[6:4] to 010b
+ ///
+ IoWrite8 (R_PCH_RTC_INDEX, (UINT8) (R_PCH_RTC_REGA | Nmi));
+ Data8 = IoRead8 (R_PCH_RTC_TARGET) & (UINT8) ~(BIT6 | BIT5 | BIT4);
+ Data8 |= (UINT8) (BIT5);
+ IoWrite8 (R_PCH_RTC_TARGET, Data8);
+ ///
+ /// 5. Clear RTC Register 0Bh[7].
+ ///
+ IoWrite8 (R_PCH_RTC_INDEX, (UINT8) (R_PCH_RTC_REGB | Nmi));
+ IoAnd8 (R_PCH_RTC_TARGET, (UINT8) ~B_PCH_RTC_REGB_SET);
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 19.1 Handling Status Registers
+ /// System BIOS must set 1b to clear the following registers during power-on
+ /// and resuming from Sx sleep state.
+ /// - RCBA + Offset 3310h[0] = 1b
+ /// Done in ConfigureMiscItems ()
+ /// - RCBA + Offset 3310h[4] = 1b, needs to be done as early as possible during PEI
+ /// - RCBA + Offset 3310h[5] = 1b
+ /// Done in ConfigureMiscItems ()
+ ///
+ MmioWrite32 (
+ (UINTN) (RootComplexBar + R_PCH_RCRB_PRSTS),
+ (UINT32) (B_PCH_RCRB_PRSTS_FIELD_1)
+ );
+
+ DEBUG ((EFI_D_INFO, "PchMiscEarlyInit() - End\n"));
+
+ return;
+}
+
+///
+/// Entry point
+///
+
+/**
+ Installs the PCH PEI Init PPI
+ Performing Pch early init after PchPlatfromPolicy PPI produced
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+**/
+EFI_STATUS
+EFIAPI
+InstallPchInitPpi (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINT32 RootComplexBar;
+ EFI_PEI_PPI_DESCRIPTOR *PchDmiTcVcMapPpiDesc;
+ PCH_DMI_TC_VC_PPI *PchDmiTcVcMapPpi;
+
+ DEBUG ((EFI_D_INFO, "InstallPchInitPpi() - Start\n"));
+
+ ///
+ /// Check if Rcba has been set
+ ///
+ RootComplexBar = PCH_RCRB_BASE;
+ DEBUG ((EFI_D_INFO, "Rcba needs to be programmed before here\n"));
+ ASSERT ((RootComplexBar & (UINT32) (~B_PCH_LPC_RCBA_BAR)) == 0);
+ ///
+ /// Perform miscellaneous init needed in very early PEI phase
+ ///
+ PchMiscEarlyInit (RootComplexBar);
+
+ ///
+ /// Install the DMI TC VC PPI
+ /// Allocate descriptor and PPI structures. Since these are dynamically updated
+ ///
+ PchDmiTcVcMapPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ if (PchDmiTcVcMapPpiDesc == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for PchDmiTcVcMapPpiDesc! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PchDmiTcVcMapPpi = (PCH_DMI_TC_VC_PPI *) AllocateZeroPool (sizeof (PCH_DMI_TC_VC_PPI));
+ if (PchDmiTcVcMapPpi == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for PchDmiTcVcMapPpi! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CopyMem (PchDmiTcVcMapPpi, &mPchDmiTcVcMap, sizeof (PCH_DMI_TC_VC_PPI));
+
+ PchDmiTcVcMapPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PchDmiTcVcMapPpiDesc->Guid = &gPchDmiTcVcMapPpiGuid;
+ PchDmiTcVcMapPpiDesc->Ppi = PchDmiTcVcMapPpi;
+ Status = (**PeiServices).InstallPpi (PeiServices, PchDmiTcVcMapPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install the PCH PEI Init PPI
+ ///
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiListVariable);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Performing Pch early init after PchPlatfromPolicy PPI produced
+ ///
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mNotifyList);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mPchS3ResumeNotifyDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InstallPchInitPpi() - End\n"));
+
+ return Status;
+}
+
+/**
+ This function trigger SMI through Iotrap to perform PCH register save and restore in SMI
+
+ @param[in] PeiServices - Pointer to PEI Services Table.
+ @param[in] NotifyDesc - Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi - Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS - Always return EFI_SUCCESS
+**/
+EFI_STATUS
+PchS3ResumeAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ PCH_LATE_INIT_SMM_VARIABLE SaveRestoreData;
+ UINTN VariableSize;
+ PEI_READ_ONLY_VARIABLE_PPI *VariableServices;
+
+ Status = PeiServicesGetBootMode (&BootMode);
+ DEBUG ((EFI_D_INFO, "[PCH] BootMode = %X\n", BootMode));
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ return EFI_SUCCESS;
+ }
+ ///
+ /// Locate Variable Ppi
+ ///
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiReadOnlyVariablePpiGuid, 0, NULL, &VariableServices);
+ ASSERT_EFI_ERROR (Status);
+
+ VariableSize = sizeof (PCH_LATE_INIT_SMM_VARIABLE);
+ Status = VariableServices->PeiGetVariable (
+ PeiServices,
+ PCH_INIT_PEI_VARIABLE_NAME,
+ &gPchInitPeiVariableGuid,
+ NULL,
+ &VariableSize,
+ &SaveRestoreData
+ );
+
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ ///
+ /// Write to IO trap address to trigger SMI for register restoration
+ ///
+ DEBUG ((EFI_D_INFO, "S3 SMI register restoration\n"));
+ IoWrite16 (SaveRestoreData.IoTrapAddress, 0x0);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif
new file mode 100644
index 0000000..f8cc797
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "PchInitPeim"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchInit\Pei"
+ RefName = "PchInitPeim"
+[files]
+"PchInitPeim.sdl"
+"PchInitPeim.mak"
+"PchInitPeim.h"
+"PchInitPeim.c"
+"PchInitPeim.dxs"
+"PchInitPeim.inf"
+"PchUsbInit.c"
+"PchInitCommon.h"
+"PchDmiPeim.c"
+"PchUsbPreconditionPeim.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs
new file mode 100644
index 0000000..a2a2f80
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.dxs
@@ -0,0 +1,39 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "PeimDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h
new file mode 100644
index 0000000..1e433db
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.h
@@ -0,0 +1,253 @@
+/** @file
+ Header file for the PCH Init PEIM
+
+@copyright
+ Copyright (c) 2004 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _PCH_INIT_PEIM_H_
+#define _PCH_INIT_PEIM_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGluePeim.h"
+#include "PchInitVar.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchUsbCommon.h"
+#include "IobpDefinitions.h"
+#include "PchHsio.h"
+#include EFI_PPI_PRODUCER (PchInit)
+#include EFI_PPI_PRODUCER (PchDmiTcVcMap)
+#include EFI_PPI_CONSUMER (MemoryDiscovered)
+#include EFI_PPI_CONSUMER (PchUsbPolicy)
+#include EFI_PPI_CONSUMER (PchPlatformPolicy)
+#include EFI_PPI_CONSUMER (PchReset)
+#include EFI_PPI_PRODUCER (PchPeiInitDone)
+#endif
+
+//
+// ChipsetInit settings defines
+//
+#define H2M_HSIO_MESSAGE (0x7 << 28)///< Master type for all H2M Hsio messages
+#define H2M_HSIO_CMD_GETHSIOVER 1 ///< Triggers Hsio version to be sent through ME/Host FW Status registers
+#define H2M_HSIO_CMD_CLOSE 0 ///< Triggers H2M Hsio interface to close and revert FW Status registers
+#define M2H_HSIO_MSG_ACK 0x7 ///< Ack sent in response to any H2M Hsio messages
+#define MAX_ME_MSG_ACK_TIMEOUT 0x186A0 // Wait max of 100ms for FW to acknowledge.
+
+/**
+ Internal function performing SATA init needed in PEI phase
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval None
+**/
+EFI_STATUS
+EFIAPI
+PchSataInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ );
+
+/**
+ This function may trigger platform reset depending on the current GbE status,
+ the intended GbE enabling, and current ME status. (When ME is enabled, this function
+ may trigger a Global reset.)
+ This function may not return if it triggers an platform reset and the BIOS boot flow
+ restarts.
+ If this function returns EFI_SUCCESS it indicates there is no need for platform
+ reset in this boot, and boot flow continues.
+ If this function returns EFI_DEVICE_ERROR, something error happens.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS No platform reset action is taken. System can continue boot flow.
+ @retval Others Won't return if platform reset action is taken
+**/
+EFI_STATUS
+EFIAPI
+PchGbeMandatedReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ );
+
+/**
+ Perform Thermal Management Support initialization
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+PchThermalInit (
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ );
+
+/**
+ Initialize IOAPIC according to IoApicConfig policy of the PCH
+ Platform Policy PPI
+
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+PchIoApicInit (
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ );
+
+/**
+ This function performs basic initialization for PCH in PEI phase.
+ If any of the base address arguments is zero, this function will disable the corresponding
+ decoding, otherwise this function will enable the decoding.
+ This function locks down the PMBase.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] NotifyDescriptor The notification structure this PEIM registered on install.
+ @param[in] Ppi The memory discovered PPI. Not used.
+
+ @retval EFI_SUCCESS Succeeds.
+ @retval EFI_DEVICE_ERROR Device error, aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+PchInitialize (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ The function performing USB init in PEI phase. This could be used by USB recovery
+ or debug features that need USB initialization during PEI phase.
+ Note: Before executing this function, please be sure that PCH_INIT_PPI.Initialize
+ has been done and PchUsbPolicyPpi has been installed.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+PchUsbInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ The function performing TC/VC mapping program, and poll all PCH Virtual Channel
+ until negotiation completion
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+PchDmiTcVcProgPoll (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ The function set the Target Link Speed in PCH to DMI GEN 2.
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchDmiGen2Prog (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ The function program DMI miscellaneous registers.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+ @param[in] PchPlatformPolicyPpi The PCH Platform Policy PPI instance
+
+ @retval EFI_SUCCESS The DMI required settings programmed correctly
+**/
+EFI_STATUS
+EFIAPI
+PchDmiMiscProg (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi
+ );
+
+/**
+ The function is used while doing CPU Only Reset, where PCH may be required
+ to initialize strap data before soft reset.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+ @param[in] Operation Get/Set Cpu Strap Set Data
+ @param[in, out] CpuStrapSet Cpu Strap Set Data
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @exception EFI_UNSUPPORTED The function is not supported.
+**/
+EFI_STATUS
+EFIAPI
+PchCpuStrapSet (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CPU_STRAP_OPERATION Operation,
+ IN OUT UINT16 *CpuStrapSet
+ );
+
+/**
+ The function performing USB init in PEI phase. This could be
+ used by USB recovery ,debug features or usb precondition
+ enabled case that need USB initialization during PEI phase.
+ Please be sure the function should not be executed in if the
+ boot mode is S3 resume.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+PchStartUsbInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMemBaseAddr,
+ IN UINT32 XhciMemBaseAddr,
+ IN UINT8 Revision
+ );
+
+/**
+ This function handles Pch S3 resume task
+
+ @param[in] PeiServices - Pointer to PEI Services Table.
+ @param[in] NotifyDesc - Pointer to the descriptor for the Notification event that
+ caused this function to execute.
+ @param[in] Ppi - Pointer to the PPI data associated with this function.
+
+ @retval EFI_STATUS - Always return EFI_SUCCESS
+**/
+EFI_STATUS
+PchS3ResumeAtEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf
new file mode 100644
index 0000000..02e4639
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.inf
@@ -0,0 +1,108 @@
+## @file
+# Component description file for the PCH Init PEIM.
+#
+#@copyright
+# Copyright (c) 2004 - 2013 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchInitPeim
+FILE_GUID = FD236AE7-0791-48c4-B29E-29BDEEE1A838
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchInitPeim.h
+ PchInitPeim.c
+ PchUsbInit.c
+ ../Common/PchUsbCommon.c
+ ../Common/PchInitVar.c
+ ../Common/PchHsio.c
+ ../Common/PchHsioLptHB0.c
+ ../Common/PchHsioLptHCx.c
+ ../Common/PchHsioLptLpBx.c
+ PchDmiPeim.c
+
+ PchUsbPreconditionPeim.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Guid/ChipsetInitHob
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Heci/Include
+ $(EFI_SOURCE)/$(PROJECT_ME_ROOT)/Library/MeKernel/include
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/library/Pei/Include
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include
+
+[libraries.common]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGluePeiFirmwarePerformanceLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkPpiLib
+ PchPlatformLib
+ PeiLib
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkIIGluePeiFirmwarePerformanceLib
+ PchPlatformLib
+ MeLibPpi
+ MeGuidLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchInitPeim.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchInitPpi
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ -D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak
new file mode 100644
index 0000000..0bd26c3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.mak
@@ -0,0 +1,117 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitPeim/PchInitPeim.mak 4 12/18/12 4:53a Scottyang $
+#
+# $Revision: 4 $
+#
+# $Date: 12/18/12 4:53a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitPeim/PchInitPeim.mak $
+#
+# 4 12/18/12 4:53a Scottyang
+# [TAG] EIP109697
+# [Category] Improvement
+# [Description] Update PCH RC 0.8.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 3 11/20/12 8:36a Scottyang
+# [TAG] EIP107014
+# [Category] Improvement
+# [Description] Update RC 0.8.0
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 2 2/24/12 2:13a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:53a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchInitPeim module
+#---------------------------------------------------------------------------
+EDK : PchInitPeim
+PchInitPeim : $(BUILD_DIR)\PchInitPeim.mak PchInitPeimBin
+
+
+$(BUILD_DIR)\PchInitPeim.mak : $(PchInitPeim_DIR)\$(@B).cif $(PchInitPeim_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchInitPeim_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchInitPeim_INCLUDES=\
+ /I$(INTEL_PCH_DIR)\PchInit\Common\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(INTEL_PCH_DIR)\Guid\SurvivabilityHob\
+ $(ME_INCLUDES)\
+
+PchInitPeim_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchInitPpi"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ /D __EDKII_GLUE_PEI_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchInitPeim_LIB_LINKS =\
+ $(GuidLib_LIB) \
+ $(PchPlatformPeiLib_LIB) \
+ $(IntelPchPpiLib_LIB)\
+ $(EDKFRAMEWORKPPILIB) \
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB) \
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB) \
+ $(EdkIIGluePeiReportStatusCodeLib_LIB) \
+ $(EdkIIGluePeiServicesLib_LIB) \
+ $(EdkIIGluePeiMemoryAllocationLib_LIB) \
+ $(EdkIIGlueBasePciLibCf8_LIB) \
+ $(PchUsbCommonPeiLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(PEILIB)
+
+PchInitPeimBin: $(PchInitPeim_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchInitPeim.mak all \
+ "MY_INCLUDES=$(PchInitPeim_INCLUDES)"\
+ "MY_DEFINES=$(PchInitPeim_DEFINES)"\
+ NAME=PchInitPeim\
+ MAKEFILE=$(BUILD_DIR)\PchInitPeim.mak \
+ GUID=FD236AE7-0791-48c4-B29E-29BDEEE1A838\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchInitPeim_DIR)\PchInitPeim.dxs\
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX\
+ COMPRESS=0
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl
new file mode 100644
index 0000000..cfde1c7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchInitPeim.sdl
@@ -0,0 +1,67 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitPeim/PchInitPeim.sdl 1 2/08/12 8:53a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:53a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchInitPeim/PchInitPeim.sdl $
+#
+# 1 2/08/12 8:53a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchInitPeim_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchInitPeim support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchInitPeim_DIR"
+End
+
+MODULE
+ File = "PchInitPeim.mak"
+ Help = "Includes PchInitPeim.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchInitPeim.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c
new file mode 100644
index 0000000..44381fc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbInit.c
@@ -0,0 +1,198 @@
+/** @file
+ Initializes PCH USB Controllers.
+
+@copyright
+ Copyright (c) 2009 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include "PchInitPeim.h"
+
+/**
+ The function performing USB init in PEI phase. This could be used by USB recovery
+ or debug features that need USB initialization during PEI phase.
+ Note: Before executing this function, please be sure that PCH_INIT_PPI.Initialize
+ has been done and PchUsbPolicyPpi has been installed.
+
+ @param[in] PeiServices General purpose services available to every PEIM
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+PchUsbInit (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ PCH_USB_POLICY_PPI *PchUsbPolicyPpi;
+
+ DEBUG ((EFI_D_INFO, "PchUsbInit() - Start\n"));
+
+ ///
+ /// Get PchUsbPolicy PPI for PCH_USB_CONFIG
+ ///
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPchUsbPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&PchUsbPolicyPpi
+ );
+
+ if (Status == EFI_SUCCESS) {
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "\n------------------------ PchUsbPolicyPpi Dump Begin -----------------\n"));
+ DEBUG ((EFI_D_INFO, "Revision : 0x%x\n", PchUsbPolicyPpi->Revision));
+ DEBUG ((EFI_D_INFO, "Mode : 0x%x\n", PchUsbPolicyPpi->Mode));
+ DEBUG ((EFI_D_INFO, "EhciMemBaseAddr : 0x%x\n", PchUsbPolicyPpi->EhciMemBaseAddr));
+ DEBUG ((EFI_D_INFO, "EhciMemLength : 0x%x\n", PchUsbPolicyPpi->EhciMemLength));
+ DEBUG ((EFI_D_INFO, "XhciMemBaseAddr : 0x%x\n", PchUsbPolicyPpi->XhciMemBaseAddr));
+#endif
+ Status = PchStartUsbInit (
+ PchUsbPolicyPpi->UsbConfig,
+ (UINT32) PchUsbPolicyPpi->EhciMemBaseAddr,
+ (UINT32) PchUsbPolicyPpi->XhciMemBaseAddr,
+ PchUsbPolicyPpi->Revision
+ );
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "\n------------------------ PchUsbPolicyPpi Dump End -----------------\n"));
+#endif
+ }
+ DEBUG ((EFI_D_INFO, "PchUsbInit() - End\n"));
+ return Status;
+}
+
+/**
+ The function performing USB init in PEI phase. This could be
+ used by USB recovery ,debug features or usb precondition
+ enabled case that need USB initialization during PEI phase.
+ Please be sure the function should not be executed in if the
+ boot mode is S3 resume.
+
+ @param[in] UsbConfig Pointer to a PCH_USB_CONFIG that provides the platform setting
+ @param[in] EhciMemBaseAddr Predefined Ehci memory base address for Ehci hc configuration
+ @param[in] XhciMemBaseAddr Predefined Xhci memory base address for Xhci hc configuration
+ @param[in] Revision Revision of PCH_USB_CONFIG
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT
+**/
+EFI_STATUS
+PchStartUsbInit (
+ IN PCH_USB_CONFIG *UsbConfig,
+ IN UINT32 EhciMemBaseAddr,
+ IN UINT32 XhciMemBaseAddr,
+ IN UINT8 Revision
+ )
+{
+ EFI_STATUS Status;
+ UINT32 RootComplexBar;
+ UINT32 FuncDisableReg;
+#ifdef EFI_DEBUG
+ UINT8 i;
+#endif
+
+ DEBUG ((EFI_D_INFO, "PchStartUsbInit() - Start\n"));
+ Status = EFI_INVALID_PARAMETER;
+ if (UsbConfig != NULL) {
+#ifdef EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Revision : 0x%x\n", Revision));
+ DEBUG ((EFI_D_INFO, "EhciMemBaseAddr : 0x%x\n", EhciMemBaseAddr));
+ DEBUG ((EFI_D_INFO, "XhciMemBaseAddr : 0x%x\n", XhciMemBaseAddr));
+
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "------------------------ PCH_USB_CONFIG Dump Start -----------------\n"));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG UsbPerPortCtl= %x\n", UsbConfig->UsbPerPortCtl));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Ehci1Usbr= %x\n", UsbConfig->Ehci1Usbr));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Ehci2Usbr= %x\n", UsbConfig->Ehci2Usbr));
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG PortSettings[%d] Enabled= %x\n", i, UsbConfig->PortSettings[i].Enable));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG PortSettings[%d] Location = %x\n", i, UsbConfig->PortSettings[i].Location));
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Port30Settings[%d] Enabled= %x\n", i, UsbConfig->Port30Settings[i].Enable));
+ }
+
+ for (i = 0; i < GetPchEhciMaxControllerNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20Settings[%d] Enabled= %x\n", i, UsbConfig->Usb20Settings[i].Enable));
+ }
+
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.Mode= %x\n", UsbConfig->Usb30Settings.Mode));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.PreBootSupport= %x\n", UsbConfig->Usb30Settings.PreBootSupport));
+ DEBUG ((EFI_D_INFO, " XhciStreams is obsoleted, it doesn't effect any setting change since Revision 2.\n"));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualMode= %x\n", UsbConfig->Usb30Settings.ManualMode));
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.XhciIdleL1= %x\n", UsbConfig->Usb30Settings.XhciIdleL1));
+
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ if (UsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[i] == 0) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualModeUsb20PerPinRoute[%d]= EHCI\n", i));
+ } else {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30Settings.ManualModeUsb20PerPinRoute[%d]= XHCI\n", i));
+ }
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO,
+ "PCH_USB_CONFIG Usb30Settings.ManualModeUsb30PerPinEnable[%d]= %x\n",
+ i,
+ UsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[i]));
+ }
+
+ for (i = 0; i < GetPchUsbMaxPhysicalPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20OverCurrentPins[%d]= OC%x\n", i, UsbConfig->Usb20OverCurrentPins[i]));
+ }
+
+ for (i = 0; i < GetPchXhciMaxUsb3PortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb30OverCurrentPins[%d]= OC%x\n", i, UsbConfig->Usb30OverCurrentPins[i]));
+ }
+
+ for (i = 0; i < GetPchEhciMaxUsbPortNum (); i++) {
+ DEBUG ((EFI_D_INFO, " PCH_USB_CONFIG Usb20PortLength[%d]= %x.%0x\n", i, UsbConfig->PortSettings[i].Usb20PortLength >> 4, UsbConfig->PortSettings[i].Usb20PortLength & 0xF));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+ DEBUG ((EFI_D_INFO, "\n------------------------ PCH_USB_CONFIG Dump End -----------------\n"));
+#endif
+ RootComplexBar = PCH_RCRB_BASE;
+ FuncDisableReg = MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS);
+
+ Status = CommonUsbInit (
+ UsbConfig,
+ (UINT32) EhciMemBaseAddr,
+ (UINT32) XhciMemBaseAddr,
+ 0,
+ RootComplexBar,
+ &FuncDisableReg,
+ Revision
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ MmioWrite32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS), (UINT32) (FuncDisableReg));
+ //
+ // Reads back for posted write to take effect
+ //
+ MmioRead32 ((UINTN) (RootComplexBar + R_PCH_RCRB_FUNC_DIS));
+ }
+
+ DEBUG ((EFI_D_INFO, "PchStartUsbInit() - End\n"));
+
+ return Status;
+
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c
new file mode 100644
index 0000000..0735fd6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Pei/PchUsbPreconditionPeim.c
@@ -0,0 +1,105 @@
+/** @file
+
+ PCH USB precondition feature support in PEI phase
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchInitPeim.h"
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+
+extern USB_CONTROLLER EhciControllersMap[];
+
+/**
+ Perform USB precondition on EHCI, it is the HC on USB HC in PEI phase
+
+ @param[in] Device The device number of the EHCI
+ @param[in] EhciMmioBase Memory base address of EHCI Controller
+
+ @retval None
+**/
+VOID
+EhciPrecondition (
+ IN UINT8 Device,
+ IN UINT32 EhciMmioBase
+ )
+{
+ UINTN HcResetTimeout;
+
+ HcResetTimeout = 0;
+ while ((HcResetTimeout < 200) &&
+ (MmioRead32 (EhciMmioBase + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_HCRESET)) {
+ PchPmTimerStall (100);
+ HcResetTimeout++;
+ }
+
+ if ((MmioRead32 (EhciMmioBase + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_HCRESET) == 0) {
+ //
+ // Route all ports to this EHCI
+ //
+ MmioWrite32 ((EhciMmioBase + R_PCH_EHCI_CONFIGFLAG), BIT0);
+ }
+}
+
+/**
+ Perform USB precondition on XHCI, it is the HC on USB HC in PEI phase
+
+ @param[in] BusNumber The Bus number of the XHCI
+ @param[in] Device The device number of the XHCI
+ @param[in] Function The function number of the XHCI
+ @param[in] XhciMmioBase Memory base address of XHCI Controller
+ @param[in] XhciUSB2Ptr Pointer to USB2 protocol port register
+ @param[in] HsPortCount The number of USB2 protocol port supported by this XHCI
+
+ @retval None
+**/
+VOID
+XhciPrecondition (
+ IN UINT8 BusNumber,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 XhciMmioBase,
+ IN UINTN *XhciUSB2Ptr,
+ IN UINTN HsPortCount,
+ IN UINTN *XhciUSB3Ptr,
+ IN UINTN SsPortCount
+ )
+{
+ UINT32 Data32;
+ UINTN HcHaltTimeout;
+
+ //
+ // Set the XHC to halt state before reset
+ //
+ HcHaltTimeout = 0;
+ if (!(MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0)) {
+ Data32 = MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBCMD);
+ MmioWrite32 ((XhciMmioBase + R_PCH_XHCI_USBCMD), (Data32 &~B_PCH_XHCI_USBCMD_RS));
+ while ((HcHaltTimeout < 200) &&
+ (!(MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0))) {
+ PchPmTimerStall (100);
+ HcHaltTimeout++;
+ }
+ }
+
+ if (MmioRead32 (XhciMmioBase + R_PCH_XHCI_USBSTS) & BIT0) {
+ MmioOr16 ((XhciMmioBase + R_PCH_XHCI_USBCMD), BIT1);
+ }
+}
+
+#endif // USB_PRECONDITION_ENABLE_FLAG
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c
new file mode 100644
index 0000000..e29c5a1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.c
@@ -0,0 +1,753 @@
+/** @file
+ PCH S3 Save and Restore SMM Driver Entry
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#include "PchLateInitSmm.h"
+
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_Common[] = {
+ {Acpi, R_PCH_ACPI_PM1_EN, 0, BIT14, 2},
+ {Rcrb, 0x3300, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x3304, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x3308, 0, 0xFFFFFFFF, 4},
+ {Rcrb, 0x330C, 0, 0xFFFFFFFF, 4}
+};
+
+#ifdef TRAD_FLAG
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_PchH[] = {
+ {Acpi, R_PCH_ACPI_GPE0a_EN, 0, 0xFFFF0246, 4},
+ {Acpi, R_PCH_ACPI_GPE0b_EN, 0, 0xFF000040, 4},
+ {Tco , R_PCH_TCO2_CNT , 0, BIT5 | BIT4, 1}
+};
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+STATIC PCH_SAVE_RESTORE_REG PchSaveRestoreReg_PchLp[] = {
+ {Rcrb, 0x3320, 0, 0xFFFFFFFF, 4}
+};
+#endif // ULT_FLAG
+
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_Common[] = {
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, 0, R_PCH_HDA_PCS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, PCI_BASE_ADDRESSREG_OFFSET, R_HDA_WAKEEN, 0, BIT3 | BIT2 | BIT1 | BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_USB, 0, 0, R_PCH_EHCI_PWR_CNTL_STS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_CONFIGFLAG, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 2, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 6, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 10, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 14, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 18, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 22, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 26, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 30, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 34, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 38, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_PWR_CNTL_STS + 1, 0, BIT0 | BIT7, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_USB2PR, 0, 0x7FFF, 2, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_XHCI, 0, 0, R_PCH_XHCI_USB3PR, 0, 0x3F, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 0, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 1, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 2, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 3, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 4, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 5, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL}
+};
+
+#ifdef TRAD_FLAG
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_PchH[] = {
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, 0, R_PCH_EHCI_PWR_CNTL_STS + 1, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_CONFIGFLAG, 0, BIT0, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 2, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 6, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 10, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 14, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 18, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 22, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 26, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 30, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 34, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, PCI_BASE_ADDRESSREG_OFFSET, R_PCH_EHCI_PORTSC0 + 38, 0, BIT6 | BIT5 | BIT4, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 6, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL},
+ {PciCfg, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 7, 0, R_PCH_PCIE_PMCS + 1, 0, BIT0, 1, NULL}
+};
+#endif // TRAD_FLAG
+
+#ifdef ULT_FLAG
+STATIC PCH_SAVE_RESTORE_PCI PchSaveRestorePciReg_PchLp[] = {
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P0DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P1DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp},
+ {PciMmr, PCI_DEVICE_NUMBER_PCH_SATA, 2, R_PCH_SATA_AHCI_BAR, R_PCH_SATA_AHCI_P3DEVSLP, 0, 0x1FFFFFFF, 4, RestorePxDevSlp}
+};
+#endif // ULT_FLAG
+DEVICE_POWER_STATE DevicePowerState[] = {
+ {PCI_DEVICE_NUMBER_PCH_AZALIA, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_USB_EXT, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_USB, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_XHCI, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 0, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 1, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 2, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 3, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 4, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 5, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 6, DeviceD0},
+ {PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, 7, DeviceD0}
+};
+
+PCH_SAVE_RESTORE_PCI_WRAP PchSaveRestorePciRegWrap[] = {
+#ifdef TRAD_FLAG
+ {PchSaveRestorePciReg_Common, ARRAY_SIZE(PchSaveRestorePciReg_Common), PchH},
+ {PchSaveRestorePciReg_PchH, ARRAY_SIZE (PchSaveRestorePciReg_PchH), PchH}
+#endif // TRAD_FLAG
+#if (defined ULT_FLAG) && (defined TRAD_FLAG)
+ ,
+#endif // ULT_FLAG && TRAD_FLAG
+#ifdef ULT_FLAG
+ {PchSaveRestorePciReg_Common, ARRAY_SIZE(PchSaveRestorePciReg_Common), PchLp},
+ {PchSaveRestorePciReg_PchLp, ARRAY_SIZE(PchSaveRestorePciReg_PchLp), PchLp}
+#endif // ULT_FLAG
+};
+
+PCH_SAVE_RESTORE_REG_WRAP PchSaveRestoreRegWrap[] = {
+#ifdef TRAD_FLAG
+ {PchSaveRestoreReg_Common, ARRAY_SIZE(PchSaveRestoreReg_Common), PchH},
+ {PchSaveRestoreReg_PchH, ARRAY_SIZE(PchSaveRestoreReg_PchH), PchH}
+#endif // TRAD_FLAG
+#if (defined ULT_FLAG) && (defined TRAD_FLAG)
+ ,
+#endif // ULT_FLAG && TRAD_FLAG
+#ifdef ULT_FLAG
+ {PchSaveRestoreReg_Common, ARRAY_SIZE(PchSaveRestoreReg_Common), PchLp},
+ {PchSaveRestoreReg_PchLp, ARRAY_SIZE(PchSaveRestoreReg_PchLp), PchLp}
+#endif // ULT_FLAG
+};
+
+UINT32 PciMemBase = 0;
+
+/**
+
+ Find the Offset to a given Capabilities ID
+ CAPID list:
+ 0x01 = PCI Power Management Interface
+ 0x04 = Slot Identification
+ 0x05 = MSI Capability
+ 0x10 = PCI Express Capability
+
+ @param[in] Bus - Pci Bus Number
+ @param[in] Device - Pci Device Number
+ @param[in] Func - Pci Function Number
+ @param[in] CapId - CAPID to search for
+
+ @retval 0 - CAPID not found
+ @retval Other - CAPID found, Offset of desired CAPID
+
+**/
+UINT8
+PcieFindCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Func,
+ IN UINT8 CapId
+ )
+{
+ UINT8 CapHeader;
+
+ ///
+ /// Always start at Offset 0x34
+ ///
+ CapHeader = MmioRead8 (MmPciAddress (0, Bus, Device, Func, PCI_CAPBILITY_POINTER_OFFSET));
+ if (CapHeader == 0xFF) {
+ return 0;
+ }
+
+ while (CapHeader != 0) {
+ ///
+ /// Bottom 2 bits of the pointers are reserved per PCI Local Bus Spec 2.2
+ ///
+ CapHeader &= ~(BIT1 | BIT0);
+ ///
+ /// Search for desired CapID
+ ///
+ if (MmioRead8 (MmPciAddress (0, Bus, Device, Func, CapHeader)) == CapId) {
+ return CapHeader;
+ }
+
+ CapHeader = MmioRead8 (MmPciAddress (0, Bus, Device, Func, CapHeader + 1));
+ }
+
+ return 0;
+}
+
+/**
+
+ Save Device Power State and restore later
+
+ @param[in] Device - Pci Device Number
+ @param[in] Function - Pci Function Number
+
+ @retval None
+
+**/
+VOID
+SaveDevPowState (
+ IN UINT8 Device,
+ IN UINT8 Function
+ )
+{
+ UINTN index;
+
+ for (index = 0; index < ARRAY_SIZE(DevicePowerState); index++) {
+ if ((DevicePowerState[index].Device == Device) && (DevicePowerState[index].Function) == Function) {
+ DevicePowerState[index].PowerState = DeviceD3;
+ break;
+ }
+ }
+}
+
+/**
+
+ Restore Device Power State back to D3
+
+ @retval None
+
+**/
+VOID
+RestoreDevPowState (
+ VOID
+ )
+{
+ UINTN index;
+ UINTN PciBaseAddress;
+ UINT8 CapOffset;
+
+ for (index = 0; index < ARRAY_SIZE(DevicePowerState); index++) {
+ if (DevicePowerState[index].PowerState == DeviceD3) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ DevicePowerState[index].Device,
+ DevicePowerState[index].Function,
+ 0
+ );
+ CapOffset = PcieFindCapId (
+ 0,
+ DevicePowerState[index].Device,
+ DevicePowerState[index].Function,
+ EFI_PCI_CAPABILITY_ID_PCIPM
+ );
+ if (CapOffset != 0) {
+ MmioOr8 (PciBaseAddress + CapOffset + 0x4, DeviceD3);
+ }
+ }
+ }
+}
+
+/**
+ Restore PxDevSlp
+
+ @param[in] *PchSaveRestorePci - Pointer to Pch Save Restore Pci to be restored.
+
+ @retval None
+**/
+VOID
+RestorePxDevSlp(
+ IN PCH_SAVE_RESTORE_PCI *PchSaveRestorePci
+ )
+{
+ UINTN PciBaseAddress;
+ UINT32 PciBar;
+ UINTN Address;
+ UINT8 PciCmd;
+ UINT32 Data32;
+ UINT32 PortIndex;
+
+ ASSERT ((PchSaveRestorePci->AccessType == PciMmr) &&
+ (PchSaveRestorePci->Device == PCI_DEVICE_NUMBER_PCH_SATA) &&
+ ((PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P0DEVSLP) ||
+ (PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P1DEVSLP) ||
+ (PchSaveRestorePci->Offset == R_PCH_SATA_AHCI_P3DEVSLP)) &&
+ (PchSaveRestorePci->Width == 4));
+
+ PciBaseAddress = MmPciAddress (
+ 0,
+ 0,
+ PchSaveRestorePci->Device,
+ PchSaveRestorePci->Function,
+ 0
+ );
+ PortIndex = (PchSaveRestorePci->Offset - R_PCH_SATA_AHCI_P0DEVSLP)/0x80;
+ PciCmd = MmioRead8 (PciBaseAddress + PCI_COMMAND_OFFSET);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePci->BarOffset);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePci->BarOffset, PciMemBase);
+ Address = PciMemBase + PchSaveRestorePci->Offset;
+ ///
+ /// Restore DM and DITO
+ ///
+ MmioAndThenOr32 (Address, (UINT32)~PchSaveRestorePci->Mask, (PchSaveRestorePci->Data & (B_PCH_SATA_AHCI_PxDEVSLP_DM_MASK | B_PCH_SATA_AHCI_PxDEVSLP_DITO_MASK)));
+
+ ///
+ /// Makesure PxCMD.ST and PxDEVSLP.ADSE are cleared to '0' before updating PxDEVSLP.DETO and PxDEVSLP.MDAT value.
+ ///
+ Data32 = MmioRead32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)));
+ MmioAnd32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)), (UINT32)~B_PCH_SATA_AHCI_PxCMD_ST);
+ MmioAnd32 (Address, (UINT32)~B_PCH_SATA_AHCI_PxDEVSLP_ADSE);
+ MmioOr32 (Address, (PchSaveRestorePci->Data & (UINT32)~B_PCH_SATA_AHCI_PxDEVSLP_ADSE));
+ MmioOr32 (PciMemBase + (R_PCH_SATA_AHCI_P0CMD + (0x80 * PortIndex)), (Data32 & B_PCH_SATA_AHCI_PxCMD_ST));
+ MmioOr32 (Address, (PchSaveRestorePci->Data & B_PCH_SATA_AHCI_PxDEVSLP_ADSE));
+
+ ///
+ /// Restore original PCI command and bar
+ ///
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, PciCmd);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePci->BarOffset, PciBar);
+}
+
+/**
+ A SMI callback to do PCH SMI register restoration
+
+ @param[in] DispatchHandle - The handle of this callback, obtained when registering
+ @param[in] DispatchContext - Pointer to the EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT
+
+ @retval None
+**/
+VOID
+PchIoTrapSmiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+{
+ UINT16 AcpiBase;
+ UINT16 TcoBase;
+ UINTN index;
+ UINTN i;
+ UINTN PciBaseAddress;
+ UINTN Address;
+ UINT8 PowerState;
+ UINT8 PciCmd;
+ UINT32 PciBar;
+ UINT32 Mask;
+ PCH_SERIES PchSeries;
+
+ AcpiBase = PchLpcPciCfg32(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ TcoBase = AcpiBase + PCH_TCO_BASE;
+ PowerState = 0x0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Restoring IO and MMIO registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestoreRegWrap); i++) {
+ if (PchSeries != PchSaveRestoreRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestoreRegWrap[i].size; index++) {
+ Mask = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Mask;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].AccessType) {
+ case Tco:
+ Address = TcoBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ IoAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ IoAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ IoAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ case Acpi:
+ Address = AcpiBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ IoAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ IoAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ IoAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ case Rcrb:
+ Address = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchMmRcrb32AndThenOr (Address, (UINT32) ~Mask, PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data);
+ break;
+ case 2:
+ PchMmRcrb16AndThenOr (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ case 1:
+ PchMmRcrb8AndThenOr (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data));
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Restoring PCI config space and PCI bar registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestorePciRegWrap); i++) {
+ if (PchSeries != PchSaveRestorePciRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestorePciRegWrap[i].size; index++) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ 0
+ );
+ if (MmioRead32(PciBaseAddress) == 0xFFFFFFFF) {
+ continue;
+ }
+ if (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].RestoreFunction == NULL) {
+ Mask = PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Mask;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].AccessType) {
+ case PciCfg:
+ Address = PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ MmioAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data);
+ break;
+ case 2:
+ MmioAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ case 1:
+ MmioAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ }
+ break;
+ case PciMmr:
+ PciCmd = MmioRead8 (PciBaseAddress + PCI_COMMAND_OFFSET);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciMemBase);
+ Address = PciMemBase + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ MmioAndThenOr32 (Address, (UINT32) ~Mask, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data);
+ break;
+ case 2:
+ MmioAndThenOr16 (Address, (UINT16) ~Mask, (UINT16) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ case 1:
+ MmioAndThenOr8 (Address, (UINT8) ~Mask, (UINT8) (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data));
+ break;
+ }
+ ///
+ /// Restore original PCI command and bar
+ ///
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, PciCmd);
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciBar);
+ break;
+ }
+ } else {
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci [index].RestoreFunction (&(PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index]));
+ }
+ }
+ }
+}
+
+/**
+ This function save PCH register before enter S3
+
+ @param[in] Handle Handle of the callback
+ @param[in] Context The dispatch context
+
+ @retval EFI_SUCCESS PCH register saved
+**/
+EFI_STATUS
+PchS3EntryCallBack (
+ IN EFI_HANDLE Handle,
+ IN EFI_SMM_SX_DISPATCH_CONTEXT *Context
+ )
+{
+ UINT32 AcpiBase;
+ UINT32 TcoBase;
+ UINTN PciBaseAddress;
+ UINTN index;
+ UINTN i;
+ UINT8 PowerState;
+ UINT8 CapOffset;
+ UINT32 PciBar;
+ UINT32 Mask;
+ UINT32 Address;
+ PCH_SERIES PchSeries;
+
+ AcpiBase = PchLpcPciCfg32(R_PCH_LPC_ACPI_BASE) & B_PCH_LPC_ACPI_BASE_BAR;
+ TcoBase = AcpiBase + PCH_TCO_BASE;
+ PowerState = 0x0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Saving IO and MMIO registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestoreRegWrap); i++) {
+ if (PchSeries != PchSaveRestoreRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestoreRegWrap[i].size; index++) {
+ Mask = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Mask;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].AccessType) {
+ case Tco:
+ Address = TcoBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case Acpi:
+ Address = AcpiBase + PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (IoRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case Rcrb:
+ Address = PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Address;
+ switch (PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Width) {
+ case 4:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestoreRegWrap[i].PchSaveRestoreReg[index].Data = (PchMmRcrb8 (Address)) & Mask;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Saving PCI config space and PCI bar registers
+ ///
+ for (i = 0; i < ARRAY_SIZE (PchSaveRestorePciRegWrap); i++) {
+ if (PchSeries != PchSaveRestorePciRegWrap[i].PchSeries) {
+ continue;
+ }
+ for (index = 0; index < PchSaveRestorePciRegWrap[i].size; index++) {
+ PciBaseAddress = MmPciAddress(
+ 0,
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ 0
+ );
+ if (MmioRead32(PciBaseAddress) == 0xFFFFFFFF) {
+ continue;
+ }
+ Mask = PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Mask;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].AccessType) {
+ case PciCfg:
+ Address = (UINT32) PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ case PciMmr:
+ PciBar = MmioRead32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset);
+ CapOffset = PcieFindCapId (
+ 0,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device,
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function,
+ EFI_PCI_CAPABILITY_ID_PCIPM
+ );
+ if (CapOffset != 0) {
+ PowerState = MmioRead8(PciBaseAddress + CapOffset + 0x4) & (BIT1 | BIT0);
+ if (PowerState == DeviceD3) {
+ ///
+ /// Bring up device to D0
+ ///
+ MmioAnd8 (PciBaseAddress + CapOffset + 0x4, (UINT8)~(BIT1 | BIT0));
+ MmioWrite32 (PciBaseAddress + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].BarOffset, PciBar);
+ MmioWrite8 (PciBaseAddress + PCI_COMMAND_OFFSET, BIT1);
+ SaveDevPowState(PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Device, PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Function);
+ }
+ }
+ PciBar = PciBar & (UINT32)~(0xF);
+ if (PciBar == 0x0) {
+ continue;
+ }
+ Address = PciBar + PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Offset;
+ switch (PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Width) {
+ case 4:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead32 (Address)) & Mask;
+ break;
+ case 2:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead16 (Address)) & Mask;
+ break;
+ case 1:
+ PchSaveRestorePciRegWrap[i].PchSaveRestorePci[index].Data = (MmioRead8 (Address)) & Mask;
+ break;
+ }
+ break;
+ }
+ }
+ }
+
+ ///
+ /// Restore devices to D3
+ ///
+ RestoreDevPowState();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes the PCH SMM handler for PCH save and restore
+
+ @param[in] ImageHandle - Handle for the image of this driver
+ @param[in] SystemTable - Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS - PCH SMM handler was installed
+**/
+EFI_STATUS
+PchLateInitSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemBase;
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *PchIoTrap;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_SX_DISPATCH_CONTEXT SxDispatchContext;
+ EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatchProtocol;
+ EFI_HANDLE SxDispatchHandle;
+ PCH_LATE_INIT_SMM_VARIABLE SaveRestoreData;
+
+ DEBUG ((EFI_D_INFO, "PchLateInitSmmEntryPoint()\n"));
+
+ ///
+ /// Locate the PCH Trap dispatch protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, &PchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ PchIoTrapContext.Type = ReadWriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = PchIoTrap->Register (
+ PchIoTrap,
+ PchIoTrapSmiCallback,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ SaveRestoreData.IoTrapAddress = PchIoTrapContext.Address;
+
+ DEBUG ((EFI_D_INFO, "PchIotrapSmiAddress = 0x%x\n", PchIoTrapContext.Address));
+
+ ///
+ /// Locate the Sx Dispatch Protocol
+ ///
+ Status = gBS->LocateProtocol (
+ &gEfiSmmSxDispatchProtocolGuid,
+ NULL,
+ &SxDispatchProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Register the callback for S3 entry
+ ///
+ SxDispatchContext.Type = SxS3;
+ SxDispatchContext.Phase = SxEntry;
+ Status = SxDispatchProtocol->Register (
+ SxDispatchProtocol,
+ PchS3EntryCallBack,
+ &SxDispatchContext,
+ &SxDispatchHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MemBase = 0x0ffffffff;
+#ifndef AMI_OVERRIDE_FOR_SMM
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &MemBase,
+ ImageHandle,
+ NULL
+ );
+#else
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &MemBase,
+ ImageHandle,
+ NULL
+ );
+#endif // AMI_OVERRIDE_FOR_SMM
+ ASSERT_EFI_ERROR (Status);
+
+ PciMemBase = (UINT32) MemBase;
+
+ SaveRestoreData.PciMemBase = PciMemBase;
+
+ Status = gRT->SetVariable (
+ PCH_INIT_PEI_VARIABLE_NAME,
+ &gPchInitPeiVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof (PCH_LATE_INIT_SMM_VARIABLE),
+ &SaveRestoreData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif
new file mode 100644
index 0000000..260cf93
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchLateInitSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchInit\Smm"
+ RefName = "PchLateInitSmm"
+[files]
+"PchLateInitSmm.sdl"
+"PchLateInitSmm.mak"
+"PchLateInitSmm.c"
+"PchLateInitSmm.h"
+"PchLateInitSmm.dxs"
+"PchLateInitSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs
new file mode 100644
index 0000000..32f981f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.dxs
@@ -0,0 +1,46 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+
+**/
+
+//
+// Common for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are both "defined" in R8 codebase;
+// BUILD_WITH_EDKII_GLUE_LIB is defined in Edk-Dev-Snapshot-20070228 and later version
+// BUILD_WITH_GLUELIB and BUILD_WITH_EDKII_GLUE_LIB are "not defined" in R9 codebase.
+//
+#if defined (BUILD_WITH_GLUELIB) || defined (BUILD_WITH_EDKII_GLUE_LIB)
+#include "EfiDepex.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
+#include EFI_ARCH_PROTOCOL_DEFINITION (VariableWrite)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h
new file mode 100644
index 0000000..0082af0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.h
@@ -0,0 +1,106 @@
+/** @file
+ Header file for PCH SMM Handler
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+#ifndef _PCHLATEINITSMM_H_
+#define _PCHLATEINITSMM_H_
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchInitVar.h"
+#include "pci22.h"
+#endif
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (SmmSxDispatch)
+
+#define EFI_PCI_CAPABILITY_ID_PCIPM 0x01
+
+#define DeviceD0 0x00
+#define DeviceD3 0x03
+
+#define ARRAY_SIZE(data) (sizeof (data) / sizeof (data[0]))
+
+typedef enum {
+ PciCfg,
+ PciMmr
+} PCH_PCI_ACCESS_TYPE;
+
+typedef enum {
+ Acpi,
+ Rcrb,
+ Tco
+} PCH_ACCESS_TYPE;
+
+typedef struct {
+ PCH_ACCESS_TYPE AccessType;
+ UINT32 Address;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+} PCH_SAVE_RESTORE_REG;
+
+typedef struct {
+ PCH_SAVE_RESTORE_REG* PchSaveRestoreReg;
+ UINT8 size;
+ PCH_SERIES PchSeries;
+} PCH_SAVE_RESTORE_REG_WRAP;
+
+struct _PCH_SAVE_RESTORE_PCI;
+
+typedef struct _PCH_SAVE_RESTORE_PCI{
+ PCH_PCI_ACCESS_TYPE AccessType;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 BarOffset;
+ UINT16 Offset;
+ UINT32 Data;
+ UINT32 Mask;
+ UINT8 Width;
+ VOID (*RestoreFunction)(struct _PCH_SAVE_RESTORE_PCI *PchSaveRestorePci);
+} PCH_SAVE_RESTORE_PCI;
+
+typedef struct {
+ PCH_SAVE_RESTORE_PCI* PchSaveRestorePci;
+ UINT8 size;
+ PCH_SERIES PchSeries;
+} PCH_SAVE_RESTORE_PCI_WRAP;
+
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 PowerState;
+} DEVICE_POWER_STATE;
+
+VOID
+RestorePxDevSlp(
+ IN PCH_SAVE_RESTORE_PCI *PchSaveRestorePci
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf
new file mode 100644
index 0000000..9f04d49
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.inf
@@ -0,0 +1,88 @@
+## @file
+# Component description file for the PCH late initialization SMM module.
+#
+#@copyright
+# Copyright (c) 2012 Intel Corporation. All rights reserved
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+#
+# This file contains a 'Sample Driver' and is licensed as such
+# under the terms of your license agreement with Intel or your
+# vendor. This file may be modified by the user, subject to
+# the additional terms of the license agreement
+#
+
+[defines]
+BASE_NAME = PchLateInitSmm
+FILE_GUID = D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchLateInitSmm.c
+ PchLateInitSmm.h
+ ../Common/PchInitVar.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode/Include
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+#
+# Typically the sample code referenced will be available in the code base already
+# So keep this include at the end to defer to the source base definition
+# and only use the sample code definition if source base does not include these files.
+#
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[libraries.common]
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkProtocolLib
+ EfiScriptLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchLateInitSmm.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchLateInitSmmEntryPoint
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak
new file mode 100644
index 0000000..d9cf9b7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.mak
@@ -0,0 +1,97 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.mak 1 12/18/12 4:55a Scottyang $
+#
+# $Revision: 1 $
+#
+# $Date: 12/18/12 4:55a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.mak $
+#
+# 1 12/18/12 4:55a Scottyang
+# [TAG] EIP109697
+# [Category] Improvement
+# [Description] Update PCH RC 0.8.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# Create PchLateInitSmm Driver
+#---------------------------------------------------------------------------
+EDK : PchLateInitSmm
+PchLateInitSmm : $(BUILD_DIR)\PchLateInitSmm.mak PchLateInitSmmBin
+
+$(BUILD_DIR)\PchLateInitSmm.mak : $(PchLateInitSmm_DIR)\$(@B).cif $(PchLateInitSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchLateInitSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchLateInitSmm_INCLUDES=\
+ /I$(INTEL_PCH_DIR)\PchInit\Common\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(EDK_SOURCE)\Foundation\Efi\Include\
+
+PchLateInitSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PchLateInitSmmEntryPoint"\
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+
+PchLateInitSmm_LIB_LINKS =\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EFISCRIPTLIB)\
+ $(PchUsbCommonDxeLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchLateInitSmmBin: $(PchLateInitSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchLateInitSmm.mak all \
+ "MY_INCLUDES=$(PchLateInitSmm_INCLUDES)" \
+ "MY_DEFINES=$(PchLateInitSmm_DEFINES)" \
+ GUID=D7B10D4E-67E6-4C74-83E9-F9AF0ACC33CC\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchLateInitSmm_DIR)\PchLateInitSmm.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl
new file mode 100644
index 0000000..efb0a48
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchInit/Smm/PchLateInitSmm.sdl
@@ -0,0 +1,71 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.sdl 1 12/18/12 4:55a Scottyang $
+#
+# $Revision: 1 $
+#
+# $Date: 12/18/12 4:55a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLateInitSmm.sdl $
+#
+# 1 12/18/12 4:55a Scottyang
+# [TAG] EIP109697
+# [Category] Improvement
+# [Description] Update PCH RC 0.8.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SBPEI.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+#*************************************************************************
+TOKEN
+ Name = "PchLateInitSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchLateInitSmm support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchLateInitSmm_DIR"
+End
+
+MODULE
+ File = "PchLateInitSmm.mak"
+ Help = "Includes PchLateInitSmm to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchLateInitSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************