summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/LynxPoint
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/LynxPoint')
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl977
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif19
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf53
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl735
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudio.asl44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl133
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl238
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl199
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl288
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl1029
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl605
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl1229
-rw-r--r--ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c292
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h104
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.inf77
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.mak96
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosDepex.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c28
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h62
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.inf48
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.mak21
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.sdl43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.c30
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.h73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxe.dsc58
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxeLib.dsc30
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.cif33
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.sdl56
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchPei.dsc38
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IntelPchPeiLib.dsc28
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/IobpDefinitions.h51
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/Library/DxeRuntimePciLibPciExpress.h61
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/Library/PchPciExpressHelpersLib.h296
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/Library/PchPlatformLib.h385
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/Library/PchSmbusLibrary.h44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/Library/RcFviDxeLib.h175
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchAccess.h509
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h474
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsAdsp.h109
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h399
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h196
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h1018
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsPcie.h548
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsRcrb.h483
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSata.h703
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSerialIo.h169
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSmbus.h172
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h380
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsThermal.h100
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h563
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Include/PchUsbConfig.h178
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c884
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h221
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak118
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak91
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.c204
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.h119
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.inf73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c2148
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf78
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak76
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl72
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl55
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl83
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c2201
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c295
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak112
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl93
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c831
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h29
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif8
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c54
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif9
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h25
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf63
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak74
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl59
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h25
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf64
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif9
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c225
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak69
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl73
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h49
-rw-r--r--ReferenceCode/Chipset/LynxPoint/LynxPoint.cif47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pch.sdl485
-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
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.cif24
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.dxs43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.inf104
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.mak115
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.sdl102
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmm.h727
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c891
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c101
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c317
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h155
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c2425
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c519
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPowerButton.c104
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c87
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c975
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c300
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.c820
-rw-r--r--ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.h128
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c388
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs52
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h99
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf86
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak100
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.sdl69
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.cif28
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf68
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak63
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.sdl72
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h80
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.c43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.h153
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h53
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.c43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.h263
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.c42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.h68
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c45
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h126
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c26
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h72
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h57
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c32
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h53
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.c47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.h136
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.cif33
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.inf70
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.mak62
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.sdl71
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.c41
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h121
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/UsbHcPortPrecondition.h53
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.c44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.h1061
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.c44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.h139
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.c43
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.h218
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.c42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.h90
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.c34
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.h166
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c46
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h177
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h182
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c48
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h346
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c34
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h157
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.c254
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.h86
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.mak124
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.sdl97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.c134
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.h65
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf84
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.mak99
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.c496
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h83
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.mak117
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchResetRuntime.inf90
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c369
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.dxs45
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h126
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.inf103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.mak115
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.sdl75
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c563
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs41
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h106
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf100
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak52
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl75
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c156
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.dxs46
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h60
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.inf95
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.mak94
-rw-r--r--ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.sdl57
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/Sensor.asl103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl1527
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c188
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.dxs48
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.h36
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.inf94
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Guid/SmbusArpMap/SmbusArpMap.h29
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h681
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Include/PchAslUpdateLib.h166
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.c474
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.inf66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak83
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.sdl29
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.c427
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.h33
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.c490
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.dxs44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.h56
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.inf82
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.c250
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.dxs40
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.h60
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.inf87
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/PchSampleCode.cif34
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/IntelPchSampleCodePpiLib.inf45
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h38
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c25
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h136
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/UsbController/UsbController.h49
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SampleCode/Protocol/SmmSmbus/SmmSmbus.h50
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.c943
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.h323
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.inf94
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.mak116
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataControllerName.c173
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c516
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h193
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf79
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak96
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.c523
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.dxs42
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h178
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.inf77
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.mak100
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.sdl76
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h190
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak124
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c661
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs40
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h360
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c681
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf93
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c149
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs44
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h409
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c444
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf88
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c291
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif15
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf91
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak97
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c117
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c241
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs41
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h183
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c128
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif14
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf95
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak105
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.mak93
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.sdl24
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.dxs35
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.inf76
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.c282
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.h95
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs36
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.inf85
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak105
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.c478
-rw-r--r--ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.h164
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.mak125
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.sdl92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.c1425
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.h300
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c133
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.h74
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf83
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.mak99
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.sdl67
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.c322
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.dxs39
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf91
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak113
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.sdl66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.c244
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs45
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h76
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif13
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak112
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.sdl66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.c229
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h82
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c77
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif15
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs45
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h47
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf87
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak111
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.sdl66
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.c246
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.h166
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif11
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak103
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.sdl92
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.c218
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs30
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.inf87
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak102
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.sdl68
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.c280
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs31
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.mak94
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.sdl78
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPeim.inf87
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif12
-rw-r--r--ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl73
432 files changed, 89947 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl
new file mode 100644
index 0000000..2b95557
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/Pch.asl
@@ -0,0 +1,977 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ //
+ // RPAx is root port addresses, which are updated when post to reflect
+ // the root port function number swapping.
+ //
+ Name (RPA0, 0x001C0000)
+ Name (RPA1, 0x001C0001)
+ Name (RPA2, 0x001C0002)
+ Name (RPA3, 0x001C0003)
+ Name (RPA4, 0x001C0004)
+ Name (RPA5, 0x001C0005)
+ Name (RPA6, 0x001C0006)
+ Name (RPA7, 0x001C0007)
+
+ //
+ // PCHS stands for PCH series. This will be updated when post.
+ // 1: PchH
+ // 2: PchLp
+ // others: unknown
+ //
+ Name (PCHS, 0xFFFFFFFF)
+
+ //
+ // Reserved MEM range for S3 Save/restore with 64K in size.
+ // This will be updated when post.
+ //
+ Name (SRMB, 0xFFFFFFFF)
+
+ //
+ // Maximum Snoop Latency and Maximum No-Snoop Latency values for PCIE.
+ // This will be updated when post.
+ //
+ Name (PML1, 0xFFFFFFFF)
+ Name (PML2, 0xFFFFFFFF)
+ Name (PML3, 0xFFFFFFFF)
+ Name (PML4, 0xFFFFFFFF)
+ Name (PML5, 0xFFFFFFFF)
+ Name (PML6, 0xFFFFFFFF)
+ Name (PML7, 0xFFFFFFFF)
+ Name (PML8, 0xFFFFFFFF)
+ Name (PNL1, 0xFFFFFFFF)
+ Name (PNL2, 0xFFFFFFFF)
+ Name (PNL3, 0xFFFFFFFF)
+ Name (PNL4, 0xFFFFFFFF)
+ Name (PNL5, 0xFFFFFFFF)
+ Name (PNL6, 0xFFFFFFFF)
+ Name (PNL7, 0xFFFFFFFF)
+ Name (PNL8, 0xFFFFFFFF)
+
+Scope(\)
+{
+ //
+ // Define the IO Address 0810h-0813h as an ACPI Operating Region first, and
+ // then it will be dynamically updated during initialization of DTS code.
+ // The address presented here may not be the actual address used.
+ // This address range is used as a DTS I/O Trap SMI so that ASL and SMI
+ // can communicate when needed.
+ //
+ OperationRegion(IO_D,SystemIO,0x810,0x4)
+ Field(IO_D,ByteAcc,NoLock,Preserve) {
+ TRPD, 8 // 0x810 = DTS I/O Trap
+ }
+ //
+ // The IO address in this ACPI Operating Region will be updated during POST.
+ // This address range is used as a HotKey I/O Trap SMI so that ASL and SMI can
+ // communicate when needed.
+ //
+ OperationRegion(IO_H,SystemIO,0x1000,0x4)
+ Field(IO_H,ByteAcc,NoLock,Preserve) {
+ TRPH, 8
+ }
+ //
+ // Define PCH PMBASE I/O as an ACPI operating region. The base address
+ // can be found in Device 31, Registers 40-43h.
+ //
+ OperationRegion(PMIO, SystemIo, \PMBS, 0x80)
+ Field(PMIO, ByteAcc, NoLock, Preserve) {
+ Offset(0x28), // GPE0 Enable
+ , 16,
+ , 3, // GPE for 0-2 GPIO's
+ GPE3, 1,
+ , 7, // GPE for 4-0xA GPIO's
+ GPEB, 1,
+ Offset(0x3c), // UPRWC - USB Per-Port registers write control
+ , 1,
+ UPRW, 1, // USB Per-Port registers write enable
+ Offset(0x42), // General Purpose Control
+ , 1,
+ GPEC, 1
+ }
+ Field(PMIO, ByteAcc, NoLock, WriteAsZeros) {
+ Offset(0x20), // GPE0 Status
+ , 16,
+ , 3, // GPS for 0-2 GPIO's
+ GPS3, 1,
+ , 7, // GPS for 4-0xa GPIO's
+ GPSB, 1,
+ Offset(0x64), // TCO status register
+ , 9,
+ SCIS, 1, // TCO DMI SCI status
+ , 6
+ }
+
+ //
+ // Define PCH PMBASE I/O as an ACPI operating region. The base address
+ // can be found in Device 31, Registers 40-43h.
+ //
+ OperationRegion(PMLP, SystemIo, Add(\PMBS,0x80), 0x20)
+ Field(PMLP, ByteAcc, NoLock, Preserve) {
+ Offset(0x10), // GPE0 Enable
+ , 8,
+ GE08, 1,
+ , 8,
+ GE17, 1,
+ , 27,
+ GE45, 1,
+ , 5,
+ GE51, 1,
+ , 76,
+ }
+ Field(PMLP, ByteAcc, NoLock, WriteAsZeros) {
+ Offset(0x00), // GPE0 Status
+ , 8,
+ GS08, 1,
+ , 8,
+ GS17, 1,
+ , 27,
+ GS45, 1,
+ , 5,
+ GS51, 1,
+ , 76,
+ }
+
+ //
+ // Define PCH GPIO I/O as an ACPI operating region.
+ // The base address can be found in Device 31, Registers 48-4Bh.
+ //
+
+ OperationRegion(GPR, SystemIo, \GPBS, 0x400)
+ Field(GPR, ByteAcc, NoLock, Preserve) {
+ Offset(0x00), // GPIO, Use Select, Bank 0
+ GU00, 8,
+ GU01, 8,
+ GU02, 8,
+ GU03, 8,
+ Offset(0x04), // GPIO, I/O Select, Bank 0
+ GIO0, 8,
+ GIO1, 8,
+ GIO2, 8,
+ GIO3, 8,
+ Offset(0x0C), // GPIO, Level, Bank 0
+ GL00, 8,
+ GL01, 8,
+ GL02, 8,
+ GP24, 1,
+ , 2,
+ GP27, 1, // SATA_PWR_EN#0
+ GP28, 1, // SATA_PWR_EN#1 (SATA Ports 1 and 2)
+ , 3,
+ Offset(0x18),
+ GB00, 8, // GPIO, Blink, Bank 0
+ GB01, 8,
+ GB02, 8,
+ GB03, 8,
+ Offset(0x2C),
+ GIV0, 8, // GPIO, Invert, Bank 0
+ GIV1, 8,
+ GIV2, 8,
+ GIV3, 8,
+ Offset(0x30), // GPIO, Use Select, Bank 1
+ GU04, 8,
+ GU05, 8,
+ GU06, 8,
+ GU07, 8,
+ Offset(0x34), // GPIO, I/O Select, Bank 1
+ GIO4, 8,
+ GIO5, 8,
+ GIO6, 8,
+ GIO7, 8,
+ Offset(0x38), // GPIO, Level, Bank 1
+ GL04, 8,
+ GL05, 8,
+ GL06, 8,
+ GL07, 8,
+ Offset(0x40), // GPIO, Use Select, Bank 2
+ GU08, 8,
+ GU09, 8,
+ GU0A, 8,
+ GU0B, 8,
+ Offset(0x44), // GPIO, I/O Select, Bank 2
+ GIO8, 8,
+ GIO9, 8,
+ GIOA, 8,
+ GIOB, 8,
+ Offset(0x48), // GPIO, Level, Bank 2
+ GL08, 8,
+ GL09, 8,
+ GL0A, 8,
+ GL0B, 8
+ }
+
+ //
+ // Define PCH GPIO I/O as an ACPI operating region.
+ // The base address can be found in Device 31, Registers 48-4Bh.
+ //
+ OperationRegion(GPRL, SystemIo, \GPBS, 0x40)
+ Field(GPRL, ByteAcc, NoLock, Preserve) {
+ Offset(0x00), // GPI_OWN, 0 => ACPI driver owned
+ , 8,
+ GO08, 1,
+ GO09, 1,
+ , 3,
+ GO13, 1,
+ GO14, 1,
+ , 2,
+ GO17, 1,
+ , 27,
+ GO45, 1,
+ , 5,
+ GO51, 1,
+ , 76,
+ Offset(0x30), // GPI_ROUT, 0 => SCI
+ GR00, 32,
+ GR01, 32,
+ GR02, 32
+ }
+
+ //
+ // Define a Memory Region that will allow access to the Root Complex
+ // Register Block. Note that in the Intel Reference Solution, the RCBA
+ // will get fixed up dynamically during POST.
+ //
+ OperationRegion(RCRB,SystemMemory,\SRCB,0x4000)
+ Field(RCRB,DWordAcc,Lock,Preserve) {
+ Offset(0x0000), // Backbone Related Registers
+ Offset(0x1000), // Other Chipset Registers
+#ifdef TRAD_FLAG
+ Offset(0x2330), // SBI AFE Address
+ AFEA, 32,
+ Offset(0x2334), // SBI AFE Data
+ AFED, 32,
+ Offset(0x2338), // SBI AFE Status
+ AFES, 16,
+ Offset(0x233A), // SBI AFE Routing Id
+ AFER, 16,
+#endif // TRAD_FLAG
+ Offset(0x3000), // Legacy\Other Chipset Configuration Registers
+ Offset(0x331c),
+ , 24,
+ PMFS, 1, // PCIe Source Clock Request Status
+ Offset(0x3320),
+ CKEN, 32, // PCIe Source Clock Enable Register
+ Offset(0x3404), // High Performance Timer Configuration
+ HPAS, 2, // (1:0) High Performance Address Select
+ , 5, // (6:2) Reserved
+ HPAE, 1, // (7) High Performance Address Enable
+ Offset(0x3418), // Function Disable Register
+ , 1, // (0) Reserved
+ ADSD, 1, // (1) Audio DSP Disable
+ SATD, 1, // (2) Serial ATA Disable
+ SMBD, 1, // (3) SMBus Disable
+ HDAD, 1, // (4) High Definition Audio Disable
+ , 11, // (15:5) Skip for now
+ RP1D, 1, // (16) Root Port 1 Disable
+ RP2D, 1, // (17) Root Port 2 Disable
+ RP3D, 1, // (18) Root Port 3 Disable
+ RP4D, 1, // (19) Root Port 4 Disable
+ RP5D, 1, // (20) Root Port 5 Disable
+ RP6D, 1, // (21) Root Port 6 Disable
+ RP7D, 1, // (22) Root Port 7 Disable
+ RP8D, 1, // (23) Root Port 8 Disable
+ Offset(0x359c), // Usb Port Disable Override Register
+ UP0D, 1, // (0) Usb Port 0 disable
+ UP1D, 1, // (1) Usb Port 1 disable
+ UP2D, 1, // (2) Usb Port 2 disable
+ UP3D, 1, // (3) Usb Port 3 disable
+ UP4D, 1, // (4) Usb Port 4 disable
+ UP5D, 1, // (5) Usb Port 5 disable
+ UP6D, 1, // (6) Usb Port 6 disable
+ UP7D, 1, // (7) Usb Port 7 disable
+ UP8D, 1, // (8) Usb Port 8 disable
+ UP9D, 1, // (9) Usb Port 9 disable
+ UPAD, 1, // (10) Usb Port 10 disable
+ UPBD, 1, // (11) Usb Port 11 disable
+ UPCD, 1, // (12) Usb Port 12 disable
+ UPDD, 1, // (13) Usb Port 13 disable
+ , 1, // (14) Reserved
+ , 1 // (15) Reserved
+ }
+ //
+ // Support S0, S3, S4, and S5. The proper bits to be set when
+ // entering a given sleep state are found in the Power Management
+ // 1 Control ( PM1_CNT ) register, located at ACPIBASE + 04h,
+ // bits 10d - 12d.
+ //
+
+ //
+ // Define the IO Address 1000h-1003h as an ACPI Operating Region first, and
+ // then it will be dynamically updated during initialization of PFAT code.
+ // The address presented here may not be the actual address used.
+ // This address range is used as a PFAT Tools Interface I/O Trap so that the
+ // update tool can trigger bios code to update the flash using the pfat flow.
+ //
+ OperationRegion (IO_P, SystemIO, 0x1000, 0x4)
+ Field (IO_P, ByteAcc, NoLock, Preserve) {
+ TRPF, 8 // 0x1000 = PFAT I/O Trap
+ }
+
+} //end Scope(\)
+
+ Scope (\_SB)
+ {
+
+ Method(RDGI,1,Serialized) //Read the value of Input GPIO Line
+ {
+ // Function to Read GPIO
+ //
+ // Arg0 : GPIn : GPIO Pin number to be read(Zero based)
+ //
+ If(LLessEqual(Arg0, 94)){
+ // GPBS - GPIO Base Address - 0x800
+ // Local0 = GPIOBASE + 100h + (GPIn * 0x08)
+ Store( Add(Add(GPBS,0x100) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ ,30,
+ TEMP, 1
+ }
+ Return(TEMP)
+ }
+ //AMI_OVERRIDE ---- Fixed for Ubuntu Firmware Test >>
+ Return(0)
+ //AMI_OVERRIDE ---- Fixed for Ubuntu Firmware Test <<
+ } // End of Method(RDGI,1)
+
+ Method(RDGP,1,Serialized)
+ {
+ // Function to Read GPIO
+ //
+ // Arg0 : GPIn : GPIO Pin number to be read(Zero based)
+ //
+ If(LLessEqual(Arg0, 94)){
+ // GPBS - GPIO Base Address - 0x800
+ // Local0 = GPIOBASE + 100h + (GPIn * 0x08)
+ Store( Add(Add(GPBS,0x100) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ ,31,
+ TEMP, 1
+ }
+ Return(TEMP)
+ }
+ //AMI_OVERRIDE ---- Fixed for Ubuntu Firmware Test >>
+ Return(0)
+ //AMI_OVERRIDE ---- Fixed for Ubuntu Firmware Test <<
+ } // End of Method(RDGP,1)
+
+ Method(WTGP,2,Serialized)
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - Value to be written
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store( Add(Add(GPBS,0x100) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ , 31,
+ TEMP, 1
+ }
+ Store(Arg1,TEMP)
+ }
+ }
+ Method(WTIN,2,Serialized)
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - Value to be written
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store( Add(Add(GPBS,0x100) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, ByteAcc, NoLock, Preserve) {
+ Offset(0x0),
+ , 3,
+ TEMP, 1
+ }
+ Store(Arg1,TEMP)
+ }
+ }
+
+ Method(WPGP,2,Serialized) //GP Weak pull
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - 00 = none 01 = down 10 = up
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store( Add(Add(GPBS,0x104) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 2
+ }
+ Store(Arg1,TEMP)
+ }
+ }
+
+ Method(GP2N,2,Serialized) //GPIO to Native
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - 0 = Native 1 = GPIO
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store( Add(Add(GPBS,0x100) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 4)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 1
+ }
+ Store(Arg1,TEMP)
+ }
+ }
+
+ Method(GP2A,2,Serialized) //GP to APIC
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - 00 = mask 01 = route to IOxAPIC and also Pull UP/NONE the GPIO mode Sensing weak pull
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store( Add(Add(GPBS,0x104) , Multiply(Arg0,0x08)),Local0)
+ OperationRegion(LGP2, SystemIo, Local0, 4)
+ Field(LGP2, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ GPWP, 2,
+ GPIS, 1
+ }
+ if(LEqual(Arg1,1))
+ {
+ Store(0,GPIS)
+ Store(0,GPWP)
+ }Else{
+ Store(2,GPWP)
+ Store(1,GPIS)
+ }
+
+ Store(Add(GPBS, 0x10), Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 2)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 16
+ }
+
+ // GPI PIRQ to IOxAPIC enable bit map
+ // GPI[55:45] to IOxAPIC enable bit[15:5], Subtract 40 from GPI to get ACPI bit
+ // GPI[14:13] to IOxAPIC enable bit[4:3], Subtract 10 from GPI to get ACPI bit
+ // GPI[10:8] to IOxAPIC enable bit[2:0], Subtract 8 from GPI to get ACPI bit
+ If(LGreaterEqual(Arg0, 45))
+ {
+ Subtract(Arg0, 40, Local1) // GPI[55:45] map to APIC[15:5]
+ }Else{
+ If(LLessEqual(Arg0, 10))
+ {
+ Subtract(Arg0, 8, Local1) // GPI[10:8] map to APIC[2:0]
+ }Else{
+ Subtract(Arg0, 10, Local1) // GPI[14:13] map to APIC[4:3]
+ }
+ }
+
+ Store(ShiftLeft(1, Local1), Local2)
+ If(Arg1){ //Enable GP to IOAPIC
+ Or(TEMP, Local2, TEMP)
+ } Else{ //mask
+ And(TEMP, Not(Local2), TEMP)
+ }
+ }
+ }
+
+ Method(GP2B,2,Serialized) //GP to APIC
+ {
+ // Function to write GPIO
+ // Arg0 - GPIn : GPIO Pin number to write
+ // Arg1 - 00 = mask 01 = route to IOxAPIC
+ //
+ If(LLessEqual(Arg0, 94)){
+ Store(Add(GPBS, 0x10), Local0)
+ OperationRegion(LGPI, SystemIo, Local0, 2)
+ Field(LGPI, AnyAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 16
+ }
+
+ // GPI PIRQ to IOxAPIC enable bit map
+ // GPI[55:45] to IOxAPIC enable bit[15:5], Subtract 40 from GPI to get ACPI bit
+ // GPI[14:13] to IOxAPIC enable bit[4:3], Subtract 10 from GPI to get ACPI bit
+ // GPI[10:8] to IOxAPIC enable bit[2:0], Subtract 8 from GPI to get ACPI bit
+ If(LGreaterEqual(Arg0, 45))
+ {
+ Subtract(Arg0, 40, Local1) // GPI[55:45] map to APIC[15:5]
+ }Else{
+ If(LLessEqual(Arg0, 10))
+ {
+ Subtract(Arg0, 8, Local1) // GPI[10:8] map to APIC[2:0]
+ }Else{
+ Subtract(Arg0, 10, Local1) // GPI[14:13] map to APIC[4:3]
+ }
+ }
+
+ Store(ShiftLeft(1, Local1), Local2)
+ If(Arg1){ //Enable GP to IOAPIC
+ Or(TEMP, Local2, TEMP)
+ } Else{ //mask
+ And(TEMP, Not(Local2), TEMP)
+ }
+ }
+ }
+
+ } // End of Scope SB
+
+scope (\_SB.PCI0) {
+ Name(LTRE, 0)
+ Name(OBFF, 0)
+
+ Name(LMSL, 0)
+ Name(LNSL, 0)
+ //
+ // LAN Controller - Device 25, Function 0
+ //
+ Device(GLAN) { // GbE Controller
+ Name(_ADR, 0x00190000)
+ Method(_PRW, 0) { Return(GPRW(0x0D, 4)) } // can wakeup from S4 state
+ } // end "GbE Controller"
+
+ //
+ // EHCI Controller #1 - Device 29, Function 0
+ //
+ Device(EHC1) {
+ Name(_ADR, 0x001D0000)
+ include("PchEhci1.asl")
+ Method(_PRW, 0) { Return(GPRW(0x0D, 4)) } // can wakeup from S4 state
+ } // end "EHCI Controller #1"
+
+ //
+ // EHCI Controller #2 - Device 26, Function 0
+ //
+ Device(EHC2) {
+ Name(_ADR, 0x001A0000)
+ include("PchEhci2.asl")
+ Method(_PRW, 0) { Return(GPRW(0x0D, 4)) } // can wakeup from S4 state
+ } // end "EHCI Controller #2"
+
+ //
+ // xHCI Controller - Device 20, Function 0
+ //
+ Device(XHC) {
+ Name(_ADR, 0x00140000)
+ include("PchXhci.asl")
+ Method(_PRW, 0) { Return(GPRW(0x0D, 4)) } // can wakeup from S4 state
+ } // end "xHCI Controller"
+
+ //
+ // High Definition Audio Controller - Device 27, Function 0
+ //
+ Device(HDEF) {
+ Name(_ADR, 0x001B0000)
+ include("PchAudio.asl")
+ Method(_PRW, 0) { Return(GPRW(0x0D, 4)) } // can wakeup from S4 state
+ } // end "High Definition Audio Controller"
+
+#ifdef SERIAL_IO_FLAG
+ //
+ // Serial IO Controllers definitions
+ //
+ include ("PchSerialIo.asl")
+ include ("ReferenceCode\\Chipset\\LynxPoint\\SampleCode\\AcpiTables\\Dsdt\\SerialIoDevices.asl")
+#endif // SERIAL_IO_FLAG
+
+#ifdef ADSP_FLAG
+ //
+ // Audio DSP Device definition - Device 19, Function 0
+ //
+ Device(ADSP) {
+ Name(_ADR, 0)
+ include("PchAudioDsp.asl")
+ }
+#endif // ADSP_FLAG
+
+#if 0
+ //
+ // PCIE Root Port #1
+ //
+ Device(RP01) {
+ Method (_ADR, 0) { Return (RPA0) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR1, LTRE)
+ Store (PML1, LMSL)
+ Store (PNL1, LNSL)
+ Store (OBF1, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR04) }// APIC mode
+ Return (PR04) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #1"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #2
+ //
+ Device(RP02) {
+ Method (_ADR, 0) { Return (RPA1) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR2, LTRE)
+ Store (PML2, LMSL)
+ Store (PNL2, LNSL)
+ Store (OBF2, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR05) }// APIC mode
+ Return (PR05) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #2"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #3
+ //
+ Device(RP03) {
+ Method (_ADR, 0) { Return (RPA2) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR3, LTRE)
+ Store (PML3, LMSL)
+ Store (PNL3, LNSL)
+ Store (OBF3, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR06) }// APIC mode
+ Return (PR06) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #3"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #4
+ //
+ Device(RP04) {
+ Method (_ADR, 0) { Return (RPA3) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR4, LTRE)
+ Store (PML4, LMSL)
+ Store (PNL4, LNSL)
+ Store (OBF4, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR07) }// APIC mode
+ Return (PR07) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #4"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #5
+ //
+ Device(RP05) {
+ Method (_ADR, 0) { Return (RPA4) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR5, LTRE)
+ Store (PML5, LMSL)
+ Store (PNL5, LNSL)
+ Store (OBF5, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR08) }// APIC mode
+ Return (PR08) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #5"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #6
+ //
+ Device(RP06) {
+ Method (_ADR, 0) { Return (RPA5) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR6, LTRE)
+ Store (PML6, LMSL)
+ Store (PNL6, LNSL)
+ Store (OBF6, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If (LEqual(And(CDID,0xF000), 0x8000)) { // LPT-H
+ If(PICM) { Return(AR09) }// APIC mode
+ Return (PR09) // PIC Mode
+ } Else { // ULT
+ If(PICM) { Return(AR08) }// APIC mode
+ Return (PR08) // PIC Mode
+ }
+ } // end _PRT
+
+ } // end "PCIE Root Port #6"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #7
+ //
+ Device(RP07) {
+ Method (_ADR, 0) { Return (RPA6) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR7, LTRE)
+ Store (PML7, LMSL)
+ Store (PNL7, LNSL)
+ Store (OBF7, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR0E) } // APIC mode
+ Return (PR0E) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #7"
+#endif
+
+#if 0
+ //
+ // PCIE Root Port #8
+ //
+ Device(RP08) {
+ Method (_ADR, 0) { Return (RPA7) }
+ //
+ // Pass LTRx to LTRE so PchPcie.asl can be reused for PCIes.
+ //
+ Method(_INI)
+ {
+ Store (LTR8, LTRE)
+ Store (PML8, LMSL)
+ Store (PNL8, LNSL)
+ Store (OBF8, OBFF)
+ }
+ include("PchPcie.asl")
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+ Method(_PRT,0) {
+ If(PICM) { Return(AR0F) }// APIC mode
+ Return (PR0F) // PIC Mode
+ } // end _PRT
+
+ } // end "PCIE Root Port #8"
+#endif
+
+ //
+ // Serial ATA Host Controller - Device 31, Function 2
+ //
+
+ // PCH SATA Controller
+ Device (SAT0)
+ {
+ //Bus 0x00, Device 0x1F, Function 0x02
+ Name(_ADR, 0x001F0002)
+ Name(FDEV, Zero)
+ Name(FDRP, Zero)
+
+ Method(_DEP){
+ ADBG("SAT0 DEP Call")
+
+ If(LGreaterEqual(OSYS,2013)) { // PEP SATA Constraint for WinBlue and newer version of WinOS
+ If(LAnd (LEqual(S0ID, 1), LNotEqual(And(PEPC, 0x03), 0))){ // PEPC Bit[1:0] - SATA (0:None, 1:SATA Ports[all], 2:SATA Controller)
+ // SATA PEP not set to No Constraint
+ ADBG("SAT0 DEP")
+ Return(Package() {\_SB.PEPD})
+ }
+ }
+
+ ADBG("SAT0 DEP NULL")
+ Return(Package() {}) // No dependency for other OS (non-WinBlue)
+ }
+
+ Device(PRT0)
+ {
+ Name(_ADR,0x0000FFFF) // Port 0
+ Method(_SDD,1, Serialized)
+ {
+ CreateByteField(Arg0, 157, BFDS)
+ ToInteger(BFDS, FDEV)
+ CreateByteField(Arg0, 154, BFRP)
+ ToInteger(BFRP, FDRP)
+ }
+ //Get Task File
+ Method(_GTF,0,Serialized)
+ {
+ //Set Feature Command to enable DevSlp
+ If (LAnd(LAnd(LEqual(DVS0, 1), LEqual(And(FDEV, 0x01), 0x01)), LEqual(And(FDRP, 0x80), 0x80))) {
+ Name(PIB1, Buffer(7)
+ {0x10, 0x09, 0x00, 0x00, 0x00, 0xB0, 0xEF })
+ Return (PIB1)
+ }
+ Name(PIB2, Buffer(7)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+ Return (PIB2)
+ }
+ }
+ Device(PRT1)
+ {
+ Name(_ADR,0x0001FFFF) // Port 1
+ Name(FDEV, Zero)
+ Name(FDRP, Zero)
+ Method(_SDD,1, Serialized)
+ {
+ CreateByteField(Arg0, 157, BFDS)
+ ToInteger(BFDS, FDEV)
+ CreateByteField(Arg0, 154, BFRP)
+ ToInteger(BFRP, FDRP)
+ }
+ // Get Task File
+ Method(_GTF,0,Serialized)
+ {
+ //Set Feature Command to enable DevSlp
+ If (LAnd(LAnd(LEqual(DVS1, 1), LEqual(And(FDEV, 0x01), 0x01)), LEqual(And(FDRP, 0x80), 0x80))) {
+ Name(PIB1, Buffer(7)
+ {0x10, 0x09, 0x00, 0x00, 0x00, 0xB0, 0xEF })
+ Return (PIB1)
+ }
+ Name(PIB2, Buffer(7)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+ Return (PIB2)
+ }
+ }
+ Device(PRT2)
+ {
+ Name(_ADR,0x0002FFFF) // Port 1
+ Name(FDEV, Zero)
+ Name(FDRP, Zero)
+ Method(_SDD,1, Serialized)
+ {
+ CreateByteField(Arg0, 157, BFDS)
+ ToInteger(BFDS, FDEV)
+ CreateByteField(Arg0, 154, BFRP)
+ ToInteger(BFRP, FDRP)
+ }
+ // Get Task File
+ Method(_GTF,0,Serialized)
+ {
+ //Set Feature Command to enable DevSlp
+ If (LAnd(LAnd(LEqual(DVS2, 1), LEqual(And(FDEV, 0x01), 0x01)), LEqual(And(FDRP, 0x80), 0x80))) {
+ Name(PIB1, Buffer(7)
+ {0x10, 0x09, 0x00, 0x00, 0x00, 0xB0, 0xEF })
+ Return (PIB1)
+ }
+ Name(PIB2, Buffer(7)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+ Return (PIB2)
+ }
+ }
+ Device(PRT3)
+ {
+ Name(_ADR,0x0003FFFF) // Port 3
+ Name(FDEV, Zero)
+ Name(FDRP, Zero)
+ Method(_SDD,1, Serialized)
+ {
+ CreateByteField(Arg0, 157, BFDS)
+ ToInteger(BFDS, FDEV)
+ CreateByteField(Arg0, 154, BFRP)
+ ToInteger(BFRP, FDRP)
+ }
+ // Get Task File
+ Method(_GTF,0,Serialized)
+ {
+ //Set Feature Command to enable DevSlp
+ If (LAnd(LAnd(LEqual(DVS3, 1), LEqual(And(FDEV, 0x01), 0x01)), LEqual(And(FDRP, 0x80), 0x80))) {
+ Name(PIB1, Buffer(7)
+ {0x10, 0x09, 0x00, 0x00, 0x00, 0xB0, 0xEF })
+ Return (PIB1)
+ }
+ Name(PIB2, Buffer(7)
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 })
+ Return (PIB2)
+ }
+ }
+ }
+
+ Device(SAT1) {
+ Name(_ADR,0x001F0005)
+ //
+ // SATA Methods pulled in via SSDT.
+ //
+ }
+
+ //
+ // SMBus Controller - Device 31, Function 3
+ //
+ Device(SBUS) {
+ Name(_ADR,0x001F0003)
+ Include("PchSmb.asl")
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif
new file mode 100644
index 0000000..e1bbbb9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "PchAcpiTables"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\AcpiTables\Dsdt"
+ RefName = "PchAcpiTables"
+[files]
+"PchAcpiTables.sdl"
+"PchAcpiTables.inf"
+"Pch.asl"
+"PchAudio.asl"
+"PchPcie.asl"
+"PchSmb.asl"
+"PchEhci1.asl"
+"PchEhci2.asl"
+"UsbSbd.asl"
+"PchXhci.asl"
+"PchAudioDsp.asl"
+"PchSerialIo.asl"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf
new file mode 100644
index 0000000..0cce4b9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.inf
@@ -0,0 +1,53 @@
+## @file
+# Component description file for the ACPI tables
+#
+#@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
+#
+
+
+[defines]
+BASE_NAME = PchAcpiTables
+FILE_GUID = 31401EE7-1600-437c-A11C-B1035D8E6070
+COMPONENT_TYPE = PCH_ACPI_TABLES
+FFS_EXT = .ffs
+
+[sources.common]
+ Pch.asl
+ PchAudio.asl
+ PchAudioDsp.asl
+ PchSerialIo.asl
+ PchPcie.asl
+ PchSmb.asl
+ PchEhci1.asl
+ PchEhci2.asl
+ UsbSbd.asl
+ PchXhci.asl
+
+[libraries.common]
+
+[includes.common]
+ .
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl
new file mode 100644
index 0000000..56ded8a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAcpiTables.sdl
@@ -0,0 +1,735 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchAcpiTables/PchAcpiTables.sdl 5 11/07/13 3:10a Littleyan $
+#
+# $Revision: 5 $
+#
+# $Date: 11/07/13 3:10a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchAcpiTables/PchAcpiTables.sdl $
+#
+# 5 11/07/13 3:10a Littleyan
+# [TAG] EIP142529
+# [Category] SPEC Update
+# [Description] PCH RC update to 1.7.0
+# [Files] PchAcpiTables.sdl PchXhci.asl PchPciExpressHelpersLib.h
+# PchRegsThermal.h PchPciExpressHelpersLibrary.c
+# PchPm.c PchRootPorts.c PchInitPeim.c
+# PchSmmSx.c PchPcieSmm.c PchInfo.h
+# PchS3Peim.c SerialIoDevices.asl Sensor.asl
+#
+# 4 9/13/13 9:03a Barretlin
+# [TAG] EIP132976
+# [Category] Improvement
+# [Description] fix after plugging USB key on Rear USB3_1(TOP)
+# port(HS03) , there's no remove and save item in bot right corner
+# [Files] PchAcpiTables.sdl PchXhci.asl
+#
+# 3 5/24/13 2:48a Scottyang
+# [TAG] None
+# [Category] Improvement
+# [Description] Set token for OEM to change PchEhxi1.asl and
+# PchEhxi2.asl.
+# [Files] PchAcpiTables.sdl, PchEhci1.asl, PchEhci2.asl
+#
+# 2 5/06/13 8:14a Scottyang
+# [TAG] None
+# [Category] Improvement
+# [Description] Set token for OEM easy to modify.
+# [Files] PchAcpiTables.sdl
+# PchXhci.asl
+#
+# 1 2/08/12 8:39a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = PchAcpiTables_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchAcpiTables support in Project"
+End
+
+TOKEN
+ Name = "EHC1_PR01_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR01_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR11_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR11_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR12_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR12_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR13_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR13_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR14_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR14_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR15_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR15_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR16_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR16_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR17_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR17_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR18_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC1_PR18_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR01_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR01_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR11_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR11_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR12_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR12_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR13_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR13_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR14_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR14_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR15_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR15_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR16_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHC2_PR16_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB1, 0x1E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS01_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS01's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS01_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS01's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS02_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS02's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS02_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS02's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS03_INTERNAL"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Help = "1: HS03 is internal port./0: HS03 is external port."
+End
+
+TOKEN
+ Name = "HS03_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS03's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS03_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS03's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS04_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS04's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS04_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS04's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS05_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS05's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS05_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS05's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS06_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS06's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS06_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS06's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS07_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS07's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS07_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS07's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS08_UPC"
+ Value = "0xFF,0x00,0x00,0x00"
+ Help = "HS08's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS08_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS08's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS09_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS09's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS09_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS09's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS10_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "HS10's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS10_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS10's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS11_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS11's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS11_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS11's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS12_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS12's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS12_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS12's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS13_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS13's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS13_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS13's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS14_UPC"
+ Value = "0xFF,0xFF,0x00,0x00"
+ Help = "HS14's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS14_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS14's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS15_UPC"
+ Value = "0x00,0x00,0x00,0x00"
+ Help = "HS15's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HS15_PLD"
+ Value = "0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "HS15's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP1_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP1's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP1_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP1's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP1_PR3"
+ Value = "0x01"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP2_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP2's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP2_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x0C, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP2's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP2_PR3"
+ Value = "0x02"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP3_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP3's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP3_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP3's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP3_PR3"
+ Value = "0x04"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP4_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP4's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP4_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP4's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP4_PR3"
+ Value = "0x08"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP5_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP5's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP5_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP5's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP5_PR3"
+ Value = "0x10"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP6_UPC"
+ Value = "0xFF,0x03,0x00,0x00"
+ Help = "SSP6's Usb Port Capabilities"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP6_PLD"
+ Value = "0x01, 0xC6, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0C, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00"
+ Help = "SSP6's Physical Location Description"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP6_PR3"
+ Value = "0x20"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "PchAcpiTables_DIR"
+End
+
+ELINK
+ Name = "$(PchAcpiTables_DIR)\Pch.asl"
+ Parent = "INTEL_GENERIC_ASL"
+ Priority = 1
+ 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/AcpiTables/Dsdt/PchAudio.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudio.asl
new file mode 100644
index 0000000..df64da3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudio.asl
@@ -0,0 +1,44 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+ //
+ // High Definition Audio - Device 27, Function 0
+ //
+ OperationRegion(HDAR, PCI_Config, 0x4C,0x10)
+ Field(HDAR,WordAcc,NoLock,Preserve) {
+ Offset(0), // 0x4C, Dock Control Register
+ DCKA,1, // Dock Attach
+ ,7,
+ Offset(1), // 04Dh, Dock Status Register
+ DCKM,1, // Dock Mated
+ ,6,
+ DCKS,1, // Docking Supported
+ Offset(8), // 0x54, Power Management Control and Status Register
+ , 8,
+ PMEE,1,
+ , 6,
+ PMES,1 // PME Status
+ }
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl
new file mode 100644
index 0000000..159179b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchAudioDsp.asl
@@ -0,0 +1,133 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ Name (_HID, "INT33C8")
+ Name (_CID, "INT33C8")
+ Name (_DDN, "Intel(R) Smart Sound Technology Host Controller - INT33C8" )
+ Name (_UID, 1)
+
+ Method(_DEP){
+ ADBG("ADSP DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("ADSP DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("ADSP DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ // Default parameters values for Realtek codec
+ Name (MCLK, Zero)
+ Name (SCLK, 0x9)
+ Name (SSPM, Zero)
+
+ // Bluetooth support
+ Name (ABTH, Zero)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00100000, BAR0) // MMIO 1 - Audio DSP MMIO
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR1) // MMIO 2 - Shadowed PCI Config Space
+ Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {3} // Audio DSP IRQ
+ })
+
+ Name (EOD, 1)
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Switch (ToInteger(CODS))
+ {
+ Case (0) {
+ // Realtek param values
+ Store (\_SB.PCI0.I2C0.ACD0.MCLK, \_SB.PCI0.ADSP.MCLK)
+ Store (\_SB.PCI0.I2C0.ACD0.SCLK, \_SB.PCI0.ADSP.SCLK)
+ Store (\_SB.PCI0.I2C0.ACD0.SSPM, \_SB.PCI0.ADSP.SSPM)
+ }
+ Case (1) {
+ // Cirrus param values
+ Store (\_SB.PCI0.I2C0.ACD1.MCLK, \_SB.PCI0.ADSP.MCLK)
+ Store (\_SB.PCI0.I2C0.ACD1.SCLK, \_SB.PCI0.ADSP.SCLK)
+ Store (\_SB.PCI0.I2C0.ACD1.SSPM, \_SB.PCI0.ADSP.SSPM)
+ }
+ Case (2) {
+ // IDT param values
+ Store (\_SB.PCI0.I2C0.ACD2.MCLK, \_SB.PCI0.ADSP.MCLK)
+ Store (\_SB.PCI0.I2C0.ACD2.SCLK, \_SB.PCI0.ADSP.SCLK)
+ Store (\_SB.PCI0.I2C0.ACD2.SSPM, \_SB.PCI0.ADSP.SSPM)
+ }
+ Default {
+ // Realtek params as default
+ Store (\_SB.PCI0.I2C0.ACD0.MCLK, \_SB.PCI0.ADSP.MCLK)
+ Store (\_SB.PCI0.I2C0.ACD0.SCLK, \_SB.PCI0.ADSP.SCLK)
+ Store (\_SB.PCI0.I2C0.ACD0.SSPM, \_SB.PCI0.ADSP.SSPM)
+ }
+ }
+ Return (RBUF)
+ }
+
+ Method (_SRS, 0x1, Serialized)
+ {
+ Store (1, EOD)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LGreaterEqual(OSYS,2012))
+ {
+ If(LEqual(S0ID, 1))
+ {
+ CreateDWordField (^RBUF,^BAR0._BAS,BVAL)
+ If (LEqual(BVAL, 0))
+ {
+ Return (0x0)
+ }
+ If (And (EOD, 0x1, EOD))
+ {
+ Return (0xf) // Enabled 1111
+ }
+ Else
+ {
+ Return (0xd) // Disabled 1101
+ }
+ }
+ }
+ Return (0x0)
+ }
+
+ Method (_DIS, 0x0, NotSerialized)
+ {
+ Store (0, EOD)
+ }
+
+ Device (I2S0)
+ { // I2S Port 0
+ Name (_ADR, 0)
+ }
+ Device (I2S1)
+ { // I2S Port 1
+ Name (_ADR, 1)
+ } \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl
new file mode 100644
index 0000000..327b5c2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci1.asl
@@ -0,0 +1,238 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ OperationRegion(PWKE,PCI_Config,0x54,0x12)
+
+ Field(PWKE,DWordAcc,NoLock,Preserve)
+ {
+ , 8,
+ PMEE, 1, // PWR_CNTL_STS.PME_En
+ , 6,
+ PMES, 1, // PWR_CNTL_STS.PME_Sts
+ Offset (0x0E),
+ , 1,
+ PWUC, 8 // Port Wake Up Capability Mask
+ }
+
+ Method(_PSW,1)
+ {
+ If(Arg0)
+ {
+ Store(Ones,PWUC)
+ }
+ Else
+ {
+ Store(0,PWUC)
+ }
+ }
+
+ // The CRB leaves the USB ports on in S3/S4 to allow
+ // the ability to Wake from USB. Therefore, define
+ // the below control methods to state D2 entry during
+ // the given S-State.
+
+ Method(_S3D,0)
+ {
+ Return(2)
+ }
+
+ Method(_S4D,0)
+ {
+ Return(2)
+ }
+
+ Device(HUBN)
+ {
+ Name(_ADR, Zero)
+
+ Device(PR01)
+ {
+ Name(_ADR, One)
+
+ //
+ // There will have "Generic USB Hub" existed at Port 1 of each EHCI controller
+ // in Windows "Device Manager" while RMH is enabled, so need to add _UPC
+ // and _PLD to report OS that it's not user visible to pass WHQL: Single Computer
+ // Display Object test in Win7
+ //
+ Method(_UPC,0,Serialized) {
+ Name(UPCA, Package() { ASL_EHC1_PR01_UPC })
+ Return(UPCA)
+ }
+
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR01_PLD}
+ })
+
+ Return (PLDP)
+ }
+
+ Device(PR11)
+ {
+ Name(_ADR, One)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR11_UPC })
+ Return(UPCP)
+ }
+
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR11_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ Device(PR12)
+ {
+ Name(_ADR, 0x02)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR12_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR12_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ Device(PR13)
+ {
+ Name(_ADR, 0x03)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR13_UPC })
+ Return(UPCP)
+ }
+
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR13_PLD}
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LEqual(And(CDID,0xF000), 0x9000)) { // on LPT-LP platforms this port is internal
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(PR14)
+ {
+ Name(_ADR, 0x04)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR14_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR14_PLD}
+ })
+ Return (PLDP)
+ }
+ Alias(SBV1,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR15)
+ {
+ Name(_ADR, 0x05)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR15_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR15_PLD}
+ })
+ Return (PLDP)
+ }
+ Alias(SBV2,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR16)
+ {
+ Name(_ADR, 0x06)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR16_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR16_PLD}
+ })
+ Return (PLDP)
+ }
+ Alias(SBV1,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR17)
+ {
+ Name(_ADR, 0x07)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR17_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR17_PLD}
+ })
+ Return (PLDP)
+ }
+ Alias(SBV2,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR18)
+ {
+ Name(_ADR, 0x08)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC1_PR18_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC1_PR18_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+ } // End of PR01
+ } // End of HUBN
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl
new file mode 100644
index 0000000..0449f59
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchEhci2.asl
@@ -0,0 +1,199 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ OperationRegion(PWKE,PCI_Config,0x54,0x12)
+
+ Field(PWKE,DWordAcc,NoLock,Preserve)
+ {
+ , 8,
+ PMEE, 1, // PWR_CNTL_STS.PME_En
+ , 6,
+ PMES, 1, // PWR_CNTL_STS.PME_Sts
+ Offset (0x0E),
+ , 1,
+ PWUC, 6 // Port Wake Up Capability Mask
+ }
+
+ Method(_PSW,1)
+ {
+ If(Arg0)
+ {
+ Store(Ones,PWUC)
+ }
+ Else
+ {
+ Store(0,PWUC)
+ }
+ }
+
+ // The CRB leaves the USB ports on in S3/S4 to allow
+ // the ability to Wake from USB. Therefore, define
+ // the below control methods to state D2 entry during
+ // the given S-State.
+
+ Method(_S3D,0)
+ {
+ Return(2)
+ }
+
+ Method(_S4D,0)
+ {
+ Return(2)
+ }
+
+ Device(HUBN)
+ {
+ Name(_ADR, Zero)
+
+ Device(PR01)
+ {
+ Name(_ADR, One)
+
+ //
+ // There will have "Generic USB Hub" existed at Port 1 of each EHCI controller
+ // in Windows "Device Manager" while RMH is enabled, so need to add _UPC
+ // and _PLD to report OS that it's not user visible to pass WHQL: Single Computer
+ // Display Object test in Win7
+ //
+ Method(_UPC,0,Serialized) {
+ Name(UPCA, Package() { ASL_EHC2_PR01_UPC })
+ Return(UPCA)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR01_PLD}
+ })
+ Return (PLDP)
+ }
+
+ Device(PR11)
+ {
+ Name(_ADR, One)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR11_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR11_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ Device(PR12)
+ {
+ Name(_ADR, 0x02)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR12_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR12_PLD}
+ })
+ Return (PLDP)
+ }
+ Alias(SBV1,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#1) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR13)
+ {
+ Name(_ADR, 0x03)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR13_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR13_PLD}
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LEqual(And(CDID,0xF000), 0x9000)) { // on LPT-LP platforms this port is internal
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ Alias(SBV2,SDGV) // copy USB Sideband Deferring GPE Vector (HOST_ALERT#2) to DSM method
+ Include("UsbSBD.ASL")
+ }
+
+ Device(PR14)
+ {
+ Name(_ADR, 0x04)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR14_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR14_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ Device(PR15)
+ {
+ Name(_ADR, 0x05)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR15_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR15_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ Device(PR16)
+ {
+ Name(_ADR, 0x06)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_EHC2_PR16_UPC })
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer (0x10) {
+ ASL_EHC2_PR16_PLD}
+ })
+ Return (PLDP)
+ }
+ }
+
+ } // End of PR01
+ } // End of HUBN
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl
new file mode 100644
index 0000000..5a64ec9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchPcie.asl
@@ -0,0 +1,288 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+
+ OperationRegion(PXCS,PCI_Config,0x00,0x380)
+ Field(PXCS,AnyAcc, NoLock, Preserve)
+ {
+ Offset(0),
+ VDID, 32,
+ Offset(0x19), // BNUM - Bus Number Register
+ SCBN, 8, // Secondary Bus Number
+ Offset(0x50), // LCTL - Link Control Register
+ L0SE, 1, // 0, L0s Entry Enabled
+ , 3,
+ LDIS, 1,
+ , 3,
+ Offset(0x52), // LSTS - Link Status Register
+ , 13,
+ LASX, 1, // 0, Link Active Status
+// AMI_OVERRIDE, [EIP84720]>
+ Offset(0x54), // SLCAP - Slot Capabilities Register
+ , 6,
+ HPCE, 1, // 6, Hot Plug Capable
+// AMI_OVERRIDE, [EIP84720]<
+ Offset(0x5A), // SLSTS[7:0] - Slot Status Register
+ ABPX, 1, // 0, Attention Button Pressed
+ , 2,
+ PDCX, 1, // 3, Presence Detect Changed
+ , 2,
+ PDSX, 1, // 6, Presence Detect State
+ , 1,
+ Offset(0x60), // RSTS - Root Status Register
+ , 16,
+ PSPX, 1, // 16, PME Status
+// AMI_OVERRIDE, [EIP121262]>
+ PMEP, 1, // 17, PME Pending
+// AMI_OVERRIDE, [EIP121262]<
+ Offset(0xA4),
+ D3HT, 2, // Power State
+ Offset(0xD8), // MPC - Miscellaneous Port Configuration Register
+ , 30,
+ HPEX, 1, // 30, Hot Plug SCI Enable
+ PMEX, 1, // 31, Power Management SCI Enable
+ Offset(0xE2), // RPPGEN - Root Port Power Gating Enable
+ , 2,
+ L23E, 1, // 2, L23_Rdy Entry Request (L23ER)
+ L23R, 1, // 3, L23_Rdy to Detect Transition (L23R2DT)
+ Offset(0x324),
+ , 3,
+ LEDM, 1 // PCIEDBG.DMIL1EDM
+ }
+ Field(PXCS,AnyAcc, NoLock, WriteAsZeros)
+ {
+ Offset(0xDC), // SMSCS - SMI/SCI Status Register
+ , 30,
+ HPSX, 1, // 30, Hot Plug SCI Status
+ PMSX, 1 // 31, Power Management SCI Status
+ }
+
+ Method(_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(VDID, 0xFFFFFFFF)){
+ Return(0x00)
+ } Else {
+ Return(0x0F)
+ }
+ }
+
+ Name(LTRV, Package(){0,0,0,0})
+ Name(OPTS, 0) // PCH SETUP options for LTR and OBFF
+// AMI_OVERRIDE, [EIP121262]>
+ Name(RPAV, 0)
+// AMI_OVERRIDE, [EIP121262]<
+ //
+ // _DSM Device Specific Method
+ //
+ // Arg0: UUID Unique function identifier
+ // Arg1: Integer Revision Level
+ // Arg2: Integer Function Index (0 = Return Supported Functions)
+ // Arg3: Package Parameters
+ Method(_DSM, 4, Serialized) {
+ //
+ // Switch based on which unique function identifier was passed in
+ //
+ Switch(ToInteger(Arg0)) {
+ //
+ // _DSM Definitions for Latency Tolerance Reporting
+ //
+ // Arguments:
+ // Arg0: UUID: E5C937D0-3553-4d7a-9117-EA4D19C3434D
+ // Arg1: Revision ID: 2
+ // Arg2: Function Index: 1, 4 or 6
+ // Arg3: Empty Package
+ //
+ // Return:
+ // A Package of four integers corresponding with the LTR encoding defined
+ // in the PCI Express Base Specification, as follows:
+ // Integer 0: Maximum Snoop Latency Scale
+ // Integer 1: Maximum Snoop Latency Value
+ // Integer 2: Maximum No-Snoop Latency Scale
+ // Integer 3: Maximum No-Snoop Latency Value
+ // These values correspond directly to the LTR Extended Capability Structure
+ // fields described in the PCI Express Base Specification.
+ //
+ Case(ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")) {
+ //
+ // Switch by function index
+ //
+ Switch(ToInteger(Arg2)) {
+ //
+ // Function Index:0
+ // Standard query - A bitmask of functions supported
+ //
+ Case (0)
+ {
+ if (LEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+ Store(1, OPTS) // function 0
+ if (LTRE){
+ Or(OPTS,0x40,OPTS) // function 6
+ }
+ if (OBFF){
+ Or(OPTS,0x10,OPTS) // function 4
+ }
+ Return (OPTS) // bitmask of supported functions: 6, 4, 0.
+ } else {
+ Return (0)
+ }
+ }
+ //
+ // Function Index: 4
+ //
+ Case(4) {
+ if (LEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+ if (OBFF){
+ Return (Buffer () {0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0}) // OBFF capable, offset 4[08h]
+ } else {
+ Return (Buffer () {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0})
+ }
+ }
+ }
+ //
+ // Function Index: 6
+ // LTR Extended Capability Structure
+ //
+ Case(6) {
+ if (LEqual(Arg1, 2)){ // test Arg1 for Revision ID: 2
+ if (LTRE){
+ if (LOr(LEqual(LMSL, 0xFFFFFFFF),LEqual(LNSL, 0xFFFFFFFF)))
+ {
+ if (LEqual (PCHS, 1)) {
+ //PCH-H
+ Store (0x0846, LMSL)
+ Store (0x0846, LNSL)
+ } elseif (LEqual (PCHS, 2)) {
+ //PCH-LP
+ Store (0x1003, LMSL)
+ Store (0x1003, LNSL)
+ }
+ }
+ Store(And(ShiftRight(LMSL,10),7), Index(LTRV, 0))
+ Store(And(LMSL,0x3FF), Index(LTRV, 1))
+ Store(And(ShiftRight(LNSL,10),7), Index(LTRV, 2))
+ Store(And(LNSL,0x3FF), Index(LTRV, 3))
+
+ Return (LTRV)
+ } else {
+ Return (0)
+ }
+ }
+ }
+ } // End of switch(Arg2)
+ } // End of case(ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D"))
+ } // End of switch(Arg0)
+ return (Buffer() {0x00})
+ } // End of _DSM
+
+ Device(PXSX)
+ {
+ Name(_ADR, 0x00000000)
+
+ // NOTE: Any PCIE Hot-Plug dependency for this port is
+ // specific to the CRB. Please modify the code based on
+ // your platform requirements.
+
+ Method(_PRW, 0) { Return(GPRW(0x09, 4)) } // can wakeup from S4 state
+// AMI_OVERRIDE, [EIP84720]>
+ Method(_RMV, 0, NotSerialized){
+#if defined ASL_Thunderbolt_SUPPORT && ASL_Thunderbolt_SUPPORT == 1 && ASL_TBT_RC_VERSION > 17
+ If(LEqual(\TBUS, SCBN))
+ {
+#if defined ASL_DEFAULT_TBT_RMV_RETURN_VALUE && ASL_DEFAULT_TBT_RMV_RETURN_VALUE == 1
+ Return(TBMV)
+#else
+ Return(0)
+#endif
+ }
+ Else
+ {
+ Return(HPCE) //0:device cannot be removed 1:device can be removed
+ }
+#else
+ Return(HPCE) //0:device cannot be removed 1:device can be removed
+#endif
+ }
+// AMI_OVERRIDE, [EIP84720]<
+
+ }
+
+// AMI_OVERRIDE, [EIP121262]>
+ Method(_REG,2)
+ {
+ If(LAnd(LEqual(Arg0,2),LEqual(Arg1,1)))
+ {
+ Store(One, RPAV)
+ }
+ }
+// AMI_OVERRIDE, [EIP121262]<
+
+ //
+ // PCI_EXP_STS Handler for PCIE Root Port
+ //
+ Method(HPME,0,Serialized)
+ {
+// AMI_OVERRIDE, [EIP105657]>
+ If(LOr(PSPX, PMEP)){
+ Store(PMEX, Local1)
+ Store(0, PMEX)
+ Sleep(50)
+ Store(1, PSPX)
+ Sleep(50)
+ If(PSPX){
+ Store(1, PSPX)
+ Sleep(50)
+ }
+ Store(Local1, PMEX)
+ }
+// AMI_OVERRIDE, [EIP105657]<
+
+ If(PMSX) {
+ //
+ // Clear the PME SCI status bit with timout
+ //
+ Store(200,Local0)
+ While(Local0) {
+ //
+ // Clear PME SCI Status
+ //
+ Store(1, PMSX)
+ //
+ // If PME SCI Status is still set, keep clearing it.
+ // Otherwise, break the while loop.
+ //
+ If(PMSX) {
+ Decrement(Local0)
+ } else {
+ Store(0,Local0)
+ }
+ }
+ //
+ // Notify PCIE Endpoint Devices
+ //
+ Notify(PXSX, 0x02)
+ }
+ }
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl
new file mode 100644
index 0000000..1142148
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSerialIo.asl
@@ -0,0 +1,1029 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the SandyBridge *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ //
+ // System Bus
+ //
+ Scope (\_SB.PCI0)
+ {
+
+ External(BID)
+ External(\_SB.PCI0.I2C0.PS0X, MethodObj)
+ External(\_SB.PCI0.I2C0.PS3X, MethodObj)
+ External(\_SB.PCI0.I2C1.PS0X, MethodObj)
+ External(\_SB.PCI0.SDHC.PS0X, MethodObj)
+
+ Device(SIRC)
+ {
+ //
+ // Serial IO devices occupy 2 address ranges each: BAR0 and BAR1.
+ // Each device claims its BAR0 addresses in its own _CRS method
+ // BAR1 addresses are not defined inside devices; instead, they are gathered in SIRC device
+ // SIRC also contains about half of BAR0 for SDIO - upper half except 0xC bytes which are clamed by WiFi device
+ //
+ Name(_HID,EISAID("PNP0C02"))
+
+ Name(_UID,4)
+
+ Method(_STA)
+ {
+ If(LLess(OSYS,2012)) { Return(0x0) } // check for Win7 or older
+ If(LEqual(And(CDID,0xF000), 0x8000)) { Return(0x0) } // check for LPT-H chipset
+ Return (0xF)
+ }
+
+ //
+ // Base address of the below memory ranges will be updated with actual addresses during BIOS execution.
+ //
+ Name(BUF1,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU01) }) // Serial IO SDMA BAR1
+ Name(BUF2,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU02) }) // Serial IO I2C0 BAR1
+ Name(BUF3,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU03) }) // Serial IO I2C1 BAR1
+ Name(BUF4,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU04) }) // Serial IO SPI0 BAR1
+ Name(BUF5,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU05) }) // Serial IO SPI1 BAR1
+ Name(BUF6,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU06) }) // Serial IO UA00 BAR1
+ Name(BUF7,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU07) }) // Serial IO UA01 BAR1
+ Name(BUF8,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BU08) }) // Serial IO SDIO BAR1
+ Name(BUFL,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00000008, SDLO) }) // Serial IO SDIO BAR0 lower part
+ Name(BUFH,ResourceTemplate() { Memory32Fixed (ReadWrite, 0x00000000, 0x00000FEC, SDHI) }) // Serial IO SDIO BAR0 upper part
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Store(ResourceTemplate() { }, Local0) // placeholder for concatenated buffers
+ CreateDWordField(BUF1, ^BU01._BAS, BR01)
+ CreateDWordField(BUF2, ^BU02._BAS, BR02)
+ CreateDWordField(BUF3, ^BU03._BAS, BR03)
+ CreateDWordField(BUF4, ^BU04._BAS, BR04)
+ CreateDWordField(BUF5, ^BU05._BAS, BR05)
+ CreateDWordField(BUF6, ^BU06._BAS, BR06)
+ CreateDWordField(BUF7, ^BU07._BAS, BR07)
+ CreateDWordField(BUF8, ^BU08._BAS, BR08)
+ //
+ // concatenate all buffers with non-zero address into Local0
+ //
+ If(LNotEqual(BR01, 0)) { ConcatenateResTemplate(Local0, BUF1, Local0) }
+ If(LNotEqual(BR02, 0)) { ConcatenateResTemplate(Local0, BUF2, Local0) }
+ If(LNotEqual(BR03, 0)) { ConcatenateResTemplate(Local0, BUF3, Local0) }
+ If(LNotEqual(BR04, 0)) { ConcatenateResTemplate(Local0, BUF4, Local0) }
+ If(LNotEqual(BR05, 0)) { ConcatenateResTemplate(Local0, BUF5, Local0) }
+ If(LNotEqual(BR06, 0)) { ConcatenateResTemplate(Local0, BUF6, Local0) }
+ If(LNotEqual(BR07, 0)) { ConcatenateResTemplate(Local0, BUF7, Local0) }
+
+ If(LNotEqual(BR08, 0)) {
+ ConcatenateResTemplate(Local0, ^BUF8, Local0)
+ //
+ // Calculate regions occupied by SDIO's BAR0
+ //
+ OperationRegion(SDCH, SystemMemory, BR08, 0x40) // SDHC PCI Config Header
+ Field(SDCH, DWordAcc, NoLock, Preserve) {
+ Offset(0x10),
+ BAR0, 32
+ }
+
+ CreateDWordField(^BUFL, ^SDLO._BAS, LBAS)
+ CreateDWordField(^BUFH, ^SDHI._BAS, HBAS)
+ Add(BAR0, 0x1000, LBAS)
+ Add(BAR0, 0x1014, HBAS)
+
+ ConcatenateResTemplate(Local0, BUFL, Local0)
+ ConcatenateResTemplate(Local0, BUFH, Local0)
+ }
+
+ Return (Local0)
+ } //end _CRS
+
+ Method(CNTR,1,Serialized)
+ {
+ Switch (ToInteger(Arg0))
+ {
+ Case (1) { CreateDWordField(^BUF1,^BU01._BAS, BAR1); Return(BAR1) }
+ Case (2) { CreateDWordField(^BUF2,^BU02._BAS, BAR2); Return(BAR2) }
+ Case (3) { CreateDWordField(^BUF3,^BU03._BAS, BAR3); Return(BAR3) }
+ Case (4) { CreateDWordField(^BUF4,^BU04._BAS, BAR4); Return(BAR4) }
+ Case (5) { CreateDWordField(^BUF5,^BU05._BAS, BAR5); Return(BAR5) }
+ Case (6) { CreateDWordField(^BUF6,^BU06._BAS, BAR6); Return(BAR6) }
+ Case (7) { CreateDWordField(^BUF7,^BU07._BAS, BAR7); Return(BAR7) }
+ Case (8) { CreateDWordField(^BUF8,^BU08._BAS, BAR8); Return(BAR8) }
+ Default { Return (0xFFFFFFFF) }
+ }
+ } //end CNTR
+
+ } // end of SIRC
+
+ //----------------------------
+ // Serial IO GPIO Controller
+ //----------------------------
+ Device (GPI0)
+ {
+ Name (_HID, "INT33C7")
+ Name (_CID, "INT33C7")
+ Name (_UID, 1)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // BIOS specific change.
+ // Provide Min & Max IO range addresses
+ // BIOS to update AddressMinimum & AddressMaximum fields
+ // dynamically after PCI enumeration.
+ //
+ DWordIo (ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange,
+ 0x0000, 0x0000, 0x03FF, 0x0000, 0x0400,,, BAR0)
+ })
+
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+
+ Return (RBUF)
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._MIN,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+ } // Device (GPI0)
+
+ //---------------------------
+ // Serial IO DMA Controller
+ //---------------------------
+ Device (SDMA)
+ {
+ Name (_HID, "INTL9C60")
+ Name (_UID, 1)
+ Name (_ADR, 0x00150000)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , , ) {20}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ Method (PTD3, 0x0, NotSerialized) {
+ //
+ // put DMA hardware in D3
+ //
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(1), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(1),0x84 ,Local0)
+ OperationRegion(DMB1, SystemMemory, Local0, 4)
+ Field(DMB1, DWordAcc, NoLock, Preserve) { TEMP, 32 }
+ Or(TEMP, 0x3, TEMP)
+ }
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // OS older than Win 8? hide the device
+ If(LAnd(LEqual(DOSD, 2), LEqual(OSYS,2012))) { PTD3(); Return(0x0) } // "auto" mode & Win8? hide the device
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ } // Device (SDMA)
+
+
+ //----------------------------
+ // Serial IO I2C0 Controller
+ //----------------------------
+ Device (I2C0)
+ {
+ Name (_HID, "INT33C2")
+ Name (_CID, "INT33C2")
+ Name (_UID, 1)
+ Name (_ADR, 0x00150001)
+
+ Method(_DEP){
+ ADBG("I2C0 DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("I2C0 DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("I2C0 DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ Method (SSCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 432, 507, 9 })
+ Store(SSH0, Index(PKG,0))
+ Store(SSL0, Index(PKG,1))
+ Store(SSD0, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (FMCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 72, 160, 9 })
+ Store(FMH0, Index(PKG,0))
+ Store(FML0, Index(PKG,1))
+ Store(FMD0, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (FPCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 26, 50, 5 })
+ Store(FPH0, Index(PKG,0))
+ Store(FPL0, Index(PKG,1))
+ Store(FPD0, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C0, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 2000 })
+ Store(M1C0, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M0D0, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 0 })
+ Store(M2C0, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Name (DBUF, ResourceTemplate ()
+ {
+ //
+ // Provide Serial IO DMA channels used by the I2C0 controller
+ //
+ FixedDMA(0x18, 4, Width32Bit, DMA1) //Tx
+ FixedDMA(0x19, 5, Width32Bit, DMA2) //Rx
+ })
+ If(LNotEqual(\_SB_.PCI0.SDMA._STA, 0x0)) {
+ Return (ConcatenateResTemplate(RBUF, DBUF))
+ } Else {
+ Return (RBUF)
+ }
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for I2C0
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("I2C0 Ctrlr D0")
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(2), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(2),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ If(CondRefOf(\_SB.PCI0.I2C0.PS0X))
+ {
+ \_SB.PCI0.I2C0.PS0X()
+ }
+ }
+
+ // D3 Method for I2C0
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("I2C0 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(2), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(2),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ If(CondRefOf(\_SB.PCI0.I2C0.PS3X))
+ {
+ \_SB.PCI0.I2C0.PS3X()
+ }
+
+ }
+
+ } // Device (I2C0)
+
+ //----------------------------
+ // Serial IO I2C1 Controller
+ //----------------------------
+ Device (I2C1)
+ {
+ Name (_HID, "INT33C3")
+ Name (_CID, "INT33C3")
+ Name (_UID, 2)
+ Name (_ADR, 0x00150002)
+
+ Method(_DEP){
+ ADBG("I2C1 DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("I2C1 DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("I2C1 DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ Method (SSCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 432, 507, 9 })
+ Store(SSH1, Index(PKG,0))
+ Store(SSL1, Index(PKG,1))
+ Store(SSD1, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (FMCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 72, 160, 9 })
+ Store(FMH1, Index(PKG,0))
+ Store(FML1, Index(PKG,1))
+ Store(FMD1, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (FPCN, 0x0, NotSerialized)
+ {
+ Name (PKG, Package(3) { 26, 50, 5 })
+ Store(FPH1, Index(PKG,0))
+ Store(FPL1, Index(PKG,1))
+ Store(FPD1, Index(PKG,2))
+ Return (PKG)
+ }
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C1, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 2000 })
+ Store(M1C1, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M0D0, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 0 })
+ Store(M2C1, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Name (DBUF, ResourceTemplate ()
+ {
+ FixedDMA(0x1A, 6, Width32Bit, DMA1) //Tx
+ FixedDMA(0x1B, 7, Width32Bit, DMA2) //Rx
+ })
+
+ If(LNotEqual(\_SB_.PCI0.SDMA._STA, 0x0)) {
+ Return (ConcatenateResTemplate(RBUF, DBUF))
+ } Else {
+ Return (RBUF)
+ }
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for I2C1
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("I2C1 Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(3), 0)) {
+ If(CondRefOf(\_SB.PCI0.I2C1.PS0X))
+ {
+ \_SB.PCI0.I2C1.PS0X()
+ }
+ Add(\_SB.PCI0.SIRC.CNTR(3),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ // D3 Method for I2C1
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("I2C1 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(3), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(3),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+ } // Device (I2C1)
+
+ //----------------------------
+ // Serial IO SPI0 Controller
+ //----------------------------
+ Device (SPI0)
+ {
+ Name (_HID, "INT33C0")
+ Name (_CID, "INT33C0")
+ Name (_UID, 1)
+ Name (_ADR, 0x00150003)
+
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C2, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 2000 })
+ Store(M1C2, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+
+ }
+
+ // D0 Method for SPI0
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("SPI0 Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(4), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(4),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ // D3 Method for SPI0
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("SPI0 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(4), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(4),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+ } // Device (SPI0)
+
+ //----------------------------
+ // Serial IO SPI1 Controller
+ //----------------------------
+ Device (SPI1)
+ {
+ Name (_HID, "INT33C1")
+ Name (_CID, "INT33C1")
+ Name (_UID, 2)
+ Name (_ADR, 0x00150004)
+
+
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C3, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 2000 })
+ Store(M1C3, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Name (DBUF, ResourceTemplate ()
+ {
+ FixedDMA(0x10, 0, Width32Bit, DMA1) //Tx
+ FixedDMA(0x11, 1, Width32Bit, DMA2) //Rx
+ })
+
+ If(LNotEqual(\_SB_.PCI0.SDMA._STA, 0x0)) {
+ Return (ConcatenateResTemplate(RBUF, DBUF))
+ } Else {
+ Return (RBUF)
+ }
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for SPI1
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("SPI1 Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(5), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(5),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ // D3 Method for SPI1
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("SPI1 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(5), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(5),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+ } // Device (SPI1)
+
+ //-----------------------------
+ // Serial IO UART0 Controller
+ //-----------------------------
+ Device (UA00)
+ {
+ Name (_HID, "INT33C4")
+ Name (_CID, "INT33C4")
+ Name (_UID, 1)
+ Name (_ADR, 0x00150005)
+
+ Method(_DEP){
+ ADBG("UA00 DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("UA00 DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("UA00 DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C4, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M1C4, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x0001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for UAR0
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("UAR0 Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(6), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(6),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ // D3 Method for UAR0
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("UAR0 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(6), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(6),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+
+ } // Device (UART0)
+
+ //-----------------------------
+ // Serial IO UART1 Controller
+ //-----------------------------
+ Device (UA01)
+ {
+ Name (_HID, "INT33C5")
+ Name (_CID, "INT33C5")
+ Name (_UID, 2)
+ Name (_ADR, 0x00150006)
+
+ Method(_DEP){
+ ADBG("UA01 DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("UA01 DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("UA01 DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ Method (M0D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M0C5, Index(PKG,0))
+ Return (PKG)
+ }
+ Method (M1D3, 0x0, Notserialized)
+ {
+ Name (PKG, Package(1) { 200 })
+ Store(M1C5, Index(PKG,0))
+ Return (PKG)
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x0001000, BAR0)
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {21}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Name (DBUF, ResourceTemplate ()
+ {
+ FixedDMA(0x16, 2, Width32Bit, DMA1) //Tx
+ FixedDMA(0x17, 3, Width32Bit, DMA2) //Rx
+ })
+
+ If(LNotEqual(\_SB_.PCI0.SDMA._STA, 0x0)) {
+ Return (ConcatenateResTemplate(RBUF, DBUF))
+ } Else {
+ Return (RBUF)
+ }
+ }
+
+ Method (_HRV)
+ {
+ //
+ // Report LPC Revision Id
+ //
+ Return (CRID)
+ }
+
+ CreateDWordField(RBUF,BAR0._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for UAR1
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("UAR1 Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(7), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(7),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ // D3 Method for UAR1
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("UAR1 Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(7), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(7),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+ } // Device (UART1)
+
+ //--------------------------------
+ // Serial IO SDIO Host Controller
+ //--------------------------------
+ Device (SDHC)
+ {
+ Name (_HID, "INT33C6")
+ Name (_CID, "PNP0D40")
+ Name (_UID, 1)
+ Name (_ADR, 0x00170000)
+
+ Method(_DEP){
+ ADBG("SDHC DEP Call")
+ If(LEqual(S0ID, 1)){
+ ADBG("SDHC DEP")
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ ADBG("SDHC DEP NULL")
+ Return(Package() {})
+ }
+ }
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ //
+ // Resource settings will be overwritten after PCI enumeration
+ //
+ Memory32Fixed (ReadWrite, 0x00000000, 0x00001000, BARA) // BAR0 Range
+ Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {22}
+ })
+
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ CreateDWordField(RBUF,BARA._BAS,BVAL)
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(BVAL, 0)) { Return(0x0) } // has BAR for this device been programmed by the OS?
+ If(LLess(OSYS,2012)) { Return(0x0) } // Win 8 or above?
+ If(LEqual(S0ID, 1)) { Return(0xF) } // CS enabled in SETUP?
+ Return(0x0)
+ }
+
+ // D0 Method for SDHC
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("SDHC Ctrlr D0")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(8), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(8),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ And(TEMP, 0xFFFFFFFC, TEMP)
+ Store(TEMP, Local0)
+ }
+
+ If(CondRefOf(\_SB.PCI0.SDHC.PS0X))
+ {
+ \_SB.PCI0.SDHC.PS0X()
+ }
+ }
+
+ // D3 Method for SDHC
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("SDHC Ctrlr D3")
+
+ If(LNotEqual(\_SB.PCI0.SIRC.CNTR(8), 0)) {
+ Add(\_SB.PCI0.SIRC.CNTR(8),0x84 ,Local0)
+ OperationRegion(ICB1, SystemMemory, Local0, 4)
+ Field(ICB1, DWordAcc, NoLock, Preserve) {
+ Offset(0x0),
+ TEMP, 32
+ }
+ Or(TEMP, 0x3, TEMP)
+ Store(TEMP, Local0)
+ }
+ }
+
+ } // Device (SDHC)
+
+ } // Scope (\_SB.PCI0)
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl
new file mode 100644
index 0000000..6356e3c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchSmb.asl
@@ -0,0 +1,605 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* Copyright (c) 1999 - 2011 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 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
+--*/
+
+
+// Define various SMBus PCI Configuration Space Registers.
+
+OperationRegion(SMBP,PCI_Config,0x40,0xC0)
+Field(SMBP,DWordAcc,NoLock,Preserve)
+{
+ , 2,
+ I2CE, 1
+}
+
+OperationRegion(SMPB,PCI_Config,0x20,4)
+Field(SMPB,DWordAcc,NoLock,Preserve)
+{
+ , 5,
+ SBAR, 11
+}
+
+// Define various SMBus IO Mapped Registers.
+
+OperationRegion(SMBI,SystemIO,ShiftLeft(SBAR,5),0x10)
+Field(SMBI,ByteAcc,NoLock,Preserve)
+{
+ HSTS, 8, // 0 - Host Status Register
+ Offset(0x02),
+ HCON, 8, // 2 - Host Control
+ HCOM, 8, // 3 - Host Command
+ TXSA, 8, // 4 - Transmit Slave Address
+ DAT0, 8, // 5 - Host Data 0
+ DAT1, 8, // 6 - Host Data 1
+ HBDR, 8, // 7 - Host Block Data
+ PECR, 8, // 8 - Packer Error Check
+ RXSA, 8, // 9 - Receive Slave Address
+ SDAT, 16, // A - Slave Data
+}
+
+// SMBus Send Byte - This function will write a single byte of
+// data to a specific Slave Device per SMBus Send Byte Protocol.
+// Arg0 = Address
+// Arg1 = Data
+// Return: Success = 1
+// Failure = 0
+
+Method(SSXB,2,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform
+ // communication.
+
+ If(STRT())
+ {
+ Return(0)
+ }
+
+ // Step 2: Initiate a Send Byte.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Arg0,TXSA) // Write Address in TXSA.
+ Store(Arg1,HCOM) // Data in HCOM.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 001 = Byte Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x48,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP)
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others..
+ Return(1) // Return Success.
+ }
+
+ Return(0)
+}
+
+// SMBus Receive Byte - This function will write a single byte
+// of data to a specific Slave Device per SMBus Receive Byte
+// Protocol.
+// Arg0 = Address
+// Return: Success = Byte-Size Value
+// Failure = Word-Size Value = FFFFh.
+
+Method(SRXB,1,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform
+ // communication.
+
+ If(STRT())
+ {
+ Return(0xFFFF)
+ }
+
+ // Step 2: Initiate a Receive Byte.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Or(Arg0,1),TXSA) // Read Address in TXSA.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 001 = Byte Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x44,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP)
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others..
+ Return(DAT0) // Return Success.
+ }
+
+ Return(0xFFFF) // Return Failure.
+}
+
+// SMBus Write Byte - This function will write a single byte
+// of data to a specific Slave Device per SMBus Write Byte
+// Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Arg2 = Data
+// Return: Success = 1
+// Failure = 0
+
+Method(SWRB,3,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0)
+ }
+
+ // Step 2: Initiate a Write Byte.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Arg0,TXSA) // Write Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+ Store(Arg2,DAT0) // Data in DAT0.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 010 = Byte Data Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x48,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP)
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others..
+ Return(1) // Return Success.
+ }
+
+ Return(0) // Return Failure.
+}
+
+// SMBus Read Byte - This function will read a single byte of data
+// from a specific slave device per SMBus Read Byte Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Return: Success = Byte-Size Value
+// Failure = Word-Size Value
+
+Method(SRDB,2,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0xFFFF)
+ }
+
+ // Step 2: Initiate a Read Byte.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Or(Arg0,1),TXSA) // Read Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 010 = Byte Data Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x48,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP)
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others..
+ Return(DAT0) // Return Success.
+ }
+
+ Return(0xFFFF) // Return Failure.
+}
+
+// SMBus Write Word - This function will write a single word
+// of data to a specific Slave Device per SMBus Write Word
+// Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Arg2 = Data (16 bits in size)
+// Return: Success = 1
+// Failure = 0
+
+Method(SWRW,3,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0)
+ }
+
+ // Step 2: Initiate a Write Word.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Arg0,TXSA) // Write Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+ And(Arg2,0xFF,DAT1) // Low byte Data in DAT1.
+ And(ShiftRight(Arg2,8),0xFF,DAT0) // High byte Data in DAT0.
+
+ // Set the SMBus Host control register to 0x4C.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 011 = Word Data Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x4C,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP())
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.
+ Return(1) // Return Success.
+ }
+
+ Return(0) // Return Failure.
+}
+
+// SMBus Read Word - This function will read a single byte of data
+// from a specific slave device per SMBus Read Word Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Return: Success = Word-Size Value
+// Failure = Dword-Size Value
+
+Method(SRDW,2,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0xFFFF)
+ }
+
+ // Step 2: Initiate a Read Word.
+
+ Store(0,I2CE) // Ensure SMbus Mode.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Or(Arg0,1),TXSA) // Read Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+
+ // Set the SMBus Host control register to 0x4C.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 011 = Word Data Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x4C,HCON)
+
+ // Step 3: Exit the Method correctly.
+
+ If(COMP())
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.
+ Return(Or(ShiftLeft(DAT0,8),DAT1)) // Return Success.
+ }
+
+ Return(0xFFFFFFFF) // Return Failure.
+}
+
+// SMBus Block Write - This function will write an entire block of data
+// to a specific slave device per SMBus Block Write Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Arg2 = Buffer of Data to Write
+// Arg3 = 1 = I2C Block Write, 0 = SMBus Block Write
+// Return: Success = 1
+// Failure = 0
+
+Method(SBLW,4,Serialized)
+{
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0)
+ }
+
+ // Step 2: Initiate a Block Write.
+
+ Store(Arg3,I2CE) // Select the proper protocol.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Arg0,TXSA) // Write Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+ Store(Sizeof(Arg2),DAT0) // Count in DAT0.
+ Store(0,Local1) // Init Pointer to Buffer.
+ Store(DerefOf(Index(Arg2,0)),HBDR) // First Byte in HBD Register.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 101 = Block Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x54,HCON)
+
+ // Step 3: Send the entire Block of Data.
+
+ While(LGreater(Sizeof(Arg2),Local1))
+ {
+ // Wait up to 200ms for Host Status to get set.
+
+ Store(4000,Local0) // 4000 * 50us = 200ms.
+
+ While(LAnd(LNot(And(HSTS,0x80)),Local0))
+ {
+ Decrement(Local0) // Decrement Count.
+ Stall(50) // Delay = 50us.
+ }
+
+ If(LNot(Local0)) // Timeout?
+ {
+ KILL() // Yes. Kill Communication.
+ Return(0) // Return failure.
+ }
+
+ Store(0x80,HSTS) // Clear Host Status.
+ Increment(Local1) // Point to Next Byte.
+
+ // Place next byte in HBDR if last byte has not been sent.
+
+ If(LGreater(Sizeof(Arg2),Local1))
+ {
+ Store(DerefOf(Index(Arg2,Local1)),HBDR)
+ }
+ }
+
+ // Step 4: Exit the Method correctly.
+
+ If(COMP())
+ {
+ Or(HSTS,0xFF,HSTS) // Clear all status bits.
+ Return(1) // Return Success.
+ }
+
+ Return(0) // Return Failure.
+}
+
+// SMBus Block Read - This function will read a block of data from
+// a specific slave device per SMBus Block Read Protocol.
+// Arg0 = Address
+// Arg1 = Command
+// Arg2 = 1 = I2C Block Write, 0 = SMBus Block Write
+// Return: Success = Data Buffer (First Byte = length)
+// Failure = 0
+
+Method(SBLR,3,Serialized)
+{
+ Name(TBUF, Buffer(256) {})
+
+ // Step 1: Confirm the ICHx SMBus is ready to perform communication.
+
+ If(STRT())
+ {
+ Return(0)
+ }
+
+ // Step 2: Initiate a Block Read.
+
+ Store(Arg2,I2CE) // Select the proper protocol.
+ Store(0xBF,HSTS) // Clear all but INUSE_STS.
+ Store(Or(Arg0,1),TXSA) // Read Address in TXSA.
+ Store(Arg1,HCOM) // Command in HCOM.
+
+ // Set the SMBus Host control register to 0x48.
+ // Bit 7: = 0 = reserved
+ // Bit 6: = 1 = start
+ // Bit 5: = 0 = disregard, I2C related bit
+ // Bits 4:2: = 101 = Block Protocol
+ // Bit 1: = 0 = Normal Function
+ // Bit 0: = 0 = Disable interrupt generation
+
+ Store(0x54,HCON)
+
+ // Step 3: Wait up to 200ms to get the Data Count.
+
+ Store(4000,Local0) // 4000 * 50us = 200ms.
+
+ While(LAnd(LNot(And(HSTS,0x80)),Local0))
+ {
+ Decrement(Local0) // Decrement Count.
+ Stall(50) // Delay = 50us.
+ }
+
+ If(LNot(Local0)) // Timeout?
+ {
+ KILL() // Yes. Kill Communication.
+ Return(0) // Return failure.
+ }
+
+ Store(DAT0,Index(TBUF,0)) // Get the Data Count.
+ Store(0x80,HSTS) // Clear Host Status.
+ Store(1,Local1) // Local1 = Buffer Pointer.
+
+ // Step 4: Get the Block Data and store it.
+
+ While(LLess(Local1,DerefOf(Index(TBUF,0))))
+ {
+ // Wait up to 200ms for Host Status to get set.
+
+ Store(4000,Local0) // 4000 * 50us = 200ms.
+
+ While(LAnd(LNot(And(HSTS,0x80)),Local0))
+ {
+ Decrement(Local0) // Decrement Count.
+ Stall(50) // Delay = 50us.
+ }
+
+ If(LNot(Local0)) // Timeout?
+ {
+ KILL() // Yes. Kill Communication.
+ Return(0) // Return failure.
+ }
+
+ Store(HBDR,Index(TBUF,Local1)) // Place into Buffer.
+ Store(0x80,HSTS) // Clear Host Status.
+ Increment(Local1)
+ }
+
+ // Step 5: Exit the Method correctly.
+
+ If(COMP())
+ {
+ Or(HSTS,0xFF,HSTS) // Clear INUSE_STS and others.
+ Return(TBUF) // Return Success.
+ }
+
+ Return(0) // Return Failure.
+}
+
+
+// SMBus Start Check
+// Return: Success = 0
+// Failure = 1
+
+Method(STRT,0,Serialized)
+{
+ // Wait up to 200ms to confirm the SMBus Semaphore has been
+ // released (In Use Status = 0). Note that the Sleep time may take
+ // longer as the This function will yield the Processor such that it
+ // may perform different tasks during the delay.
+
+ Store(200,Local0) // 200 * 1ms = 200ms.
+
+ While(Local0)
+ {
+ If(And(HSTS,0x40)) // In Use Set?
+ {
+ Decrement(Local0) // Yes. Decrement Count.
+ Sleep(1) // Delay = 1ms.
+ If(LEqual(Local0,0)) // Count = 0?
+ {
+ Return(1) // Return failure.
+ }
+ }
+ Else
+ {
+ Store(0,Local0) // In Use Clear. Continue.
+ }
+ }
+
+ // In Use Status = 0 during last read, which will make subsequent
+ // reads return In Use Status = 1 until software clears it. All
+ // software using ICHx SMBus should check this bit before initiating
+ // any SMBus communication.
+
+ // Wait up to 200ms to confirm the Host Interface is
+ // not processing a command.
+
+ Store(4000,Local0) // 4000 * 50us = 200ms.
+
+ While(Local0)
+ {
+ If(And(HSTS,0x01)) // Host Busy Set?
+ {
+ Decrement(Local0) // Decrement Count.
+ Stall(50) // Delay = 50us.
+ If(LEqual(Local0,0)) // Count = 0?
+ {
+ KILL() // Yes. Kill Communication.
+ }
+ }
+ Else
+ {
+ Return(0)
+ }
+ }
+
+ Return(1) // Timeout. Return failure.
+}
+
+// SMBus Completion Check
+// Return: Success = 1
+// Failure = 0
+
+Method(COMP,0,Serialized)
+{
+ // Wait for up to 200ms for the Completion Command
+ // Status to get set.
+
+ Store(4000,Local0) // 4000 * 50us = 200ms.
+
+ While(Local0)
+ {
+ If(And(HSTS,0x02)) // Completion Status Set?
+ {
+ Return(1) // Yes. We are done.
+ }
+ Else
+ {
+ Decrement(Local0) // Decrement Count.
+ Stall(50) // Delay 50us.
+ If(LEqual(Local0,0)) // Count = 0?
+ {
+ KILL() // Yes. Kill Communication.
+ }
+ }
+ }
+
+ Return(0) // Timeout. Return Failure.
+}
+
+// SMBus Kill Command
+
+Method(KILL,0,Serialized)
+{
+ Or(HCON,0x02,HCON) // Yes. Send Kill command.
+ Or(HSTS,0xFF,HSTS) // Clear all status.
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl
new file mode 100644
index 0000000..634e088
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/PchXhci.asl
@@ -0,0 +1,1229 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* Copyright (c) 2010 - 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 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
+--*/
+
+ Method(_DEP){
+ If(LEqual(S0ID, 1)){
+ Return(Package() {\_SB.PEPD})
+ }Else{
+ Return(Package() {})
+ }
+ }
+
+ OperationRegion(XPRT,PCI_Config,0x00,0x100)
+ Field(XPRT,AnyAcc,NoLock,Preserve)
+ {
+ DVID, 16,
+ Offset(0x40),
+ , 11,
+ SWAI, 1, // 0x40 BIT[11]
+ , 20,
+ Offset(0x44),
+ , 12,
+ SAIP, 2, // 0x44 BIT[13:12]
+ , 18,
+ Offset(0x74),
+ D0D3, 2, // 0x74 BIT[1:0]
+ , 6,
+ PMEE, 1, // PME Enable
+ , 6,
+ PMES, 1, // PME Status
+ Offset(0xB0), // SSCFG Reg for LPTLP
+ , 13,
+ MB13, 1, // 0xB0 BIT[13]
+ MB14, 1, // 0xB0 BIT[14]
+ , 17,
+ Offset(0xD0),
+ PR2, 32, // XUSB2PR: xHC USB 2.0 Port Routing Register.
+ PR2M, 32, // XUSB2PRM: xHC USB 2.0 Port Routing Mask Register.
+ PR3, 32, // USB3_PSSEN: USB3.0 Port SuperSpeed Enable Register.
+ PR3M, 32 // USB3PRM: USB3.0 Port Routing Mask Register
+ }
+
+ OperationRegion(XHCP, SystemMemory, Add(PEBS, 0xA0000), 0x100)
+ Field(XHCP,AnyAcc,Lock,Preserve)
+ {
+ Offset(0x4),
+ PDBM, 16,
+ Offset(0x10),
+ MEMB, 64
+ }
+
+ //
+ // for each HS port, this method returns its corresponding selection bit in USB2PR register
+ //
+ Method(PR2S,1,Serialized) {
+
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // LPT-H
+ Switch(Arg0) {
+ Case( 1) {return (0x0001)}
+ Case( 2) {return (0x0002)}
+ Case( 3) {return (0x0004)}
+ Case( 4) {return (0x0008)}
+ Case( 5) {return (0x0100)}
+ Case( 6) {return (0x0200)}
+ Case( 7) {return (0x0400)}
+ Case( 8) {return (0x0800)}
+ Case( 9) {return (0x0010)}
+ Case(10) {return (0x0020)}
+ Case(11) {return (0x1000)}
+ Case(12) {return (0x2000)}
+ Case(13) {return (0x0040)}
+ Case(14) {return (0x0080)}
+ Case(15) {return (0x4000)}
+ }
+ } else { // LPT-LP
+ Switch(Arg0) {
+ Case( 1) {return (0x0001)}
+ Case( 2) {return (0x0002)}
+ Case( 3) {return (0x0004)}
+ Case( 4) {return (0x0008)}
+ Case( 5) {return (0x0010)}
+ Case( 6) {return (0x0020)}
+ Case( 7) {return (0x0040)}
+ Case( 8) {return (0x0080)}
+ Case( 9) {return (0x0100)}
+ }
+ }
+ }
+
+ Name(XRST, Zero)
+ //
+ // Workaround for XHCI
+ //
+ // At D3 exit (AKA PS_ON)
+ // For LPT-LP
+ // Clear PCI CFG offset 0xB0[14:13]
+ // Clear MMIO Offset 0x816C[14]
+ // Clear MMIO Offset 0x816C[2]
+ // For LPT-H, LPT-LP
+ // Set MMIO Offset 8154[31]
+ // For LPT-LP
+ // Wait until all SS ports are out of polling
+ // For each SS port which is disconnected (i.e. PORTS.PLS=5h) and CSC=0
+ // Issue Warm Port Reset
+ // Wait 101ms
+ // Write '1' to all Port Change Status bits if reset
+ // Set MMIO Offset 0x80E0[15]
+ // For LPT-H, LPT-LP
+ // Clear XHCI CFG REG 0x40[11]
+ // Clear XHCI CFG REG 0x44[13:12]
+ //
+ // Prior to D3 entry (AKA PS_OFF)
+ // For LPT-LP
+ // Set PCI CFG offset 0xB0[14:13]
+ // Set MMIO Offset 0x816C[14]
+ // Set MMIO Offset 0x816C[2]
+ // For LPT-H, LPT-LP
+ // Clear MMIO Offset 8154[31]
+ // For LPT-LP
+ // Clear MMIO Offset 0x80E0[15]
+ // For LPT-H, LPT-LP
+ // Set XHCI CFG REG 0x40[11]
+ // Set XHCI CFG REG 0x44[13:12] = '01'
+ //
+ External(\_SB.PCI0.XHC.PS0X, MethodObj)
+ External(\_SB.PCI0.XHC.PS3X, MethodObj)
+ //
+ // D0 Method for xHCI Host Controller
+ //
+ Method(_PS0,0,Serialized)
+ {
+ // Uses:
+ // Local0 - Temporary
+ // Local1 - Original command register
+ // Local2 - Original MBAR
+ // Local4 - Port reset mask
+ //
+ If(LEqual(^DVID,0xFFFF))
+ {
+ Return()
+ }
+
+ //
+ // MBAR Programming
+ //
+ Store(^MEMB,Local2) // Save MBAR
+ Store(^PDBM,Local1) // Save CMD
+ And(^PDBM,Not(0x06),^PDBM) // Clear MSE/BME
+
+ //
+ // Switch to D0
+ //
+ Store(^D0D3,Local3)
+ Store(0,^D0D3)
+
+ Store(\SRMB,^MEMB) // Set MBAR
+ Or(Local1,0x0002,^PDBM) // Set MSE
+
+ OperationRegion(MCA1,SystemMemory,\SRMB,0x9000)
+ Field(MCA1,DWordAcc,Lock,Preserve)
+ {
+ Offset(0x510),
+ PSC1, 32,
+ Offset(0x520),
+ PSC2, 32,
+ Offset(0x530),
+ PSC3, 32,
+ Offset(0x540),
+ PSC4, 32,
+ Offset(0x80E0), // AUX Reset Control 1
+ , 15,
+ AX15, 1,
+ Offset(0x8154), // AUX Domain PM control register 2
+ , 31,
+ CLK2, 1, // [31]
+ Offset(0x816C), // AUXCLKCTL
+ , 2,
+ CLK0, 1, // [2]
+ , 11,
+ CLK1, 1, // [14] - USB3 Port Aux/Core clock gating enable
+ }
+
+ If(LEqual(PCHS, 2)) // LPT-LP
+ {
+ //
+ // Clear PCI CFG offset 0xB0[14:13]
+ //
+ Store(0,^MB13)
+ Store(0,^MB14)
+ //
+ // Clear MMIO Offset 0x816C[14]
+ // Clear MMIO Offset 0x816C[2]
+ //
+ Store(0,CLK0)
+ Store(0,CLK1)
+ }
+
+ //
+ // Set MMIO Offset 8154[31] for both LPT-LP and LPT-H
+ //
+ Store(1,CLK2)
+
+ If(LEqual(PCHS, 2)) // LPT-LP
+ {
+ //
+ // Wait until all ports are out of polling (PP=1, PLS=7)
+ //
+ while(LOr(LOr(LEqual(And(PSC1,0x3F8),0x2E0),
+ LEqual(And(PSC2,0x3F8),0x2E0)),
+ LOr(LEqual(And(PSC3,0x3F8),0x2E0),
+ LEqual(And(PSC4,0x3F8),0x2E0))))
+ {
+ Stall(10)
+ }
+
+ //
+ // Bitmask of SS ports for which warm reset was performed
+ //
+ Store(0, Local4)
+
+ //
+ // For each SS port which is disconnected (i.e. PORTS.PLS=5h) and CSC=0
+ // Issue Warm Port Reset
+ //
+ And(PSC1,Not(0x02),Local0) // Mask PED
+ If(LEqual(And(Local0,0x203F9),0x2A0)) // If SS PSC1 PP=1, PLS=5, CSC=0
+ {
+ Or(Local0,0x80000000,PSC1) // Set WPR and clear change flags
+ Or(Local4,0x1,Local4)
+ }
+ And(PSC2,Not(0x02),Local0) // Mask PED
+ If(LEqual(And(Local0,0x203F9),0x2A0)) // If SS PSC2 PP=1, PLS=5, CSC=0
+ {
+ Or(Local0,0x80000000,PSC2) // Set WPR and clear change flags
+ Or(Local4,0x2,Local4)
+ }
+ And(PSC3,Not(0x02),Local0) // Mask PED
+ If(LEqual(And(Local0,0x203F9),0x2A0)) // If SS PSC3 PP=1, PLS=5, CSC=0
+ {
+ Or(Local0,0x80000000,PSC3) // Set WPR and clear change flags
+ Or(Local4,0x4,Local4)
+ }
+ And(PSC4,Not(0x02),Local0) // Mask PED
+ If(LEqual(And(Local0,0x203F9),0x2A0)) // If SS PSC4 PP=1, PLS=5, CSC=0
+ {
+ Or(Local0,0x80000000,PSC4) // Set WPR and clear change flags
+ Or(Local4,0x8,Local4)
+ }
+ //
+ // Wait 101ms
+ // Write '1' to all Port Change Status bits if reset
+ //
+ If (Local4)
+ {
+ Sleep(101)
+
+ If (And(Local4,0x1))
+ {
+ And(PSC1,Not(0x02),Local0) // Mask PED
+ Or(Local0, 0x00FE0000,PSC1) // Clear SS PSC1 Bit 23:17
+ }
+ If (And(Local4,0x2))
+ {
+ And(PSC2,Not(0x02),Local0) // Mask PED
+ Or(Local0,0x00FE0000,PSC2) // Clear SS PSC2 Bit 23:17
+ }
+ If (And(Local4,0x4))
+ {
+ And(PSC3,Not(0x02),Local0) // Mask PED
+ Or(Local0,0x00FE0000,PSC3) // Clear SS PSC3 Bit 23:17
+ }
+ If (And(Local4,0x8))
+ {
+ And(PSC4,Not(0x02),Local0) // Mask PED
+ Or(Local0,0x00FE0000,PSC4) // Clear SS PSC4 Bit 23:17
+ }
+ }
+
+ //
+ // Set MMIO Offset 0x80E0[15]
+ //
+ Store(1,AX15) //0x80E0 - BIT15, AUX Reset Control 1
+ }
+
+ //
+ // Clear PCI CFG offset 0x40[11] for both LPT-LP and LPT-H
+ //
+ Store(0,^SWAI)
+ //
+ // Clear PCI CFG offset 0x44[13:12] for both LPT-LP and LPT-H
+ //
+ Store(0,^SAIP)
+
+ //
+ // Call platform XHC PS0 method if present
+ //
+ If(CondRefOf(\_SB.PCI0.XHC.PS0X))
+ {
+ \_SB.PCI0.XHC.PS0X()
+ }
+
+ //
+ // Leave device in D0 to avoid spurious PME event upon D3 entry
+ //
+
+ //
+ // Restoring MBAR
+ //
+ And(^PDBM,Not(0x02),^PDBM) // Clear MSE
+ Store(Local2,^MEMB) // Restore MBAR
+ Store(Local1,^PDBM) // Restore CMD
+ }
+
+ //
+ // D3 Method for xHCI Host Controller
+ //
+ Method(_PS3,0,Serialized)
+ {
+ // Uses:
+ // Local0 - Temporary
+ // Local1 - Original command register
+ // Local2 - Original MBAR
+ // Local3 - D0D3 temporary
+ //
+ If(LEqual(^DVID,0xFFFF))
+ {
+ Return()
+ }
+ Store(1, ^PMES) //Clear PME status
+ Store(1, ^PMEE) //Enable PME
+
+
+ //
+ // MBAR Programming
+ //
+ Store(^MEMB,Local2) // Save MBAR
+ Store(^PDBM,Local1) // Save CMD
+ And(^PDBM,Not(0x06),^PDBM) // Clear MSE/BME
+ Store(\SRMB,^MEMB) // Set MBAR
+ Or(^PDBM,0x02,^PDBM) // Set MSE
+
+ OperationRegion(MCA1,SystemMemory,\SRMB,0x9000)
+ Field(MCA1,DWordAcc,Lock,Preserve)
+ {
+ Offset(0x80E0), // AUX Reset Control 1
+ , 15,
+ AX15, 1,
+ Offset(0x8154), // AUX Domain PM control register 2
+ , 31,
+ CLK2, 1, // BIT31
+ Offset(0x816C), // 40.2.3.6.6040.2.3.6.59 AUXCLKCTL
+ , 2,
+ CLK0, 1, // BIT2
+ , 11,
+ CLK1, 1, // BIT14 - USB3 Port Aux/Core clock gating enable
+ , 17,
+ }
+
+ //
+ // If device is in D3, set to back to D0
+ //
+ Store(^D0D3,Local3)
+ if(LEqual(Local3,3))
+ {
+ Store(0,^D0D3)
+ }
+
+ If(LEqual(PCHS, 2)) // LPT-LP
+ {
+ //
+ // Set PCI CFG offset 0xB0[14:13]
+ //
+ Store(1,^MB13)
+ Store(1,^MB14)
+ //
+ // Set MMIO Offset 0x816C[14]
+ // Set MMIO Offset 0x816C[2]
+ //
+ Store(1,CLK0)
+ Store(1,CLK1)
+ }
+
+ //
+ // Clear MMIO Offset 8154[31] for both LPT-LP and LPT-H
+ //
+ Store(0,CLK2)
+
+ If(LEqual(PCHS, 2)) // LPT-LP
+ {
+ //
+ // Clear MMIO Offset 0x80E0[15]
+ //
+ Store(0,AX15) //0x80E0 - BIT15
+ }
+
+ //
+ // Set PCI CFG offset 0x40[11] = '1' for both LPT-LP and LPT-H
+ //
+ Store(1,^SWAI)
+ //
+ // Set PCI CFG offset 0x44[13:12] = '01' for both LPT-LP and LPT-H
+ //
+ Store(1,^SAIP)
+
+ //
+ // Call platform XHC PS3 method if existed.
+ // in the PS3X, MBAR is ready, CMD is ready, and Device is in D0.
+ //
+ If(CondRefOf(\_SB.PCI0.XHC.PS3X))
+ {
+ \_SB.PCI0.XHC.PS3X()
+ }
+
+ //
+ // Restoring device back to D3
+ //
+ if(LEqual(Local3,3))
+ {
+ Store(3,^D0D3)
+ }
+ //
+ // Restoring MBAR
+ //
+ And(^PDBM,Not(0x02),^PDBM) // Clear MSE
+ Store(Local2,^MEMB) // Restore MBAR
+ Store(Local1,^PDBM) // Restore CMD
+ }
+
+ //
+ //
+ // Check for XHCI switch UUID
+ //
+ // Arguments:
+ // Arg0 (Buffer) : UUID
+ //
+ // Returns:
+ // 1: It's valid UUID
+ // 0: Invalid UUID
+ //
+ Method(CUID,1,Serialized) {
+ If(LEqual(Arg0,ToUUID("7c9512a9-1705-4cb4-af7d-506a2423ab71"))) {
+ Return(1)
+ }
+ Return(0)
+ }
+
+ //
+ // _OSC for xHCI
+ // This method enables XHCI controller if available.
+ //
+ // Arguments:
+ // Arg0 (Integer): Revision ID - should be set to 1
+ // Arg1 (Integer): Count
+ // Arg2 (Buffer) : Capabilities Buffer
+ // DWORD#1 (Status/Error):
+ // Bit 0 - Query Support Flag
+ // Bit 1 - Always clear(0)
+ // Bit 2 - Always clear(0)
+ // Bit 3 - Always clear(0)
+ // All others - reserved (return 0)
+ //
+ // DWORD#3 (Controlled):
+ // Bit 0 - If set OS request routing back to EHCI
+ // All others - reserved (return 0)
+ // Returns:
+ // Capabilities Buffer:
+ // DWORD#1 (Status):
+ // Bit 0 - Reserved (not used)
+ // Bit 1 - _OSC failure. Platform Firmware was unable to process the request or query.
+ // Capabilities bits may have been masked.
+ // Bit 2 - Unrecognized UUID. This bit is set to indicate that the platform firmware does not
+ // recognize the UUID passed in _OSC Arg0.
+ // Capabilities bits are preserved.
+ // Bit 3 - Unrecognized Revision. This bit is set to indicate that the platform firmware does not
+ // recognize the Revision ID passed in via Arg1.
+ // Capabilities bits beyond those comprehended by the firmware will be masked.
+ // Bit 4 - Capabilities Masked. This bit is set to indicate
+ // that capabilities bits set by driver software
+ // have been cleared by platform firmware.
+ // All others - reserved (return 0)
+ //
+ Method(POSC,3,Serialized) {
+ //
+ // Create DWord field from the Capabilities Buffer
+ //
+ CreateDWordField(Arg2,0,CDW1)
+ CreateDWordField(Arg2,8,CDW3)
+
+ //
+ // Set failure if xHCI is disabled by BIOS
+ //
+ If (LEqual(XHCI, 0)) {
+ Or(CDW1,0x2,CDW1)
+ }
+
+ //
+ // Query flag clear
+ //
+ If(LNot(And(CDW1,0x1))) {
+ If (And(CDW3,0x1)) {
+ //
+ // Perform switch back to EHCI
+ //
+ ESEL()
+ }
+ Else {
+ If (LEqual(And(CDID,0xF000), 0x8000)) { // if LPT-H chipset
+ If (LGreater(Arg0, 0x1)) {
+ //
+ // Perform switch to xHCI
+ //
+ XSEL()
+ } Else {
+ //
+ // Set failure if revision is not supported
+ //
+ Or(CDW1,0xA,CDW1)
+ }
+ } Else { // if LPT-LP chipset
+ If (LGreater(Arg0, 0x2)) {
+ //
+ // Perform switch to xHCI
+ //
+ XSEL()
+ } Else {
+ //
+ // Set failure if revision is not supported
+ //
+ Or(CDW1,0xA,CDW1)
+ }
+ }
+ }
+ }
+
+ Return(Arg2)
+ }
+
+ Method(XSEL, 0, Serialized)
+ {
+ //
+ // xHCI in auto or smart auto mode
+ //
+ If (LOr(LEqual(XHCI,2), LEqual(XHCI,3))) {
+ //
+ // Set B0:D31:F0 ACh[16] to indicate begin of Driver phase of USB port routing
+ //
+ Store(1, XUSB)
+ Store(1, XRST) // Backup XUSB, cause it might lost in iRST G3 or DeepSx
+ //
+ // Enable selected SS ports, route corresponding HS ports to xHCI
+ //
+ Store(0, Local0)
+ And(PR3, 0xFFFFFFC0, Local0)
+ Or(Local0, PR3M, PR3)
+ Store(0, Local0)
+ And(PR2, 0xFFFF8000, Local0)
+ Or(Local0, PR2M, PR2)
+ }
+ }
+
+ Method(ESEL, 0, Serialized)
+ {
+ //
+ // xHCI in auto or smart auto mode
+ //
+ If (LOr(LEqual(XHCI,2), LEqual(XHCI,3))) {
+ //
+ // Disable all SS ports, route all HS ports to EHCI
+ //
+ And(PR3, 0xFFFFFFC0, PR3)
+ And(PR2, 0xFFFF8000, PR2)
+
+ //
+ // Mark as not routed.
+ //
+ Store(0, XUSB)
+ Store(0, XRST)
+ }
+ }
+
+ Method(XWAK, 0, Serialized)
+ {
+ //
+ // Ports were routed to xHCI before sleep
+ //
+ If (LOr(LEqual(XUSB,1), LEqual(XRST,1))) {
+ //
+ // Restore back to xHCI
+ //
+ XSEL()
+ }
+ }
+
+ Method(_S3D, 0, NotSerialized)
+ {
+ Return(0x02)
+ }
+
+ Method(_S4D, 0, NotSerialized)
+ {
+ Return(0x02)
+ }
+
+ Device(RHUB)
+ {
+ Name(_ADR, Zero)
+
+ //
+ // High Speed Ports
+ //
+ Device(HS01)
+ {
+ Name(_ADR, 0x01)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS01_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+
+ If(LNot(And(PR2S(1), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS01_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(1), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS02)
+ {
+ Name(_ADR, 0x02)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS02_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(2), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS02_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(2), PR2))) {
+ And(VIS,0,VIS)
+ }
+
+ Return (PLDP)
+ }
+ }
+
+ Device(HS03)
+ {
+ Name(_ADR, 0x03)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS03_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(3), PR2))) {
+ Store(0x00,Index(UPCP,0x00))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10) { ASL_HS03_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(3), PR2))) {
+ And(VIS,0,VIS)
+ }
+#if defined ASL_HS03_INTERNAL && ASL_HS03_INTERNAL == 1 //AMI_OVERRITE
+ If(LEqual(And(CDID,0xF000), 0x9000)) { // on LPT-LP platforms this port is internal
+ And(VIS,0,VIS)
+ }
+#endif //AMI_OVERRITE
+ Return (PLDP)
+ }
+ }
+
+ Device(HS04)
+ {
+ Name(_ADR, 0x04)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS04_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(4), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS04_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(4), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS05)
+ {
+ Name(_ADR, 0x05)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS05_UPC }) // Change Type from "USB 3 Standard-A connector" to "Type 'A' connector". //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(5), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS05_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(5), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS06)
+ {
+ Name(_ADR, 0x06)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS06_UPC }) // Change Type from "USB 3 Standard-A connector" to "Type 'A' connector". //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(6), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS06_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(6), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS07)
+ {
+ Name(_ADR, 0x07)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS07_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(7), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS07_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(7), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS08)
+ {
+ Name(_ADR, 0x08)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS08_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(8), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS08_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(8), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS09)
+ {
+ Name(_ADR, 0x09)
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS09_UPC }) // HS09 is routed to a USB3 A Connector //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(9), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS09_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(9), PR2))) {
+ And(VIS,0,VIS)
+ }
+ If(LEqual(And(CDID,0xF000), 0x9000)) {
+ And(VIS,0,VIS) // invisible because on LPT-LP HS09 is KVM's USBR port
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS10)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xA)
+ } Else {
+ Return (0xFA) // on LPT-LP, 0xA is assigned to SSP so move this port's address away
+ }
+ }
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) // this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS10_UPC }) // HS10 is routed to a USB3 A Connector //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(10), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS10_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(10), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS11)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xB)
+ } Else {
+ Return (0xFB) // on LPT-LP, 0xB is assigned to SSP so move this port's address away
+ }
+ }
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS11_UPC }) // Proprietary connector (internal header) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(11), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS11_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(11), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS12)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xC)
+ } Else {
+ Return (0xFC) // on LPT-LP, 0xC is assigned to SSP so move this port's address away
+ }
+ }
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS12_UPC }) // Proprietary connector (internal header) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(12), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS12_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(12), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS13)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xD)
+ } Else {
+ Return (0xFD) // on LPT-LP, 0xD is assigned to SSP so move this port's address away
+ }
+ }
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS13_UPC }) // Proprietary connector (internal header) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(13), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS13_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(13), PR2))) {
+ And(VIS,0,VIS)
+ }
+
+ Return (PLDP)
+ }
+
+ }
+
+ Device(HS14)
+ {
+ Name(_ADR, 0xE)
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS14_UPC }) // Proprietary connector (internal header) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(14), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS14_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(14), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(HS15)
+ {
+ Name(_ADR, 0xF)
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_HS15_UPC }) // Not connectable, USBR not enabled in H87 //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR2S(15), PR2))) {
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_HS15_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR2S(15), PR2))) {
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ //
+ // Super Speed Ports - must match _UPC declarations of the coresponding Full Speed Ports.
+ //
+ Device(SSP1)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0x10)
+ } Else {
+ Return (0xA)
+ }
+ }
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP1_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP1_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP1_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP1_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(SSP2)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0x11)
+ } Else {
+ Return (0xB)
+ }
+ }
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP2_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP2_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP2_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP2_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(SSP3)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0x12)
+ } Else {
+ Return (0xC)
+ }
+ }
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP3_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP3_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP3_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP3_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(SSP4)
+ {
+ Method(_ADR, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0x13)
+ } Else {
+ Return (0xD)
+ }
+ }
+ Name(_STA, 0xF)
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP4_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP4_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP4_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP4_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(SSP5)
+ {
+ Name(_ADR, 0x14)
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP5_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP5_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP5_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP5_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+
+ Device(SSP6)
+ {
+ Name(_ADR, 0x15)
+ Method(_STA, 0, Serialized) {
+ If(LEqual(And(CDID,0xF000), 0x8000)) { // check for LPT-H chipset
+ Return (0xF)
+ } Else {
+ Return (0) //this port doesn't exist on LPT-LP
+ }
+ }
+ Method(_UPC,0,Serialized) {
+ Name(UPCP, Package() { ASL_SSP6_UPC }) //AMI_OVERRITE, Set token for OEM easy to modify.
+ If(LNot(And(PR3, ASL_SSP6_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ Store(0x00,Index(UPCP,0))
+ }
+ Return(UPCP)
+ }
+ Method(_PLD,0,Serialized) {
+ Name(PLDP, Package() {
+ Buffer(0x10){ ASL_SSP6_PLD } //AMI_OVERRITE, Set token for OEM easy to modify.
+ })
+ CreateBitField(DeRefOf(Index(PLDP,0)),64,VIS)
+ If(LNot(And(PR3, ASL_SSP6_PR3))) { //AMI_OVERRITE, Set token for OEM easy to modify.
+ And(VIS,0,VIS)
+ }
+ Return (PLDP)
+ }
+ }
+ }
+
diff --git a/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl
new file mode 100644
index 0000000..12bcbbf
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/AcpiTables/Dsdt/UsbSbd.asl
@@ -0,0 +1,92 @@
+/************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the Haswell *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* MPG-MSAE *;
+;* *;
+;* Copyright (c) 1999-2011 Intel Corporation. *;
+;* *;
+;* This program has been developed by Intel Corporation. *;
+;* Licensee has Intel's permission to incorporate this source code *;
+;* into their product, royalty free. This source code may NOT be *;
+;* redistributed to anyone without Intel's written permission. *;
+;* *;
+;* Intel specifically disclaims all warranties, express or *;
+;* implied, and all liability, including consequential and other *;
+;* indirect damages, for the use of this code, including liability *;
+;* for infringement of any proprietary rights, and including the *;
+;* warranties of merchantability and fitness for a particular *;
+;* purpose. Intel does not assume any responsibility for any *;
+;* errors which may appear in this code nor any responsibility to *;
+;* update it. *;
+;* *;
+;* Version: See README.TXT *;
+;* *;
+;************************************************************************/
+/*++
+ This file contains an 'Intel Peripheral Driver' 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
+--*/
+
+//
+// _DSM : Device Specific Method supporting USB Sideband Deferring function
+//
+// Arg0: UUID Unique function identifier
+// Arg1: Integer Revision Level
+// Arg2: Integer Function Index
+// Arg3: Package Parameters
+//
+Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
+{
+
+ If (LEqual(Arg0, ToUUID ("A5FC708F-8775-4BA6-BD0C-BA90A1EC72F8")))
+ {
+ //
+ // Switch by function index
+ //
+ Switch (ToInteger(Arg2))
+ {
+ //
+ // Standard query - A bitmask of functions supported
+ // Supports function 0-2
+ //
+ Case (0)
+ {
+ if (LEqual(Arg1, 1)){ // test Arg1 for the revision
+ Return (Buffer () {0x07})
+ } else {
+ Return (Buffer () {0})
+ }
+ }
+ //
+ // USB Sideband Deferring Support
+ // 0: USB Sideband Deferring not supported on this device
+ // 1: USB Sideband Deferring supported
+ //
+ Case (1)
+ {
+ if (LEqual(SDGV,0xFF)){ // check for valid GPE vector
+ Return (0)
+ } else {
+ Return (1)
+ }
+ }
+ //
+ // GPE Vector
+ // Return the bit offset within the GPE block of the GPIO (HOST_ALERT) driven by this device
+ //
+ Case (2)
+ {
+ Return (SDGV)
+ }
+ }
+ }
+
+ Return (0)
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c
new file mode 100644
index 0000000..700d6b4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.c
@@ -0,0 +1,292 @@
+/** @file
+ Source file for the ActiveBios ActiveBios protocol implementation
+
+@copyright
+ Copyright (c) 2005 - 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 "ActiveBios.h"
+
+//
+// Prototypes for our ActiveBios protocol functions
+//
+static
+EFI_STATUS
+EFIAPI
+SetState (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This,
+ IN EFI_ACTIVE_BIOS_STATE DesiredState,
+ IN UINTN Key
+ );
+
+static
+EFI_STATUS
+EFIAPI
+LockState (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This,
+ IN BOOLEAN Lock,
+ IN OUT UINTN *Key
+ );
+
+//
+// Function implementations
+//
+
+/**
+ Change the current active BIOS settings to the requested state.
+ The caller is responsible for requesting a supported state from
+ the EFI_ACTIVE_BIOS_STATE selections.
+ This will fail if someone has locked the interface and the correct key is
+ not provided.
+
+ @param[in] This Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+ @param[in] DesiredState The requested state to configure the system for.
+ @param[in] Key If the interface is locked, Key must be the Key
+ returned from the LockState function call.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_ACCESS_DENIED The interface is currently locked.
+**/
+static
+EFI_STATUS
+EFIAPI
+SetState (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This,
+ IN EFI_ACTIVE_BIOS_STATE DesiredState,
+ IN UINTN Key
+ )
+{
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+ ///
+ /// Verify requested state is allowed
+ ///
+ ASSERT (DesiredState < ActiveBiosStateMax);
+
+ ///
+ /// Check if the interface is locked by another
+ ///
+ if (mPrivateData.Locked && Key != mPrivateData.CurrentKey) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if ((MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_GCS) & B_PCH_RCRB_GCS_BILD) == B_PCH_RCRB_GCS_BILD) {
+ return EFI_ACCESS_DENIED;
+ }
+ ///
+ /// Set the requested state
+ ///
+ switch (DesiredState) {
+
+ case ActiveBiosStateSpi:
+ if (PchSeries == PchH) {
+ MmioAndThenOr16 (
+ (UINTN) (mPchRootComplexBar + R_PCH_RCRB_GCS),
+ (UINT16) (~B_PCH_H_RCRB_GCS_BBS),
+ (UINT16) (V_PCH_H_RCRB_GCS_BBS_SPI)
+ );
+ }
+ if (PchSeries == PchLp) {
+ MmioAndThenOr16 (
+ (UINTN) (mPchRootComplexBar + R_PCH_RCRB_GCS),
+ (UINT16) (~B_PCH_LP_RCRB_GCS_BBS),
+ (UINT16) (V_PCH_LP_RCRB_GCS_BBS_SPI)
+ );
+ }
+ break;
+
+ case ActiveBiosStateLpc:
+ if (PchSeries == PchH) {
+ MmioAndThenOr16 (
+ (UINTN) (mPchRootComplexBar + R_PCH_RCRB_GCS),
+ (UINT16) (~B_PCH_H_RCRB_GCS_BBS),
+ (UINT16) (V_PCH_H_RCRB_GCS_BBS_LPC)
+ );
+ }
+ if (PchSeries == PchLp) {
+ MmioAndThenOr16 (
+ (UINTN) (mPchRootComplexBar + R_PCH_RCRB_GCS),
+ (UINT16) (~B_PCH_LP_RCRB_GCS_BBS),
+ (UINT16) (V_PCH_LP_RCRB_GCS_BBS_LPC)
+ );
+ }
+ break;
+
+ default:
+ ///
+ /// This is an invalid use of the protocol
+ /// See definition, but caller must call with valid value
+ ///
+ ASSERT (!EFI_UNSUPPORTED);
+ break;
+ }
+ ///
+ /// Read state back
+ /// This ensures the chipset MMIO was flushed and updates the protocol state
+ ///
+ MmioRead16 (mPchRootComplexBar + R_PCH_RCRB_GCS);
+
+ ///
+ /// Record current state
+ ///
+ mPrivateData.ActiveBiosProtocol.State = DesiredState;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Lock or unlock the current active BIOS state.
+ Key is a simple incrementing number.
+
+ @param[in] This Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+ @param[in] Lock TRUE to lock the current state, FALSE to unlock.
+ @param[in, out] Key If Lock is TRUE, then a key will be returned. If
+ Lock is FALSE, the key returned from the prior call
+ to lock the protocol must be provided to unlock the
+ protocol. The value of Key is undefined except that
+ it cannot be 0.
+
+ @retval EFI_SUCCESS Command succeed.
+ @exception EFI_UNSUPPORTED The function is not supported.
+ @retval EFI_ACCESS_DENIED The interface is currently locked.
+**/
+static
+EFI_STATUS
+EFIAPI
+LockState (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This,
+ IN BOOLEAN Lock,
+ IN OUT UINTN *Key
+ )
+{
+ ///
+ /// Check if lock or unlock requesed
+ ///
+ if (Lock) {
+ ///
+ /// Check if already locked
+ ///
+ if (mPrivateData.Locked) {
+ return EFI_ACCESS_DENIED;
+ }
+ ///
+ /// Lock the interface
+ ///
+ mPrivateData.Locked = TRUE;
+
+ ///
+ /// Increment the key
+ ///
+ mPrivateData.CurrentKey++;
+
+ ///
+ /// Update the caller's copy
+ ///
+ *Key = mPrivateData.CurrentKey;
+ } else {
+ ///
+ /// Verify caller "owns" the current lock
+ ///
+ if (*Key == mPrivateData.CurrentKey) {
+ mPrivateData.Locked = FALSE;
+ } else {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialization function for the ActiveBios protocol implementation.
+
+ @param[in] This Pointer to the protocol
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ActiveBiosProtocolConstructor (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_GUID EfiActiveBiosProtocolGuid = EFI_ACTIVE_BIOS_PROTOCOL_GUID;
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Read current state from the PCH
+ ///
+ if (PchSeries == PchH) {
+ switch (MmioRead16 (mPchRootComplexBar + R_PCH_RCRB_GCS) & B_PCH_H_RCRB_GCS_BBS) {
+
+ case V_PCH_H_RCRB_GCS_BBS_SPI:
+ mPrivateData.ActiveBiosProtocol.State = ActiveBiosStateSpi;
+ break;
+
+ case V_PCH_H_RCRB_GCS_BBS_LPC:
+ mPrivateData.ActiveBiosProtocol.State = ActiveBiosStateLpc;
+ break;
+
+ default:
+ ///
+ /// This is an invalid use of the protocol
+ /// See definition, but caller must call with valid value
+ ///
+ ASSERT (!EFI_UNSUPPORTED);
+ break;
+ }
+ }
+
+ if (PchSeries == PchLp) {
+ switch (MmioRead16 (mPchRootComplexBar + R_PCH_RCRB_GCS) & B_PCH_LP_RCRB_GCS_BBS) {
+
+ case V_PCH_LP_RCRB_GCS_BBS_SPI:
+ mPrivateData.ActiveBiosProtocol.State = ActiveBiosStateSpi;
+ break;
+
+ case V_PCH_LP_RCRB_GCS_BBS_LPC:
+ mPrivateData.ActiveBiosProtocol.State = ActiveBiosStateLpc;
+ break;
+
+ default:
+ ///
+ /// This is an invalid use of the protocol
+ /// See definition, but caller must call with valid value
+ ///
+ ASSERT (!EFI_UNSUPPORTED);
+ break;
+ }
+ }
+ mPrivateData.ActiveBiosProtocol.SetState = SetState;
+ mPrivateData.ActiveBiosProtocol.LockState = LockState;
+ mPrivateData.CurrentKey = 1;
+ mPrivateData.Locked = FALSE;
+
+ ///
+ /// Install the protocol
+ ///
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &EfiActiveBiosProtocolGuid,
+ &mPrivateData.ActiveBiosProtocol,
+ NULL
+ );
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.cif b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.cif
new file mode 100644
index 0000000..92ebf07
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "ActiveBios"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\ActiveBios\Dxe"
+ RefName = "ActiveBios"
+[files]
+"ActiveBios.sdl"
+"ActiveBios.mak"
+"ActiveBiosMain.c"
+"ActiveBios.c"
+"ActiveBios.h"
+"ActiveBiosDepex.dxs"
+"ActiveBios.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h
new file mode 100644
index 0000000..49efbff
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.h
@@ -0,0 +1,104 @@
+/** @file
+ Defines and prototypes for the ActiveBios driver.
+ This driver implements the ActiveBios protocol for the PCH.
+ It provides a simple implementation that allows for basic control
+ of the PCH flash mapping state.
+
+@copyright
+ Copyright (c) 2005 - 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 _ACTIVE_BIOS_H_
+#define _ACTIVE_BIOS_H_
+
+//
+// Include files
+//
+//
+// 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 EFI_PROTOCOL_PRODUCER (ActiveBios)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+//
+// Active BIOS private data
+//
+#define ACTIVE_BIOS_SIGNATURE EFI_SIGNATURE_32 ('D', 'P', 'B', 'A')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_ACTIVE_BIOS_PROTOCOL ActiveBiosProtocol;
+ UINTN CurrentKey;
+ BOOLEAN Locked;
+} ACTIVE_BIOS_INSTANCE;
+
+#define ACTIVE_BIOS_INSTANCE_FROM_ACTIVE_BIOS_THIS(a) \
+ CR ( \
+ a, \
+ ACTIVE_BIOS_INSTANCE, \
+ ActiveBiosProtocol, \
+ ACTIVE_BIOS_SIGNATURE \
+ )
+
+//
+// Driver global data
+//
+extern ACTIVE_BIOS_INSTANCE mPrivateData;
+extern UINT32 mPchRootComplexBar;
+
+//
+// Protocol constructor
+//
+
+/**
+ Initialization function for the ActiveBios protocol implementation.
+
+ @param[in] This Pointer to the protocol
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+ActiveBiosProtocolConstructor (
+ IN EFI_ACTIVE_BIOS_PROTOCOL *This
+ );
+
+//
+// Driver entry point
+//
+
+/**
+ ActiveBios driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Application completed successfully
+ @exception EFI_UNSUPPORTED Unsupported chipset detected
+**/
+EFI_STATUS
+InstallActiveBios (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.inf b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.inf
new file mode 100644
index 0000000..c8cc9f7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.inf
@@ -0,0 +1,77 @@
+## @file
+# Component description file for the ActiveBios BS_DRIVER
+#
+#@copyright
+# Copyright (c) 2005 - 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 = ActiveBios
+FILE_GUID = BFD59D42-FE0F-4251-B772-4B098A1AEC85
+COMPONENT_TYPE = BS_DRIVER
+
+[Sources.Common]
+ ActiveBios.c
+ ActiveBiosMain.c
+ ActiveBios.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[Libraries.Common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[Includes.Common]
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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
+
+[Nmake.Common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = ActiveBiosDepex.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallActiveBios
+ 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_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.mak b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.mak
new file mode 100644
index 0000000..9bc4a73
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.mak
@@ -0,0 +1,96 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/ActiveBios/ActiveBios.mak 2 2/24/12 2:09a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:09a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/ActiveBios/ActiveBios.mak $
+#
+# 2 2/24/12 2:09a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:40a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# CreateActiveBios Driver
+#---------------------------------------------------------------------------
+EDK : ActiveBios
+ActiveBios : $(BUILD_DIR)\ActiveBios.mak ActiveBiosBin
+
+
+$(BUILD_DIR)\ActiveBios.mak : $(ActiveBios_DIR)\$(@B).cif $(ActiveBios_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(ActiveBios_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+ActiveBios_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+ActiveBios_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallActiveBios"\
+ /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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+ActiveBios_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+ActiveBiosBin: $(ActiveBios_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\ActiveBios.mak all \
+ "MY_INCLUDES=$(ActiveBios_INCLUDES)" \
+ "MY_DEFINES=$(ActiveBios_DEFINES)" \
+ GUID=BFD59D42-FE0F-4251-B772-4B098A1AEC85\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER \
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(ActiveBios_DIR)\ActiveBiosDepex.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/ActiveBios/Dxe/ActiveBios.sdl b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.sdl
new file mode 100644
index 0000000..c53e064
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBios.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/ActiveBios/ActiveBios.sdl 1 2/08/12 8:40a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:40a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/ActiveBios/ActiveBios.sdl $
+#
+# 1 2/08/12 8:40a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "ActiveBios_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable ActiveBios support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+MODULE
+ File = "ActiveBios.mak"
+ Help = "Includes ActiveBios to Project"
+End
+
+PATH
+ Name = "ActiveBios_DIR"
+ Help = "ActiveBios file source directory"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\ActiveBios.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/ActiveBios/Dxe/ActiveBiosDepex.dxs b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosDepex.dxs
new file mode 100644
index 0000000..d7180b7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosDepex.dxs
@@ -0,0 +1,39 @@
+/** @file
+ Dispatch dependency expression file for the ActiveBios driver.
+
+@copyright
+ Copyright (c) 2005 - 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"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+
diff --git a/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c
new file mode 100644
index 0000000..7fd6a45
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/ActiveBios/Dxe/ActiveBiosMain.c
@@ -0,0 +1,73 @@
+/** @file
+ Main implementation source file for the ActiveBios driver
+
+@copyright
+ Copyright (c) 2005 - 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 "ActiveBios.h"
+
+//
+// Global data
+//
+ACTIVE_BIOS_INSTANCE mPrivateData;
+UINT32 mPchRootComplexBar;
+
+/**
+ ActiveBios driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Application completed successfully
+ @exception EFI_UNSUPPORTED Unsupported chipset detected
+**/
+EFI_STATUS
+InstallActiveBios (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ Status = EFI_SUCCESS;
+ Handle = NULL;
+
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "Active BIOS Protocol not supported due to no proper PCH LPC found!\n"));
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// PCH RCBA must be initialized prior to run this driver.
+ ///
+ mPchRootComplexBar = PCH_RCRB_BASE;
+ ASSERT (mPchRootComplexBar != 0);
+
+ ///
+ /// Initialize private data
+ ///
+ mPrivateData.Signature = ACTIVE_BIOS_SIGNATURE;
+ mPrivateData.Handle = ImageHandle;
+
+ ///
+ /// Initialize our ActiveBios protocol
+ ///
+ Status = ActiveBiosProtocolConstructor (&mPrivateData.ActiveBiosProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c b/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c
new file mode 100644
index 0000000..40bc926
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.c
@@ -0,0 +1,28 @@
+/** @file
+ The GUID definition for ChipsetInitHob
+
+@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 "Tiano.h"
+#include "ChipsetInitHob.h"
+
+EFI_GUID gChipsetInitHobGuid = CHIPSET_INIT_INFO_HOB_GUID;
+
+EFI_GUID_STRING(&gChipsetInitHobGuid, "ChipsetInit HOB", "GUID for ChipsetInit HOB");
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h b/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h
new file mode 100644
index 0000000..df9548c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/ChipsetInitHob/ChipsetInitHob.h
@@ -0,0 +1,62 @@
+/*++ @file
+ Contains data used to determine if BIOS/ME/PMC are in sync
+ with the required platform ChipsetInit settings.
+
+@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
+--*/
+
+#ifndef _CHIPSET_INIT_INFO_HOBS_H__
+#define _CHIPSET_INIT_INFO_HOBS_H__
+
+#define CHIPSET_INIT_INFO_HOB_GUID \
+ { \
+ 0xc1392859, 0x1f65, 0x446e,0xb3, 0xf5, 0x84, 0x35, 0xfc, 0xc7, 0xd1, 0xc4 \
+ }
+
+extern EFI_GUID gChipsetInitInfoHobGuid;
+
+#pragma pack(push, 1)
+
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+#ifndef __PI_HOB_H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+ UINT16 HobType;
+ UINT16 HobLength;
+ UINT32 Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+ //
+ // Guid specific data goes here
+ //
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+#endif
+
+typedef struct _CHIPSET_INIT_INFO_HOB {
+ EFI_HOB_GUID_TYPE Header;
+ UINT32 ChipsetInitTableLen; // Size of the ChipsetInit table in bytes
+ UINT8 ChipsetInitTableUpdReq;
+ UINT8 ChipsetInitTable[384];
+} CHIPSET_INIT_INFO_HOB;
+
+#pragma pack(pop)
+#endif
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.cif b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.cif
new file mode 100644
index 0000000..c9678d7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchGuidLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Guid\"
+ RefName = "PchGuidLib"
+[files]
+"PchGuidLib.sdl"
+"PchGuidLib.mak"
+"PchGuidLib.inf"
+"ChipsetInitHob\ChipsetInitHob.c"
+"ChipsetInitHob\ChipsetInitHob.h"
+"S3SupportHob\S3SupportHob.c"
+"S3SupportHob\S3SupportHob.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.inf b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.inf
new file mode 100644
index 0000000..fe31ee1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.inf
@@ -0,0 +1,48 @@
+## @file
+# Component description file for PchGuidLib
+#
+#@copyright
+# Copyright (c) 2012 - 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 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 = PchGuidLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ChipsetInitHob/ChipsetInitHob.c
+ ChipsetInitHob/ChipsetInitHob.h
+ S3SupportHob/S3SupportHob.c
+ S3SupportHob/S3SupportHob.h
+
+[includes.common]
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+
+#
+# EDK II Glue Library utilizes some standard headers from EDK
+#
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[nmake.common]
+C_STD_INCLUDE=
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.mak b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.mak
new file mode 100644
index 0000000..df5e8f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.mak
@@ -0,0 +1,21 @@
+# MAK file for the ModulePart:PchGuidLib
+all : PchGuidLib
+
+$(PchGuidLib_LIB) : PchGuidLib
+
+PchGuidLib : $(BUILD_DIR)\PchGuidLib.mak PchGuidLibBin
+
+$(BUILD_DIR)\PchGuidLib.mak : $(PchGuidLib_DIR)\$(@B).cif $(PchGuidLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchGuidLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchGuidLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS)\
+ /f $(BUILD_DIR)\PchGuidLib.mak all\
+ "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES)" \
+ TYPE=LIBRARY
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\PchGuidLib.mak all\
+ "MY_INCLUDES=$(EDK_INCLUDES) $(EdkIIGlueLib_INCLUDES)" \
+ TYPE=PEI_LIBRARY
+!ENDIF
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.sdl b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.sdl
new file mode 100644
index 0000000..f9a5886
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/PchGuidLib.sdl
@@ -0,0 +1,43 @@
+TOKEN
+ Name = "PchGuidLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchGuidLib support in Project"
+End
+
+MODULE
+ Help = "Includes PchGuidLib.mak to Project"
+ File = "PchGuidLib.mak"
+End
+
+PATH
+ Name = "PchGuidLib_DIR"
+End
+
+ELINK
+ Name = "/I$(PchGuidLib_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchGuidLib_DIR)\ChipsetInitHob"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchGuidLib_DIR)\S3SupportHob"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "PchGuidLib_LIB"
+ Value = "$$(LIB_BUILD_DIR)\PchGuidLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.c b/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.c
new file mode 100644
index 0000000..b722fb1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.c
@@ -0,0 +1,30 @@
+/** @file
+ The GUID definition for ChipsetInitHob
+
+@copyright
+ Copyright (c) 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 <Tiano.h>
+#include "S3SupportHob.h"
+
+EFI_GUID gS3SupportHobGuid = S3_SUPPORT_HOB_GUID;
+EFI_GUID gS3DataHobGuid = S3_DATA_HOB_GUID;
+
+EFI_GUID_STRING(&gS3SupportHobGuid, "S3 Support HOB", "GUID for S3 Support HOB");
+EFI_GUID_STRING(&gS3DataHobGuid, "S3 Data HOB", "GUID for S3 Data HOB")
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.h b/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.h
new file mode 100644
index 0000000..8892e02
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Guid/S3SupportHob/S3SupportHob.h
@@ -0,0 +1,73 @@
+/*++ @file
+ Contains data used to determine if BIOS/ME/PMC are in sync
+ with the required platform ChipsetInit settings.
+
+@copyright
+ Copyright (c) 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
+--*/
+
+#ifndef _S3_SUPPORT_HOBS_H__
+#define _S3_SUPPORT_HOBS_H__
+
+#define S3_SUPPORT_HOB_GUID \
+ { \
+ 0xd33ca878, 0xde8f, 0x47d0, 0x9e, 0x47, 0x4d, 0x81, 0xb1, 0xa0, 0x9e, 0x88 \
+ }
+
+#define S3_DATA_HOB_GUID \
+ { \
+ 0x806e1de3, 0xc6c1, 0x495c, 0x85, 0xf4, 0x1b, 0xda, 0xbf, 0x93, 0x0, 0x5d \
+ }
+
+extern EFI_GUID gS3SupportHobGuid;
+extern EFI_GUID gS3DataHobGuid;
+
+#pragma pack(push, 1)
+
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+#ifndef __PI_HOB_H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+ UINT16 HobType;
+ UINT16 HobLength;
+ UINT32 Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+ //
+ // Guid specific data goes here
+ //
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+#endif
+
+typedef struct _S3_SUPPORT_HOB {
+ EFI_HOB_GUID_TYPE Header;
+ UINT32 PchS3PeimEntryPoint; // Entry Point of the PCH S3 PEIM module
+} S3_SUPPORT_HOB;
+
+typedef struct _S3_DATA_HOB {
+ EFI_HOB_GUID_TYPE Header;
+ VOID *S3DispatchDataArray; // Pointer to the EFI_PCH_S3_DISPATCH_ARRAY to be passed to DXE
+} S3_DATA_HOB;
+
+#pragma pack(pop)
+#endif
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxe.dsc b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxe.dsc
new file mode 100644
index 0000000..a7b1da9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxe.dsc
@@ -0,0 +1,58 @@
+## @file
+# Build description file for building the PCH DXE drivers
+#
+#@copyright
+# Copyright (c) 2008 - 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 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
+#
+
+#
+# DXE drivers produce PCH protocols
+#
+$(PROJECT_PCH_ROOT)\ActiveBios\Dxe\ActiveBios.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Spi\RuntimeDxe\PchSpiRuntime.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Spi\Smm\PchSpiSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\SerialGpio\Dxe\PchSerialGpio.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\SmartTimer\Dxe\SmartTimer.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\SmmControl\RuntimeDxe\SmmControl.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Smbus\Dxe\PchSmbusDxe.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Smbus\Smm\PchSmbusSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\LegacyInterrupt\Dxe\LegacyInterrupt.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Reset\RuntimeDxe\PchResetRuntime.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Wdt\Dxe\WdtDxe.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+#
+# DXE drivers use PCH protocols to initialize PCH
+#
+$(PROJECT_PCH_ROOT)\PchInit\Dxe\PchInitDxe.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+#
+# SMM drivers
+#
+$(PROJECT_PCH_ROOT)\Pcie\Smm\PchPcieSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\PchInit\Smm\PchLateInitSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\IoTrap\Smm\IoTrap.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\PchSmiDispatcher\Smm\PchSmiDispatcher.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\S3Support\Smm\S3SupportSmm.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+
+#
+# EFI 1.1 drivers
+#
+$(PROJECT_PCH_ROOT)\SataController\Dxe\SataController.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+#
+# Sample drivers
+#
+$(PROJECT_PCH_ROOT)\SampleCode\BiosWriteProtect\Smm\PchBiosWriteProtect.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxeLib.dsc b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxeLib.dsc
new file mode 100644
index 0000000..c2ed62d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchDxeLib.dsc
@@ -0,0 +1,30 @@
+## @file
+# Build description file for building the PCH DXE libraries
+#
+#@copyright
+# Copyright (c) 2008 - 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
+#
+
+#
+# PCH DXE Libraries
+#
+$(PROJECT_PCH_ROOT)\Protocol\IntelPchProtocolLib.inf
+$(PROJECT_PCH_ROOT)\Library\PchPlatformLib\PchPlatformLib.inf
+$(PROJECT_PCH_ROOT)\Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.inf
+$(PROJECT_PCH_ROOT)\Library\PchPciExpressHelpersLib\PchPciExpressHelpersLib.inf
+$(PROJECT_PCH_ROOT)\Library\PchSmbusLib\Dxe\PchSmbusLibDxe.inf
+$(PROJECT_PCH_ROOT)\Library\RcFviDxeLib\RcFviDxeLib.inf
+$(PROJECT_PCH_ROOT)\SampleCode\Library\AslUpdate\Dxe\PchAslUpdateLib.inf
+$(PROJECT_PCH_ROOT)\Guid\PchGuidLib.inf \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.cif b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.cif
new file mode 100644
index 0000000..783287c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.cif
@@ -0,0 +1,33 @@
+<component>
+ name = "IntelPchInclude"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Include"
+ RefName = "IntelPchInclude"
+[files]
+"IntelPchInclude.sdl"
+"PchRegs.h"
+"PchAccess.h"
+"IntelPchDxe.dsc"
+"IntelPchPei.dsc"
+"IntelPchDxeLib.dsc"
+"IntelPchPeiLib.dsc"
+"Library\PchPlatformLib.h"
+"Library\DxeRuntimePciLibPciExpress.h"
+"Library\PchPciExpressHelpersLib.h"
+"Library\PchSmbusLibrary.h"
+"Library\RcFviDxeLib.h"
+"PchRegs\PchRegsHda.h"
+"PchRegs\PchRegsLan.h"
+"PchRegs\PchRegsLpc.h"
+"PchRegs\PchRegsPcie.h"
+"PchRegs\PchRegsRcrb.h"
+"PchRegs\PchRegsSata.h"
+"PchRegs\PchRegsSmbus.h"
+"PchRegs\PchRegsSpi.h"
+"PchRegs\PchRegsThermal.h"
+"PchRegs\PchRegsUsb.h"
+"IobpDefinitions.h"
+"PchRegs\PchRegsAdsp.h"
+"PchUsbConfig.h"
+"PchRegs\PchRegsSerialIo.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.sdl b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.sdl
new file mode 100644
index 0000000..2ed28cd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchInclude.sdl
@@ -0,0 +1,56 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IntelPchInclude/IntelPchInclude.sdl 1 2/08/12 8:41a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:41a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelPchInclude/IntelPchInclude.sdl $
+#
+# 1 2/08/12 8:41a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IntelPchInclude_SUPPORT"
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable IntelpchInclude support in Project"
+End
+
+PATH
+ Name = "INTEL_COUGAR_POINT_INCLUDE_DIR"
+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/Include/IntelPchPei.dsc b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchPei.dsc
new file mode 100644
index 0000000..bfb05b7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchPei.dsc
@@ -0,0 +1,38 @@
+## @file
+# Build description file for building the PCH PEI modules
+#
+#@copyright
+# Copyright (c) 2008 - 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 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
+#
+
+#
+# PEI module produce PCH PPI
+#
+$(PROJECT_PCH_ROOT)\PchInit\Pei\PchInitPeim.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Smbus\Pei\PchSmbusArpDisabled.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Spi\Pei\PchSpiPeim.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Wdt\Pei\WdtPeim.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\Reset\Pei\PchResetPeim.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\SmmControl\Pei\SmmControl.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+$(PROJECT_PCH_ROOT)\S3Support\Pei\PchS3Peim.inf SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+#
+# Recovery related modules
+#
+$(PROJECT_PCH_ROOT)\Usb\Pei\PchUsb.inf Package = CompressPEIM SOURCE_OVERRIDE_PATH = $(EDK_SOURCE)\Foundation\Library\EdkIIGlueLib\EntryPoints
+
+#
+# Sample drivers
+#
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IntelPchPeiLib.dsc b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchPeiLib.dsc
new file mode 100644
index 0000000..28bd22d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IntelPchPeiLib.dsc
@@ -0,0 +1,28 @@
+## @file
+# Build description file for building the PCH PEI Libraries
+#
+#@copyright
+# Copyright (c) 2008 - 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 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
+#
+
+#
+# PCH PEI libraries
+#
+$(PROJECT_PCH_ROOT)\Ppi\IntelPchPpiLib.inf
+$(PROJECT_PCH_ROOT)\Library\PchPlatformLib\PchPlatformLib.inf
+$(PROJECT_PCH_ROOT)\Library\PchPciExpressHelpersLib\PchPciExpressHelpersLib.inf
+$(PROJECT_PCH_ROOT)\Library\PchSmbusLib\Pei\PchSmbusLibPei.inf
+$(PROJECT_PCH_ROOT)\Guid\PchGuidLib.inf
+$(PROJECT_PCH_ROOT)\SampleCode\Ppi\IntelPchSampleCodePpiLib.inf \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/IobpDefinitions.h b/ReferenceCode/Chipset/LynxPoint/Include/IobpDefinitions.h
new file mode 100644
index 0000000..6b070fd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/IobpDefinitions.h
@@ -0,0 +1,51 @@
+/** @file
+ General IOBP data structure and register definitions.
+
+@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 _IOBP_DEFINITIONS_H_
+#define _IOBP_DEFINITIONS_H_
+
+#include "Library/PchPlatformLib.h"
+
+#define IOBP_ADDR(portid, type, lane, block, offset) \
+ ((UINT32) (((portid) << 24) + ((type) << 14) + ((lane) << 8) + (block << 6) + offset))
+
+#define IOBP_PLP_ADDR(portid, type, lane, offset) \
+ ((UINT32) (((portid) << 24) + ((type) << 14) + ((lane) << 8) + offset))
+
+#define PCH_SATA_RXEQ_ID(port, genspeed) \
+ ((UINT32) (((port) << 8) + genspeed))
+
+typedef struct _IOBP_MMIO_TABLE_STRUCT {
+ UINT32 Address;
+ UINT32 AndMask;
+ UINT32 OrMask;
+} IOBP_MMIO_TABLE_STRUCT;
+
+typedef struct IOBP_MMIO_ADDRESS_STRUCT {
+ UINT32 Address;
+} IOBP_MMIO_ADDRESS;
+
+typedef struct _IOBP_SATA_TRACE_TABLE {
+ UINT32 TraceId;
+ UINT32 Address;
+ UINT32 AndMask;
+} IOBP_SATA_RXEQ_TABLE;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/Library/DxeRuntimePciLibPciExpress.h b/ReferenceCode/Chipset/LynxPoint/Include/Library/DxeRuntimePciLibPciExpress.h
new file mode 100644
index 0000000..e3c04df
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/Library/DxeRuntimePciLibPciExpress.h
@@ -0,0 +1,61 @@
+/** @file
+ Header file for the Dxe Runtime PCI Express library.
+
+@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
+**/
+#ifndef _DXE_RUNTIME_PCI_LIB_PCIEXPRESS_H_
+#define _DXE_RUNTIME_PCI_LIB_PCIEXPRESS_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#endif
+
+#if defined(__EDKII_GLUE_BASE_PCI_LIB_CF8__) || defined(__EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__)
+#error "Should not use EdkIIGluePciLibCf8 or EdkIIGluePciLibPciExpress with DxeRuntimePciLibPciExpress.\n"
+#endif
+
+/**
+ Constructor for Pci library. Register VirtualAddressNotifyEvent() notify function
+ It will ASSERT() if that operation fails
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibConstructor (
+ VOID
+ );
+
+/**
+ Register memory space
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If SmPciLibAddressMapIndex) > PCI_LIB_ADDRESS_MAP_MAX_ITEM, then ASSERT().
+
+ @param[in] Address Starting address of the memory space
+ @param[in] Length Length of the memory space
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibRegisterMemory (
+ IN UINTN Address,
+ IN UINTN Length
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPciExpressHelpersLib.h b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPciExpressHelpersLib.h
new file mode 100644
index 0000000..aa5efad
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPciExpressHelpersLib.h
@@ -0,0 +1,296 @@
+/** @file
+ Header file for PCH PCI Express helpers library
+
+@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
+
+**/
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+#define _PCH_PCI_EXPRESS_HELPERS_LIB_H_
+
+//
+// Function prototypes
+//
+/**
+ 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] Function 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 Function,
+ IN UINT8 CapId
+ );
+
+/**
+ Search and return the offset of desired Pci Express Capability ID
+ CAPID list:
+ 0x0001 = Advanced Error Rreporting Capability
+ 0x0002 = Virtual Channel Capability
+ 0x0003 = Device Serial Number Capability
+ 0x0004 = Power Budgeting Capability
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] Function Pci Function Number
+ @param[in] CapId Extended CAPID to search for
+
+ @retval 0 CAPID not found
+ @retval Other CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieFindExtendedCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT16 CapId
+ );
+
+/**
+ Map a TC to VC0 for port and endpoint
+
+ @param[in] Bus1 The bus number of the port
+ @param[in] Device1 The device number of the port
+ @param[in] Function1 The function number of the port
+ @param[in] Bus2 The bus number of the endpoint
+ @param[in] Device2 The device number of the endpoint
+ @param[in] TCx The TC number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMapTcxVc0 (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2,
+ IN UINT8 TCx
+ );
+
+/**
+ Set Common clock to Root port and Endpoint PCI device
+
+ @param[in] Bus1 Root port Pci Bus Number
+ @param[in] Device1 Root port Pci Device Number
+ @param[in] Function1 Root port Pci Function Number
+ @param[in] Bus2 Endpoint Pci Bus Number
+ @param[in] Device2 Endpoint Pci Device Number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS VC mapping correctly initialized
+**/
+EFI_STATUS
+PcieSetCommonClock (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2
+ );
+
+/**
+ This function enables the CLKREQ# PM on all the end point functions
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] RootFunction Rootport Function Number
+
+ @retval None
+**/
+VOID
+PcieSetClkreq (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 RootFunction
+ );
+
+/**
+ This function get or set the Max Payload Size on all the end point functions
+
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+ @param[in] MaxPayload The Max Payolad Size of the root port
+ @param[in] Operation True: Set the Max Payload Size on all the end point functions
+ False: Get the Max Payload Size on all the end point functions
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMaxPayloadSize (
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice,
+ IN OUT UINT16 *MaxPayload,
+ IN BOOLEAN Operation
+ );
+
+/**
+ This function disable the forwarding of EOI messages unless it discovers
+ an IOAPIC behind this root port.
+
+ @param[in] RootBus The Bus Number of the root port
+ @param[in] RootDevice The Device Number of the root port
+ @param[in] RootFunction The Function Number of the root port
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieSetEoiFwdDisable (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice
+ );
+
+/**
+ This function performs the Power Management settings for root port and downstream device
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction 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
+ @param[in, out] L1SubstatesSupported L1 substates supported on the root port
+ @param[in] L1SubstatesConfig L1 substates configurations on the root port
+ @param[in] PolicyRevision Policy revision for codes compatibility
+ @param[in] FirstRpToSetPm Indicates if this is the first root port to be set
+ @param[in] L1SupportedInAllEnabledPorts Check if L1 is supported in all enabled ports
+ @param[in] ClkreqSupportedInAllEnabledPorts Check if clkreq is supported in all enabled ports
+ @param[out] LtrSupported Return to check if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieSetPm (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ 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 OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN BOOLEAN FirstRPToSetPm,
+ IN BOOLEAN L1SupportedInAllEnabledPorts,
+ IN BOOLEAN ClkreqSupportedInAllEnabledPorts,
+ OUT BOOLEAN *LtrSupported
+ );
+
+/**
+ This function checks if the root port and downstream device support Clkreq per port, ASPM L1 and L1 substates
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction 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
+ @param[in, out] L1SubstatesSupported Flag to indicate if L1 Substates are supported
+ @param[in] L1SubstatesConfig L1 Substates configuration
+ @param[in] PolicyRevision Revision of the policy
+ @param[in, out] AspmVal Aspm value for both rootport and end point devices
+ @param[in, out] ClkreqPerPortSupported Clkreq support for both rootport and endpoint devices
+ @param[out] LtrSupported Return to check if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieCheckPmConfig (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ 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 OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN OUT UINT16 *AspmVal,
+ IN OUT BOOLEAN *ClkreqPerPortSupported,
+ OUT BOOLEAN *LtrSupported
+ );
+
+/**
+ Initializes the root port and its down stream devices
+
+ @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
+ @param[out] DeviceClassDword Get the downstream device code dword for unstream RootPort reference
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device.
+**/
+EFI_STATUS
+PchPcieInitRootPortDownstreamDevices (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ OUT UINT32 *DeviceClassDword
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPlatformLib.h b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPlatformLib.h
new file mode 100644
index 0000000..4ebc5d8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchPlatformLib.h
@@ -0,0 +1,385 @@
+/** @file
+ Header file for PchPlatform Lib.
+
+@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 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
+**/
+#ifndef _PCH_PLATFORM_LIB_H_
+#define _PCH_PLATFORM_LIB_H_
+
+///
+/// Timeout value used when Sending / Receiving messages.
+/// NOTE: this must cover the longest possible wait time
+/// between message being sent and response being available.
+/// e.g. Virtual function readiness might take some time.
+///
+
+/**
+ Delay for at least the request number of microseconds.
+ This function would be called by runtime driver, please do not use any MMIO marco here.
+
+ @param[in] Microseconds Number of microseconds to delay.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchPmTimerStall (
+ IN UINTN Microseconds
+ );
+
+/**
+ Check whether SPI is in descriptor mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE SPI is in descriptor mode
+ @retval FALSE SPI is not in descriptor mode
+**/
+BOOLEAN
+EFIAPI
+PchIsSpiDescriptorMode (
+ IN UINTN PchRootComplexBar
+ );
+
+/**
+ Return Pch stepping type
+
+ @param[in] None
+
+ @retval PCH_STEPPING Pch stepping type
+**/
+PCH_STEPPING
+EFIAPI
+PchStepping (
+ VOID
+ );
+
+/**
+ Determine if PCH is supported
+
+ @param[in] None
+
+ @retval TRUE PCH is supported
+ @retval FALSE PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+ VOID
+ );
+
+/**
+ This function can be called to enable/disable Alternate Access Mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+ @param[in] AmeCtrl If TRUE, enable Alternate Access Mode.
+ If FALSE, disable Alternate Access Mode.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchAlternateAccessMode (
+ IN UINTN PchRootComplexBar,
+ IN BOOLEAN AmeCtrl
+ );
+
+/**
+ Configures PCH IOBP
+
+ @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 Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ProgramIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ );
+
+/**
+ Read data from PCH IOBP register block
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] Data Data contain in the IOBP register block
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ReadIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ OUT UINT32 *Data
+ );
+
+
+typedef enum {
+ MemoryMapRead = 0x0,
+ MemoryMapWrite = 0x1,
+ IoMapRead = 0x2,
+ IoMapWrite = 0x3,
+ PciConfigRead = 0x4,
+ PciConfigWrite = 0x5,
+ PrivateControlRead = 0x6,
+ PrivateControlWrite = 0x7
+} PCH_IOBP_OPCODE;
+
+/**
+ Configures PCH IOBP
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] Opcode Iobp Opcode
+ @param[in] RouteId Route Id
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+PchIobpExecution (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN PCH_IOBP_OPCODE Opcode,
+ IN UINT8 RouteId,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ );
+
+/**
+ Check whether Gbe Region is valid in SPI Flash
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE Gbe Region is valid
+ @retval FALSE Gbe Region is invalid
+**/
+BOOLEAN
+EFIAPI
+PchIsGbeRegionValid (
+ IN UINTN PchRootComplexBar
+ );
+
+/**
+ Check if integrated Gbe controller present
+
+ @param[in] None
+
+ @retval TRUE Integrated Gbe present
+ @retval FALSE Integrated Gbe not present
+**/
+BOOLEAN
+EFIAPI
+PchIsIntegratedGbePresent (
+ IN VOID
+ );
+
+typedef enum {
+ PchH = 1,
+ PchLp,
+ PchUnknownSeries
+} PCH_SERIES;
+
+/**
+ Return Pch Series
+
+ @param[in] None
+
+ @retval PCH_SERIES Pch Series
+**/
+PCH_SERIES
+EFIAPI
+GetPchSeries (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Pcie Root Port Number
+
+ @param[in] None
+
+ @retval PcieMaxRootPort Pch Maximum Pcie Root Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxPciePortNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Sata Port Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataPortNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Sata Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Controller Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataControllerNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Usb Port Number of EHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb Port Number of EHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxUsbPortNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum EHCI Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum EHCI Controller Number
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxControllerNum (
+ VOID
+ );
+
+/**
+ Get Pch Usb Maximum Physical Port Number
+
+ @param[in] None
+
+ @retval Pch Usb Maximum Physical Port Number
+**/
+UINT8
+EFIAPI
+GetPchUsbMaxPhysicalPortNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb2PortNum (
+ VOID
+ );
+
+/**
+ Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb3PortNum (
+ VOID
+ );
+
+typedef enum {
+ WarmBoot = 1,
+ ColdBoot,
+ PwrFlr,
+ PwrFlrSys,
+ PwrFlrPch,
+ PchPmStatusMax
+} PCH_PM_STATUS;
+
+/**
+ Query PCH to determine the Pm Status
+
+ @param[in] PmStatus - The Pch Pm Status to be probed
+
+ @retval Return TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+ PCH_PM_STATUS PmStatus
+ )
+;
+
+/**
+ Get Pch Pcie Root Port Function Number by Root Port Number
+
+ @param[in] UINT8 Root Port Number (start from 0)
+
+ @retval Pch Pcie Root Port Function Number
+**/
+UINT8
+EFIAPI
+GetPchPcieRpfn (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 RpNumber
+ );
+
+/**
+ Get Pch Pcie Root Port Number by Root Port Function Number
+
+ @param[in] UINT8 Root Port Function Number
+
+ @retval Pch Pcie Root Port Number
+ @retval 0xFF No Root Port Number found
+**/
+UINT8
+EFIAPI
+GetPchPcieRpNumber (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 Rpfn
+ );
+
+/**
+ Returns GbE over PCIe port number.
+
+ @return Root port number (0-based)
+ @retval GbE over PCIe disabled
+**/
+UINTN
+PchGetGbePortNumber (
+ VOID
+ );
+#endif \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/Library/PchSmbusLibrary.h b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchSmbusLibrary.h
new file mode 100644
index 0000000..4dc0e3c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/Library/PchSmbusLibrary.h
@@ -0,0 +1,44 @@
+/** @file
+ Header file for Pch Smbus Lib.
+
+@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 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
+**/
+#ifndef _PCH_SMBUS_LIBRARY_H_
+#define _PCH_SMBUS_LIBRARY_H_
+
+/**
+ This function provides a standard way to execute Smbus sequential
+ I2C Read. This function allows the PCH to perform block reads to
+ certain I2C devices, such as serial E2PROMs. Typically these data
+ bytes correspond to an offset (address) within the serial memory
+ chips.
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Buffer Pointer to the buffer to store the bytes read
+ from the SMBUS
+ @param[out] Status eturn status for the executed command.
+
+ @retval UINTN The number of bytes read
+**/
+UINTN
+EFIAPI
+SmBusSeqI2CRead (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS * Status OPTIONAL
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/Library/RcFviDxeLib.h b/ReferenceCode/Chipset/LynxPoint/Include/Library/RcFviDxeLib.h
new file mode 100644
index 0000000..eadf3aa
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/Library/RcFviDxeLib.h
@@ -0,0 +1,175 @@
+/** @file
+ Header file for Reference code Firmware Version Info Interface Lib implementation.
+
+@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 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
+**/
+#ifndef _RC_FVI_DXE_LIB_H_
+#define _RC_FVI_DXE_LIB_H_
+
+#include "Smbios.h"
+
+#pragma pack(1)
+
+///
+/// FviSmbios Type table -
+/// {
+/// FVI_HEADER;
+/// FVI_ELEMENTS;
+///...FVI_ELEMENTS;
+/// .....
+/// }
+///
+typedef struct {
+ UINT8 MajorVersion;
+ UINT8 MinorVersion;
+ UINT8 Revision;
+ UINT16 BuildNum;
+} RC_VERSION;
+
+///
+/// If string is implemented for ComponentName or VersionString, and then string index of
+/// ComponentName or VersionString can't be zero. The string index of ComponentName and
+/// VersionString will be updated and calculated when collect all elements.
+/// String index must contain zero if not implemented.
+///
+typedef struct {
+ UINT8 ComponentName;
+ UINT8 VersionString;
+ RC_VERSION Version;
+ UINT8 NameString[SMBIOS_STRING_MAX_LENGTH];
+ UINT8 VerString[SMBIOS_STRING_MAX_LENGTH];
+} FVI_ELEMENTS;
+
+#define FVI_ELEMENTS_SIZE_NOSTRING (sizeof(FVI_ELEMENTS) - SMBIOS_STRING_MAX_LENGTH * 2)
+#define DEFAULT_FVI_ELEMENT_DATA(Name) \
+{ \
+ 0x1, \
+ 0x00, \
+ { \
+ (UINT8) (((Name ## _RC_VERSION) & 0xFF000000) >> 24), \
+ (UINT8) (((Name ## _RC_VERSION) & 0x00FF0000) >> 16), \
+ (UINT8) (((Name ## _RC_VERSION) & 0x0000FF00) >> 8), \
+ (UINT16) (((Name ## _RC_VERSION) & 0x000000FF)), \
+ }, \
+ Name ## _FVI_STRING, \
+ 0 \
+}
+
+///
+/// This is the definitions for SMBIOS FviSmbios Type table
+///
+typedef struct {
+ SMBIOS_STRUCTURE_HDR Header;
+ UINT8 Count; ///< Number of elements included
+} FVI_HEADER;
+
+///
+/// This is definition for Misc sub class data hub
+///
+typedef struct {
+ EFI_SUBCLASS_TYPE1_HEADER Header;
+ FVI_HEADER FviHdr;
+} MISC_SUBCLASS_FVI_HEADER;
+
+///
+/// Use the OEM Data Record for SMBIOS Type 0x80-0xFF
+///
+#define MISC_SUBCLASS_TYPE1_HEADER_DATA(Name) \
+{ \
+ EFI_MISC_SUBCLASS_VERSION, \
+ sizeof(EFI_SUBCLASS_TYPE1_HEADER), \
+ Name ## _FVI_SMBIOS_INSTANCE, \
+ 0x1, \
+ EFI_MISC_SMBIOS_STRUCT_ENCAP_RECORD_NUMBER \
+}
+
+#define DEFAULT_FVI_HEADER_DATA(Name) \
+{ \
+ { \
+ Name ## _FVI_SMBIOS_TYPE, \
+ sizeof(FVI_HEADER), \
+ 0x00, \
+ }, \
+ 0x1 \
+}
+
+///
+/// Initialize per-record portion of subclass header and fvi header, also fill
+/// static data into data portion of record
+///
+#define MISC_SUBCLASS_FVI_HEADER_ENTRY(Name) \
+{\
+ MISC_SUBCLASS_TYPE1_HEADER_DATA(Name), \
+ DEFAULT_FVI_HEADER_DATA(Name) \
+}
+
+///
+/// The function to update the element before log to Data Hub
+///
+typedef EFI_STATUS (EFIAPI FVI_ELEMENT_FUNCTION) (
+ IN OUT FVI_ELEMENTS *Element
+ );
+
+typedef struct {
+ FVI_ELEMENTS Element;
+ FVI_ELEMENT_FUNCTION *Function;
+} FVI_ELEMENT_AND_FUNCTION;
+
+typedef struct {
+ MISC_SUBCLASS_FVI_HEADER FviHeader;
+ FVI_ELEMENT_AND_FUNCTION *Elements; ///< Pointer to elements.
+} FVI_DATA_HUB_CALLBACK_CONTEXT;
+
+#pragma pack()
+
+/**
+ Initialize callback context for Firmware Version Info (FVI) Interface Spec v0.7
+ implementation.
+
+ Invoke this routine to initialize data hub and context for log,
+ all elements can be updated before execute CreateRcFviDatahub or updated by
+ the element hook that registered as FVI_ELEMENT_FUNCTION
+
+ @param[in] Type Value is defined in SMBIOS Type 14 - Group Associaction structure - item type.
+ @param[in] Count Number of elements included by this SMBIOS table
+ @param[in] FviContext Context of FVI elements for data hub log
+
+ @retval None
+**/
+VOID
+InitFviDataHubCbContext (
+ IN UINT8 Type,
+ IN UINT8 Count,
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ );
+
+/**
+ Create the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ to Data Hub.
+
+ Invoke this routine to log record when all Fvi elements are finialized
+
+ @param[in] FviContext Pointer to the notification functions context, which is context of FVI
+ elements for data hub log
+
+ @retval None
+**/
+VOID
+CreateRcFviDatahub (
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ )
+;
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchAccess.h b/ReferenceCode/Chipset/LynxPoint/Include/PchAccess.h
new file mode 100644
index 0000000..206a2cc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchAccess.h
@@ -0,0 +1,509 @@
+/** @file
+ Macros that simplify accessing PCH devices's PCI registers.
+
+ ** NOTE ** these macros assume the PCH device is on BUS 0
+
+@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
+**/
+#ifndef _PCH_ACCESS_H_
+#define _PCH_ACCESS_H_
+
+#include "PchRegs.h"
+
+#ifndef STALL_ONE_MICRO_SECOND
+#define STALL_ONE_MICRO_SECOND 1
+#endif
+#ifndef STALL_ONE_SECOND
+#define STALL_ONE_SECOND 1000000
+#endif
+
+///
+/// Memory Mapped PCI Access macros
+///
+///
+/// PCI Device MM Base
+///
+#ifndef MmPciAddress
+#define MmPciAddress(Segment, Bus, Device, Function, Register) \
+ ((UINTN) (PciRead32 (PCI_LIB_ADDRESS (0,0,0,0x60)) & 0xFC000000) + \
+ (UINTN) (Bus << 20) + \
+ (UINTN) (Device << 15) + \
+ (UINTN) (Function << 12) + \
+ (UINTN) (Register) \
+ )
+#endif
+///
+/// Pch Controller PCI access macros
+///
+#define PCH_RCRB_BASE ( \
+ MmioRead32 (MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ R_PCH_LPC_RCBA)) &~BIT0 \
+ )
+
+//
+// Device 0x1b, Function 0
+//
+#define PchAzaliaPciCfg32(Register) \
+ MmioRead32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register) \
+ )
+
+#define PchAzaliaPciCfg32Or(Register, OrData) \
+ MmioOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchAzaliaPciCfg32And(Register, AndData) \
+ MmioAnd32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchAzaliaPciCfg32AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchAzaliaPciCfg16(Register) \
+ MmioRead16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register) \
+ )
+
+#define PchAzaliaPciCfg16Or(Register, OrData) \
+ MmioOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchAzaliaPciCfg16And(Register, AndData) \
+ MmioAnd16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchAzaliaPciCfg16AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchAzaliaPciCfg8(Register) MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_AZALIA, 0, Register))
+
+#define PchAzaliaPciCfg8Or(Register, OrData) \
+ MmioOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchAzaliaPciCfg8And(Register, AndData) \
+ MmioAnd8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchAzaliaPciCfg8AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_AZALIA, \
+ 0, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+//
+// Device 0x1f, Function 0
+//
+#define PchLpcPciCfg32(Register) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcPciCfg32Or (Register, OrData) \
+ MmioOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchLpcPciCfg32And(Register, AndData) \
+ MmioAnd32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchLpcPciCfg32AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchLpcPciCfg16(Register) MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcPciCfg16Or(Register, OrData) \
+ MmioOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchLpcPciCfg16And(Register, AndData) \
+ MmioAnd16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchLpcPciCfg16AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchLpcPciCfg8(Register) MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PchLpcPciCfg8Or(Register, OrData) \
+ MmioOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ OrData \
+ )
+
+#define PchLpcPciCfg8And(Register, AndData) \
+ MmioAnd8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData \
+ )
+
+#define PchLpcPciCfg8AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ 0, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+//
+// SATA 1 device 0x1f, Function 2
+//
+#define PchSataPciCfg32(Register) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, 2, Register))
+
+#define PchSataPciCfg32Or(Register, OrData) \
+ MmioOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ OrData \
+ )
+
+#define PchSataPciCfg32And(Register, AndData) \
+ MmioAnd32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData \
+ )
+
+#define PchSataPciCfg32AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchSataPciCfg16(Register) MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, 2, Register))
+
+#define PchSataPciCfg16Or(Register, OrData) \
+ MmioOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ OrData \
+ )
+
+#define PchSataPciCfg16And(Register, AndData) \
+ MmioAnd16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData \
+ )
+
+#define PchSataPciCfg16AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchSataPciCfg8(Register) MmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA, 2, Register))
+
+#define PchSataPciCfg8Or(Register, OrData) \
+ MmioOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ OrData \
+ )
+
+#define PchSataPciCfg8And(Register, AndData) \
+ MmioAnd8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData \
+ )
+
+#define PchSataPciCfg8AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA, \
+ 2, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+//
+// SATA 2 device 0x1f, Function 5
+//
+#define PchSata2PciCfg32(Register) MmioRead32 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA2, 5, Register))
+
+#define PchSata2PciCfg32Or(Register, OrData) \
+ MmioOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ OrData \
+ )
+
+#define PchSata2PciCfg32And(Register, AndData) \
+ MmioAnd32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData \
+ )
+
+#define PchSata2PciCfg32AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr32 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchSata2PciCfg16(Register) MmioRead16 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA2, 5, Register))
+
+#define PchSata2PciCfg16Or(Register, OrData) \
+ MmioOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ OrData \
+ )
+
+#define PchSata2PciCfg16And(Register, AndData) \
+ MmioAnd16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData \
+ )
+
+#define PchSata2PciCfg16AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr16 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+#define PchSata2PciCfg8(Register) MmioRead8 (MmPciAddress (DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_SATA2, 5, Register))
+
+#define PchSata2PciCfg8Or(Register, OrData) \
+ MmioOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ OrData \
+ )
+
+#define PchSata2PciCfg8And(Register, AndData) \
+ MmioAnd8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData \
+ )
+
+#define PchSata2PciCfg8AndThenOr(Register, AndData, OrData) \
+ MmioAndThenOr8 ( \
+ MmPciAddress (0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_SATA2, \
+ 5, \
+ Register), \
+ AndData, \
+ OrData \
+ )
+
+//
+// Root Complex Register Block
+//
+#define PchMmRcrb32(Register) MmioRead32 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb32Or(Register, OrData) MmioOr32 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb32And(Register, AndData) MmioAnd32 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb32AndThenOr(Register, AndData, OrData) MmioAndThenOr32 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+#define PchMmRcrb16(Register) MmioRead16 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb16Or(Register, OrData) MmioOr16 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb16And(Register, AndData) MmioAnd16 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb16AndThenOr(Register, AndData, OrData) MmioAndThenOr16 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+#define PchMmRcrb8(Register) MmioRead8 (PCH_RCRB_BASE + Register)
+
+#define PchMmRcrb8Or(Register, OrData) MmioOr8 (PCH_RCRB_BASE + Register, OrData)
+
+#define PchMmRcrb8And(Register, AndData) MmioAnd8 (PCH_RCRB_BASE + Register, AndData)
+
+#define PchMmRcrb8AndThenOr(Register, AndData, OrData) MmioAndThenOr8 (PCH_RCRB_BASE + Register, AndData, OrData)
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h
new file mode 100644
index 0000000..b37ef61
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs.h
@@ -0,0 +1,474 @@
+/** @file
+ Register names for PCH.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_H_
+#define _PCH_REGS_H_
+
+//
+// Bit Difinitions.
+// @bug drive these definitions to code base. Should not need to be part of
+// chipset modules
+//
+#ifndef BIT0
+#define BIT0 0x0001
+#define BIT1 0x0002
+#define BIT2 0x0004
+#define BIT3 0x0008
+#define BIT4 0x0010
+#define BIT5 0x0020
+#define BIT6 0x0040
+#define BIT7 0x0080
+#define BIT8 0x0100
+#define BIT9 0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+#define BIT32 0x100000000
+#define BIT33 0x200000000
+#define BIT34 0x400000000
+#define BIT35 0x800000000
+#define BIT36 0x1000000000
+#define BIT37 0x2000000000
+#define BIT38 0x4000000000
+#define BIT39 0x8000000000
+#define BIT40 0x10000000000
+#define BIT41 0x20000000000
+#define BIT42 0x40000000000
+#define BIT43 0x80000000000
+#define BIT44 0x100000000000
+#define BIT45 0x200000000000
+#define BIT46 0x400000000000
+#define BIT47 0x800000000000
+#define BIT48 0x1000000000000
+#define BIT49 0x2000000000000
+#define BIT50 0x4000000000000
+#define BIT51 0x8000000000000
+#define BIT52 0x10000000000000
+#define BIT53 0x20000000000000
+#define BIT54 0x40000000000000
+#define BIT55 0x80000000000000
+#define BIT56 0x100000000000000
+#define BIT57 0x200000000000000
+#define BIT58 0x400000000000000
+#define BIT59 0x800000000000000
+#define BIT60 0x1000000000000000
+#define BIT61 0x2000000000000000
+#define BIT62 0x4000000000000000
+#define BIT63 0x8000000000000000
+#endif
+///
+/// The default PCH PCI bus number
+///
+#define DEFAULT_PCI_BUS_NUMBER_PCH 0
+
+//
+// Default Vendor ID and Subsystem ID
+//
+#define V_PCH_INTEL_VENDOR_ID 0x8086 ///< Default Intel PCH Vendor ID
+#define V_PCH_DEFAULT_SID 0x7270 ///< Default Intel PCH Subsystem ID
+#define V_PCH_DEFAULT_SVID_SID (V_INTEL_VENDOR_ID + (V_PCH_DEFAULT_SID << 16)) ///< Default INTEL PCH Vendor ID and Subsystem ID
+
+//
+// Include device register definitions
+//
+#include "PchRegs/PchRegsHda.h"
+#include "PchRegs/PchRegsLan.h"
+#include "PchRegs/PchRegsLpc.h"
+#include "PchRegs/PchRegsPcie.h"
+#include "PchRegs/PchRegsRcrb.h"
+#include "PchRegs/PchRegsSata.h"
+#include "PchRegs/PchRegsSmbus.h"
+#include "PchRegs/PchRegsSpi.h"
+#include "PchRegs/PchRegsThermal.h"
+#include "PchRegs/PchRegsUsb.h"
+#ifdef SERIAL_IO_FLAG
+#include "PchRegs/PchRegsSerialIo.h"
+#endif // SERIAL_IO_FLAG
+#ifdef ADSP_FLAG
+#include "PchRegs/PchRegsAdsp.h"
+#endif // ADSP_FLAG
+
+//
+// LPC Device ID macros
+//
+//
+// Device IDs that are PCH LPT Desktop specific
+//
+#define IS_PCH_LPTH_LPC_DEVICE_ID_DESKTOP(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_0) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_1) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_3) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_4) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_5) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_6) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_2) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_DT_SUPER_SKU) \
+ )
+
+#define IS_PCH_LPTLP_LPC_DEVICE_ID_DESKTOP(DeviceId) (FALSE)
+
+#define IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID_DESKTOP(DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_DESKTOP(DeviceId) \
+ )
+
+//
+// Device IDs that are PCH LPT Mobile specific
+//
+#define IS_PCH_LPTH_LPC_DEVICE_ID_MOBILE(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_MB_0) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_MB_2) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_MB_1) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_MB_SUPER_SKU) \
+ )
+
+#define IS_PCH_LPTLP_LPC_DEVICE_ID_MOBILE(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_SUPER_SKU) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_0) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_1) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_2) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_3) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_4) || \
+ (DeviceId == V_PCH_LPTLP_LPC_DEVICE_ID_MB_5) \
+ )
+
+#define IS_PCH_LPT_LPC_DEVICE_ID_MOBILE(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID_MOBILE(DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_MOBILE(DeviceId) \
+ )
+//
+// Device IDS that are PCH LPT WorkStation specific
+//
+#define IS_PCH_LPTH_LPC_DEVICE_ID_WS(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_SVR_3) || \
+ FALSE \
+ )
+
+#define IS_PCH_LPTLP_LPC_DEVICE_ID_WS(DeviceId) (FALSE)
+
+#define IS_PCH_LPT_LPC_DEVICE_ID_WS(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID_WS(DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_WS(DeviceId) \
+ )
+
+//
+// Device IDS that are PCH LPT Server specific
+//
+#define IS_PCH_LPTH_LPC_DEVICE_ID_SERVER(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_SVR_0) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_SVR_1) || \
+ (DeviceId == V_PCH_LPTH_LPC_DEVICE_ID_SVR_2) || \
+ FALSE \
+ )
+
+#define IS_PCH_LPTLP_LPC_DEVICE_ID_SERVER(DeviceId) (FALSE)
+
+#define IS_PCH_LPT_LPC_DEVICE_ID_SERVER(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID_SERVER(DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_SERVER(DeviceId) \
+ )
+
+#define IS_PCH_LPTH_LPC_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID_DESKTOP (DeviceId) || \
+ IS_PCH_LPTH_LPC_DEVICE_ID_MOBILE (DeviceId) || \
+ IS_PCH_LPTH_LPC_DEVICE_ID_WS (DeviceId) || \
+ IS_PCH_LPTH_LPC_DEVICE_ID_SERVER (DeviceId) \
+ )
+
+#define IS_PCH_LPTLP_LPC_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_DESKTOP (DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_MOBILE (DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_WS (DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID_SERVER (DeviceId) \
+ )
+
+#define IS_PCH_LPT_LPC_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_LPC_DEVICE_ID(DeviceId) \
+ )
+
+//
+// SATA AHCI Device ID macros
+//
+#define IS_PCH_LPTH_SATA_AHCI_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_AHCI) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_M_AHCI) \
+ )
+
+#define IS_PCH_LPTLP_SATA_AHCI_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_AHCI0) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_AHCI1) \
+ )
+
+#define IS_PCH_LPT_SATA_AHCI_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_SATA_AHCI_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_SATA_AHCI_DEVICE_ID (DeviceId) \
+ )
+
+//
+// SATA IDE Device ID macros
+//
+#define IS_PCH_LPTH_SATA_IDE_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_IDE) || \
+ (DeviceId == V_PCH_LPTH_SATA2_DEVICE_ID_D_IDE) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_M_IDE) || \
+ (DeviceId == V_PCH_LPTH_SATA2_DEVICE_ID_M_IDE) \
+ )
+
+#define IS_PCH_LPTLP_SATA_IDE_DEVICE_ID(DeviceId) (FALSE)
+
+#define IS_PCH_LPT_SATA_IDE_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_SATA_IDE_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_SATA_IDE_DEVICE_ID(DeviceId) \
+ )
+
+//
+// SATA RAID Device ID macros
+//
+#define IS_PCH_LPTH_SATA_RAID_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_RAID) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_PREM) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_ALTDIS) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_M_RAID) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_M_RAID_PREM) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_SERVER) || \
+ (DeviceId == V_PCH_LPTH_SATA_DEVICE_ID_M_RAID_ALTDIS) \
+ )
+
+#define IS_PCH_LPTLP_SATA_RAID_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID0) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID1) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID2) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID3) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_ALTDIS0) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_ALTDIS1) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_PREM0) || \
+ (DeviceId == V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_PREM1) \
+ )
+
+#define IS_PCH_LPT_SATA_RAID_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_SATA_RAID_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_SATA_RAID_DEVICE_ID(DeviceId) \
+ )
+
+//
+// Combined SATA IDE/AHCI/RAID Device ID macros
+//
+#define IS_PCH_LPTH_SATA_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_SATA_IDE_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTH_SATA_AHCI_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTH_SATA_RAID_DEVICE_ID (DeviceId) \
+ )
+
+#define IS_PCH_LPTLP_SATA_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTLP_SATA_AHCI_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_SATA_RAID_DEVICE_ID (DeviceId) \
+ )
+
+#define IS_PCH_LPT_SATA_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_SATA_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_SATA_DEVICE_ID (DeviceId) \
+ )
+
+#define IS_PCH_LPTH_RAID_AVAILABLE(DeviceId) (TRUE)
+#define IS_PCH_LPTLP_RAID_AVAILABLE(DeviceId) (TRUE)
+#define IS_PCH_LPT_RAID_AVAILABLE(DeviceId) \
+ ( \
+ IS_PCH_LPTH_RAID_AVAILABLE(DeviceId) || \
+ IS_PCH_LPTLP_RAID_AVAILABLE(DeviceId) \
+ )
+
+//
+// USB Device ID macros
+//
+#define IS_PCH_LPTH_USB_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_USB_DEVICE_ID_EHCI_1) || \
+ (DeviceId == V_PCH_LPTH_USB_DEVICE_ID_EHCI_2) || \
+ (DeviceId == V_PCH_LPTH_USB_DEVICE_ID_XHCI_1) \
+ )
+
+#define IS_PCH_LPTLP_USB_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_USB_DEVICE_ID_EHCI_1) || \
+ (DeviceId == V_PCH_LPTLP_USB_DEVICE_ID_XHCI_1) \
+ )
+
+#define IS_PCH_LPT_USB_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_USB_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_USB_DEVICE_ID(DeviceId) \
+ )
+
+//
+// PCIE Device ID macros
+//
+#define IS_PCH_LPTH_PCIE_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT1) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT2) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT3) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT4) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT5) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT6) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT7) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_PORT8) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_MB_SUBD) || \
+ (DeviceId == V_PCH_LPTH_PCIE_DEVICE_ID_DT_SUBD) \
+ )
+
+#define IS_PCH_LPTLP_PCIE_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT1) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT1_ALT) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT2) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT2_ALT) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT3) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT3_ALT) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT4) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT4_ALT) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT5) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT5_ALT) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT6) || \
+ (DeviceId == V_PCH_LPTLP_PCIE_DEVICE_ID_PORT6_ALT) \
+ )
+
+#define IS_PCH_LPT_PCIE_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_PCIE_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_PCIE_DEVICE_ID(DeviceId) \
+ )
+
+//
+// HD Azalia Device ID macros
+//
+#define IS_PCH_LPTLP_HDA_DEVICE_ID(DeviceId) \
+ ( \
+ (DeviceId == V_PCH_LPTLP_HDA_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_HDA_DEVICE_ID_ALT) \
+ )
+
+///
+/// Any device ID that is PCH LynxPoint
+///
+#define IS_PCH_LPTH_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTH_LPC_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTH_SATA_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTH_USB_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTH_PCIE_DEVICE_ID (DeviceId) || \
+ (DeviceId) == V_PCH_LPTH_THERMAL_DEVICE_ID || \
+ (DeviceId) == V_PCH_LPTH_SMBUS_DEVICE_ID || \
+ (DeviceId) == V_PCH_LPTH_LAN_DEVICE_ID || \
+ (DeviceId) == V_PCH_LPTH_HDA_DEVICE_ID \
+ )
+
+///
+/// Any device ID that is PCH LynxPoint-LP
+///
+#define IS_PCH_LPTLP_DEVICE_ID(DeviceId) \
+ ( \
+ IS_PCH_LPTLP_LPC_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_SATA_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_USB_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_PCIE_DEVICE_ID (DeviceId) || \
+ IS_PCH_LPTLP_HDA_DEVICE_ID (DeviceId) || \
+ (DeviceId == V_PCH_LPTLP_THERMAL_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_SMBUS_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_LAN_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_ADSP_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_DMA_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_I2C0_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_I2C1_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_SPI0_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_SPI1_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_UART0_DEVICE_ID) || \
+ (DeviceId == V_PCH_UART1_SDIO_DEVICE_ID) || \
+ (DeviceId == V_PCH_LPTLP_SDIO_DEVICE_ID) \
+ )
+
+///
+/// Combined any device ID that is PCH LynxPoint or LynxPoint-LP
+///
+#define IS_PCH_LPT_DEVICE_ID(DeviceId) \
+ (\
+ IS_PCH_LPTH_DEVICE_ID(DeviceId) || \
+ IS_PCH_LPTLP_DEVICE_ID(DeviceId) \
+ )
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsAdsp.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsAdsp.h
new file mode 100644
index 0000000..94198e7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsAdsp.h
@@ -0,0 +1,109 @@
+/** @file
+ Register names for Audio DSP block
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_CPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_ADSP_H_
+#define _PCH_REGS_ADSP_H_
+
+#ifdef ADSP_FLAG
+
+#define MMIO_ADDR_MASK 0xFFFFFFF0
+
+//
+// AUDIO DSP Registers (D19:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_ADSP 19
+#define PCI_FUNCTION_NUMBER_PCH_ADSP 0
+#define R_PCH_ADSP_VENDOR_ID 0x00
+#define V_PCH_ADSP_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LPTLP_ADSP_DEVICE_ID 0x02
+#define V_PCH_LPTLP_ADSP_DEVICE_ID 0x9C36
+
+//
+// Audio DSP PCI Configuration space definitions
+//
+#define R_PCH_ADSP_COMMAND 0x04
+#define B_PCH_ADSP_COMMAND_BME BIT2
+#define B_PCH_ADSP_COMMAND_MSE BIT1
+#define R_PCH_ADSP_ADBA 0x10
+#define R_PCH_ADSP_SPCBA 0x14
+#define R_PCH_ADSP_VDRTCTL0 0xA0
+#define B_PCH_ADSP_VDRTCTL0_D3SRAMPGD BIT2
+#define B_PCH_ADSP_VDRTCTL0_D3PGD BIT1
+#define R_PCH_ADSP_VDRTCTL2 0xA8
+#define V_PCH_ADSP_VDRTCTL2 0xFFF
+#define R_PCH_ADSP_PME_CTRL_STS 0x84
+#define B_PCH_ADSP_PME_CTRL_STS_PWR_ST (BIT1|BIT0)
+
+#define SB_DSP_ID 0xD7
+
+//
+// Audio DSP IOSF Sideband interface definitions
+//
+#define R_PCH_RCRB_IOBPIRI_IOBPIS_ADSP 0xD7000000 ///< ADSP
+
+#define R_PCH_ADSP_VDLDAT1 0x624
+#define V_PCH_ADSP_VDLDAT1_CCO 0x40100
+
+#define R_PCH_ADSP_VDLDAT2 0x628
+#define V_PCH_ADSP_VDLDAT2_MASK 0xFFFF
+#define V_PCH_ADSP_VDLDAT2_IRQ3 0xD9D8
+#define V_PCH_ADSP_VDLDAT2_IRQ3_INV 0xD8D9
+#define V_PCH_ADSP_VDLDAT2_IRQ4 0xDBDA
+
+#define R_PCH_ADSP_PCICFGCTL 0x500
+#define B_PCH_ADSP_PCICFGCTL_PCICD BIT0
+#define B_PCH_ADSP_PCICFGCTL_ACPIIE BIT1
+#define B_PCH_ADSP_PCICFGCTL_SPCBAD BIT7
+
+#define R_PCH_ADSP_PMCTL 0x1E0
+#define V_PCH_ADSP_PMCTL 0x3F
+
+//
+// Audio DSP Shim registers
+//
+#define R_PCH_ADSP_SHIM_BASE 0xE7000
+#define R_PCH_ADSP_SHIM_LTRC 0xE0
+#define V_PCH_ADSP_SHIM_LTRC 0x3003
+
+// ACPI Interrupt
+#define R_PCH_ADSP_SHIM_IMC 0x28
+#define V_PCH_ADSP_SHIM_IMC 0x7FFF0000
+#define R_PCH_ADSP_SHIM_IPCD 0x40
+#define V_PCH_ADSP_SHIM_IPCD_1 0x80000000
+#define V_PCH_ADSP_SHIM_IPCD_2 0x04000000
+
+#endif // ADSP_FLAG
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h
new file mode 100644
index 0000000..45b324d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsHda.h
@@ -0,0 +1,399 @@
+/** @file
+ Register names for PCH High Definition Audio device.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_HDA_H_
+#define _PCH_REGS_HDA_H_
+
+//
+// Azalia Controller Registers (D27:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_AZALIA 27
+#define PCI_FUNCTION_NUMBER_PCH_AZALIA 0
+
+#define R_PCH_HDA_VENDOR_ID 0x00
+#define V_PCH_HDA_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_HDA_DEVICE_ID 0x02
+#define V_PCH_LPTH_HDA_DEVICE_ID 0x8C20
+#define V_PCH_LPTLP_HDA_DEVICE_ID 0x9C20 ///< Azalia Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_HDA_DEVICE_ID_ALT 0x9C21 ///< Azalia Device ID bit[0] fuse = 1
+#define R_PCH_HDA_COMMAND 0x04
+#define B_PCH_HDA_COMMAND_INTR_DIS BIT10
+#define B_PCH_HDA_COMMAND_FBE BIT9
+#define B_PCH_HDA_COMMAND_SERR_EN BIT8
+#define B_PCH_HDA_COMMAND_WCC BIT7
+#define B_PCH_HDA_COMMAND_PER BIT6
+#define B_PCH_HDA_COMMAND_VPS BIT5
+#define B_PCH_HDA_COMMAND_MWIE BIT4
+#define B_PCH_HDA_COMMAND_SCE BIT3
+#define B_PCH_HDA_COMMAND_BME BIT2
+#define B_PCH_HDA_COMMAND_MSE BIT1
+#define B_PCH_HDA_COMMAND_IOSE BIT0
+#define R_PCH_HDA_STS 0x06
+#define B_PCH_HDA_STS_DPE BIT15
+#define B_PCH_HDA_STS_SSE BIT14
+#define B_PCH_HDA_STS_RMA BIT13
+#define B_PCH_HDA_STS_RTA BIT12
+#define B_PCH_HDA_STS_STA BIT11
+#define B_PCH_HDA_STS_DEV_STS (BIT10 | BIT9)
+#define B_PCH_HDA_STS_DPED BIT8
+#define B_PCH_HDA_STS_FB2BC BIT7
+#define B_PCH_HDA_STS_66MHZ_CAP BIT5
+#define B_PCH_HDA_STS_CAP_LST BIT4
+#define B_PCH_HDA_STS_INTR_STS BIT3
+#define R_PCH_HDA_RID 0x08
+#define B_PCH_HDA_RID 0xFF
+#define R_PCH_HDA_PI 0x09
+#define B_PCH_HDA_PI 0xFF
+#define R_PCH_HDA_SCC 0x0A
+#define B_PCH_HDA_SCC 0xFF
+#define R_PCH_HDA_BCC 0x0B
+#define B_PCH_HDA_BCC 0xFF
+#define R_PCH_HDA_CLS 0x0C
+#define B_PCH_HDA_CLS 0xFF
+#define R_PCH_HDA_LT 0x0D
+#define B_PCH_HDA_LT 0xFF
+#define R_PCH_HDA_HEADTYPE 0x0E
+#define B_PCH_HDA_HEADTYPE 0xFF
+#define R_PCH_HDA_HDBARL 0x10
+#define B_PCH_HDA_HDBARL_LBA 0xFFFFC000
+#define B_PCH_HDA_HDBARL_PREF BIT3
+#define B_PCH_HDA_HDBARL_ADDRNG (BIT2 | BIT1)
+#define B_PCH_HDA_HDBARL_SPTYP BIT0
+#define V_PCH_HDA_HDBAR_SIZE (1 << 14)
+#define R_PCH_HDA_HDBARU 0x14
+#define B_PCH_HDA_HDBARU_UBA 0xFFFFFFFF
+#define R_PCH_HDA_SVID 0x2C
+#define B_PCH_HDA_SVID 0xFFFF
+#define R_PCH_HDA_SID 0x2E
+#define B_PCH_HDA_SID 0xFFFF
+#define R_PCH_HDA_CAPPTR 0x34
+#define B_PCH_HDA_CAPPTR 0xFF
+#define R_PCH_HDA_INTLN 0x3C
+#define B_PCH_HDA_INTLN 0xFF
+#define R_PCH_HDA_INTPN 0x3D
+#define B_PCH_HDA_INTPN 0x0F
+#define R_PCH_HDA_HDCTL 0x40
+#define B_PCH_HDA_HDCTL_BCLD BIT1
+#define B_PCH_HDA_HDCTL_MODE BIT0
+#define R_PCH_HDA_AZIOBC 0x42
+#define B_PCH_HDA_AZIOBC_OSEL (BIT7 | BIT6)
+#define B_PCH_HDA_AZIOBC_AVDDIS BIT2
+#define R_PCH_HDA_TCSEL 0x44
+#define B_PCH_HDA_TCSEL (BIT2 | BIT1 | BIT0)
+#define V_PCH_HDA_TCSEL_TC0 0x00
+#define V_PCH_HDA_TCSEL_TC1 0x01
+#define V_PCH_HDA_TCSEL_TC2 0x02
+#define V_PCH_HDA_TCSEL_TC3 0x03
+#define V_PCH_HDA_TCSEL_TC4 0x04
+#define V_PCH_HDA_TCSEL_TC5 0x05
+#define V_PCH_HDA_TCSEL_TC6 0x06
+#define V_PCH_HDA_TCSEL_TC7 0x07
+#define R_PCH_HDA_DCKCTL 0x4C
+#define B_PCH_HDA_DCKCTL_DA BIT0
+#define R_PCH_HDA_DCKSTS 0x4D
+#define B_PCH_HDA_DCKSTS_DS BIT7
+#define B_PCH_HDA_DCKSTS_DM BIT0
+#define R_PCH_HDA_PID 0x50
+#define B_PCH_HDA_PID_NEXT 0xFF00
+#define B_PCH_HDA_PID_CAP 0x00FF
+#define R_PCH_HDA_PC 0x52
+#define B_PCH_HDA_PC_PME 0xF800
+#define B_PCH_HDA_PC_D2_SUP BIT10
+#define B_PCH_HDA_PC_D1_SUP BIT9
+#define B_PCH_HDA_PC_AUX (BIT8 | BIT7 | BIT6)
+#define B_PCH_HDA_PC_DSI BIT5
+#define B_PCH_HDA_PC_PMEC BIT3
+#define B_PCH_HDA_PC_VER (BIT2 | BIT1 | BIT0)
+#define R_PCH_HDA_PCS 0x54
+#define B_PCH_HDA_PCS_DATA 0xFF000000
+#define B_PCH_HDA_PCS_CCE BIT23
+#define B_PCH_HDA_PCS_PMES BIT15
+#define B_PCH_HDA_PCS_PMEE BIT8
+#define B_PCH_HDA_PCS_PS (BIT1 | BIT0)
+#define V_PCH_HDA_PCS_PS0 0x00
+#define V_PCH_HDA_PCS_PS3 0x03
+#define R_PCH_HDA_MID 0x60
+#define B_PCH_HDA_MID_NEXT 0xFF00
+#define B_PCH_HDA_MID_CAP 0x00FF
+#define R_PCH_HDA_MMC 0x62
+#define B_PCH_HDA_MMC_64ADD BIT7
+#define B_PCH_HDA_MMC_MME (BIT6 | BIT5 | BIT4)
+#define B_PCH_HDA_MMC_MMC (BIT3 | BIT2 | BIT1)
+#define B_PCH_HDA_MMC_ME BIT0
+#define R_PCH_HDA_MMLA 0x64
+#define B_PCH_HDA_MMLA 0xFFFFFFFC
+#define R_PCH_HDA_MMUA 0x68
+#define B_PCH_HDA_MMUA 0xFFFFFFFF
+#define R_PCH_HDA_MMD 0x6C
+#define B_PCH_HDA_MMD 0xFFFF
+#define R_PCH_HDA_PXID 0x70
+#define B_PCH_HDA_PXID_NEXT 0xFF00
+#define B_PCH_HDA_PXID_CAP 0x00FF
+#define R_PCH_HDA_PXC 0x72
+#define B_PCH_HDA_PXC_IMN 0x3E00
+#define B_PCH_HDA_PXC_SI BIT8
+#define B_PCH_HDA_PXC_DPT 0x00F0
+#define B_PCH_HDA_PXC_CV 0x000F
+#define R_PCH_HDA_DEVCAP 0x74
+#define B_PCH_HDA_DEVCAP_FLR BIT28
+#define B_PCH_HDA_DEVCAP_SPLS (BIT27 | BIT26)
+#define B_PCH_HDA_DEVCAP_SPLV 0x03FC0000
+#define B_PCH_HDA_DEVCAP_PWRIP BIT14
+#define B_PCH_HDA_DEVCAP_ATTNIP BIT13
+#define B_PCH_HDA_DEVCAP_ATTNBP BIT12
+#define B_PCH_HDA_DEVCAP_EL1AL 0x00000E00
+#define B_PCH_HDA_DEVCAP_EL0AL 0x000001C0
+#define B_PCH_HDA_DEVCAP_ETFS BIT5
+#define B_PCH_HDA_DEVCAP_PFS (BIT4 | BIT3)
+#define B_PCH_HDA_DEVCAP_MPSS 0x00000007
+#define R_PCH_HDA_DEVC 0x78
+#define B_PCH_HDA_DEVC_IF BIT15
+#define B_PCH_HDA_DEVC_MRRS (BIT13 | BIT12 | BIT11)
+#define B_PCH_HDA_DEVC_NSNPEN BIT11
+#define B_PCH_HDA_DEVC_APE BIT10
+#define B_PCH_HDA_DEVC_PFE BIT9
+#define B_PCH_HDA_DEVC_ETFE BIT8
+#define B_PCH_HDA_DEVC_MPS (BIT7 | BIT6 | BIT5)
+#define B_PCH_HDA_DEVC_ERO BIT4
+#define B_PCH_HDA_DEVC_URRE BIT3
+#define B_PCH_HDA_DEVC_FERE BIT2
+#define B_PCH_HDA_DEVC_NFERE BIT1
+#define B_PCH_HDA_DEVC_CERE BIT0
+#define R_PCH_HDA_DEVS 0x7A
+#define B_PCH_HDA_DEVS_TP BIT5
+#define B_PCH_HDA_DEVS_AUXPD BIT4
+#define B_PCH_HDA_DEVS_URD BIT3
+#define B_PCH_HDA_DEVS_FED BIT2
+#define B_PCH_HDA_DEVS_NFED BIT1
+#define B_PCH_HDA_DEVS_CED BIT0
+#define R_PCH_HDA_VCCAP 0x100
+#define B_PCH_HDA_VCCAP_NCO 0xFFF00000
+#define B_PCH_HDA_VCCAP_CAPVER 0x000F0000
+#define B_PCH_HDA_VCCAP_PCIEEC 0x0000FFFF
+#define R_PCH_HDA_PVCCAP1 0x104
+#define B_PCH_HDA_PVCCAP1_PATES 0x00000C00
+#define B_PCH_HDA_PVCCAP1_RC 0x00000300
+#define B_PCH_HDA_PVCCAP1_LPEVCC 0x00000070
+#define B_PCH_HDA_PVCCAP1_EVCC 0x00000007
+#define R_PCH_HDA_PVCCAP2 0x108
+#define B_PCH_HDA_PVCCAP2_VCATO 0xFF000000
+#define B_PCH_HDA_PVCCAP2_VCAC 0x000000FF
+#define R_PCH_HDA_PVCCTL 0x10C
+#define B_PCH_HDA_PVCCTL_VCAS 0x000E
+#define B_PCH_HDA_PVCCTL_LVCAT 0x0001
+#define R_PCH_HDA_PVCSTS 0x10E
+#define B_PCH_HDA_PVCSTS_VCATS 0x0001
+#define R_PCH_HDA_VC0CAP 0x110
+#define S_PCH_HDA_VC0CAP 4
+#define B_PCH_HDA_VC0CAP_PATO 0xFF000000
+#define B_PCH_HDA_VC0CAP_MTS 0x007F0000
+#define B_PCH_HDA_VC0CAP_RST BIT15
+#define B_PCH_HDA_VC0CAP_APS BIT14
+#define B_PCH_HDA_VC0CAP_PAC 0x000000FF
+#define R_PCH_HDA_VC0CTL 0x114
+#define S_PCH_HDA_VC0CTL 4
+#define B_PCH_HDA_VC0CTL_VC0EN BIT31
+#define B_PCH_HDA_VC0CTL_VC0ID 0x07000000
+#define B_PCH_HDA_VC0CTL_PAS 0x000E0000
+#define B_PCH_HDA_VC0CTL_LPAT BIT16
+#define B_PCH_HDA_VC0CTL_TCVC0_MAP 0x000000FE
+#define R_PCH_HDA_VC0STS 0x11A
+#define S_PCH_HDA_VC0STS 2
+#define B_PCH_HDA_VC0STS_VC0NP BIT1
+#define B_PCH_HDA_VC0STS_PATS BIT0
+#define R_PCH_HDA_VCICAP 0x11C
+#define S_PCH_HDA_VCICAP 4
+#define B_PCH_HDA_VCICAP_PATO 0xFF000000
+#define B_PCH_HDA_VCICAP_MTS 0x007F0000
+#define B_PCH_HDA_VCICAP_RST BIT15
+#define B_PCH_HDA_VCICAP_APS BIT14
+#define B_PCH_HDA_VCICAP_PAC 0x000000FF
+#define R_PCH_HDA_VCICTL 0x120
+#define S_PCH_HDA_VCICTL 4
+#define B_PCH_HDA_VCICTL_EN BIT31
+#define B_PCH_HDA_VCICTL_ID (BIT26 | BIT25 | BIT24)
+#define V_PCH_HDA_VCICTL_PAS 0x000E0000
+#define V_PCH_HDA_VCICTL_LPAT BIT16
+#define B_PCH_HDA_VCICTL_TCVCI_MAP 0x000000FE
+#define R_PCH_HDA_VCISTS 0x126
+#define S_PCH_HDA_VCISTS 1
+#define B_PCH_HDA_VCISTS_VCINP BIT1
+#define B_PCH_HDA_VCISTS_PATS BIT0
+#define R_PCH_HDA_RCCAP 0x130
+#define B_PCH_HDA_RCCAP_NCO 0xFFF00000
+#define B_PCH_HDA_RCCAP_CV 0x000F0000
+#define B_PCH_HDA_RCCAP_PCIEECID 0x0000FFFF
+#define R_PCH_HDA_ESD 0x134
+#define B_PCH_HDA_ESD_PN 0xFF000000
+#define B_PCH_HDA_ESD_CID 0x00FF0000
+#define B_PCH_HDA_ESD_NOLE 0x0000FF00
+#define B_PCH_HDA_ESD_ELTYP 0x0000000F
+#define R_PCH_HDA_L1DESC 0x140
+#define S_PCH_HDA_L1DESC 4
+#define B_PCH_HDA_LIDESC_TPN 0xFF000000
+#define B_PCH_HDA_LIDESC_TCID 0x00FF0000
+#define B_PCH_HDA_LIDESC_LT BIT1
+#define B_PCH_HDA_LIDESC_LV BIT0
+#define R_PCH_HDA_L1ADDL 0x148
+#define B_PCH_HDA_L1ADDL_LNK1LA 0xFFFFC000
+#define R_PCH_HDA_L1ADDU 0x14C
+#define B_PCH_HDA_L1ADDU 0xFFFFFFFF
+//
+// Intel High Definition Audio Memory Mapped Configuration Registers
+//
+#define R_HDA_GCAP 0x00
+#define S_HDA_GCAP 2
+#define B_HDA_GCAP_NOSSUP 0xF000
+#define B_HDA_GCAP_NISSUP 0x0F00
+#define B_HDA_GCAP_NBSSUP 0x00F8
+#define B_HDA_GCAP_NSDOS BIT1
+#define B_HDA_GCAP_64ADSUP BIT0
+#define R_HDA_VMIN 0x02
+#define B_HDA_VMIN_MV 0xFF
+#define R_HDA_VMAJ 0x03
+#define B_HDA_VMAJ_MV 0xFF
+#define R_HDA_OUTPAY 0x04
+#define B_HDA_OUTPAY_CAP 0x007F
+#define R_HDA_INPAY 0x06
+#define B_HDA_INPAY_CAP 0x007F
+#define R_HDA_GCTL 0x08
+#define B_HDA_GCTL_AURE BIT8
+#define B_HDA_GCTL_FC BIT1
+#define B_HDA_GCTL_CRST BIT0
+#define R_HDA_WAKEEN 0x0C
+#define B_HDA_WAKEEN_SDI_3 BIT3
+#define B_HDA_WAKEEN_SDI_2 BIT2
+#define B_HDA_WAKEEN_SDI_1 BIT1
+#define B_HDA_WAKEEN_SDI_0 BIT0
+#define R_HDA_STATESTS 0x0E
+#define B_HDA_STATESTS_SDIN3 BIT3
+#define B_HDA_STATESTS_SDIN2 BIT2
+#define B_HDA_STATESTS_SDIN1 BIT1
+#define B_HDA_STATESTS_SDIN0 BIT0
+#define R_HDA_GSTS 0x10
+#define B_HDA_GSTS_FS BIT1
+#define R_HDA_OUTSTRMPAY 0x18
+#define S_HDA_OUTSTRMPAY 2
+#define B_HDA_OUTSTRMPAY_OUTSTRMPAY 0xFFFF
+#define R_HDA_INSTRMPAY 0x1A
+#define B_HDA_INSTRMPAY_INSTRMPAY 0xFFFF
+#define R_HDA_INTCTL 0x20
+#define B_HDA_INTCTL_GIE BIT31
+#define B_HDA_INTCTL_CIE BIT30
+#define B_HDA_INTCTL_SIE_OS4 BIT7
+#define B_HDA_INTCTL_SIE_OS3 BIT6
+#define B_HDA_INTCTL_SIE_OS2 BIT5
+#define B_HDA_INTCTL_SIE_OS1 BIT4
+#define B_HDA_INTCTL_SIE_IS4 BIT3
+#define B_HDA_INTCTL_SIE_IS3 BIT2
+#define B_HDA_INTCTL_SIE_IS2 BIT1
+#define B_HDA_INTCTL_SIE_IS1 BIT0
+#define R_HDA_INTSTS 0x24
+#define B_HDA_INTSTS_GIS BIT31
+#define B_HDA_INTSTS_CIS BIT30
+#define B_HDA_INTSTS_SIS_OS4 BIT7
+#define B_HDA_INTSTS_SIS_OS3 BIT6
+#define B_HDA_INTSTS_SIS_OS2 BIT5
+#define B_HDA_INTSTS_SIS_OS1 BIT4
+#define B_HDA_INTSTS_SIS_IS4 BIT3
+#define B_HDA_INTSTS_SIS_IS3 BIT2
+#define B_HDA_INTSTS_SIS_IS2 BIT1
+#define B_HDA_INTSTS_SIS_IS1 BIT0
+#define R_HDA_WALCLK 0x30
+#define B_HDA_WALCLK_WCC 0xFFFFFFFF
+#define R_HDA_SSYNC 0x38
+#define S_HDA_SSYNC 4
+#define B_HDA_SSYNC_OS4 BIT7
+#define B_HDA_SSYNC_OS3 BIT6
+#define B_HDA_SSYNC_OS2 BIT5
+#define B_HDA_SSYNC_OS1 BIT4
+#define B_HDA_SSYNC_IS4 BIT3
+#define B_HDA_SSYNC_IS3 BIT2
+#define B_HDA_SSYNC_IS2 BIT1
+#define B_HDA_SSYNC_IS1 BIT0
+#define R_HDA_CORBLBASE 0x40
+#define B_HDA_CORBLBASE_BA 0xFFFFFF80
+#define B_HDA_CORBLBASE_UB 0x0000007F
+#define R_HDA_CORBUBASE 0x44
+#define B_HDA_CORBUBASE_BA 0xFFFFFFFF
+#define R_HDA_CORBWP 0x48
+#define B_HDA_CORBWP 0x000000FF
+#define R_HDA_CORBRP 0x4A
+#define B_HDA_CORBRP_PRST BIT15
+#define B_HDA_CORBRP_RP 0x00FF
+#define R_HDA_CORBCTL 0x4C
+#define B_HDA_CORBCTL_DMA_EN BIT1
+#define B_HDA_CORBCTL_MEMERRINTR_EN BIT0
+#define R_HDA_CORBST 0x4D
+#define B_HDA_CORBST_CMEI BIT0
+#define R_HDA_CORBSIZE 0x4E
+#define B_HDA_CORBSIZE_CAP 0xF0
+#define B_HDA_CORBSIZE_SIZE 0x03
+#define R_HDA_RIRBLBASE 0x50
+#define B_HDA_RIRBLBASE_BA 0xFFFFFF80
+#define B_HDA_RIRBLBASE_UB 0x0000007F
+#define R_HDA_RIRBUBASE 0x54
+#define B_HDA_RIRBUBASE_BA 0xFFFFFFFF
+#define R_HDA_RIRBWP 0x58
+#define B_HDA_RIRBWP_RST BIT15
+#define B_HDA_RIRBWP_WP 0x00FF
+#define R_HDA_RINTCNT 0x5A
+#define B_HDA_RINTCNT 0x00FF
+#define R_HDA_RIRBCTL 0x5C
+#define B_HDA_RIRBCTL_ROIC BIT2
+#define B_HDA_RIRBCTL_DMA BIT1
+#define B_HDA_RIRBCTL_RIC BIT0
+#define R_HDA_RIRBSTS 0x5D
+#define B_HDA_RIRBSTS_ROIS BIT2
+#define B_HDA_RIRBSTS_RI BIT0
+#define R_HDA_RIRBSIZE 0x5E
+#define B_HDA_RIRBSIZE_CAP 0xF0
+#define B_HDA_RIRBSIZE_SIZE 0x03
+#define R_HDA_IC 0x60
+#define B_HDA_IC 0xFFFFFFFF
+#define R_HDA_IR 0x64
+#define B_HDA_IR 0xFFFFFFFF
+#define R_HDA_IRS 0x68
+#define B_HDA_IRS_IRV BIT1
+#define B_HDA_IRS_ICB BIT0
+#define R_HDA_DPLBASE 0x70
+#define B_HDA_DPLBASE_LBA 0xFFFFFF80
+#define B_HDA_DPLBASE_LBU 0x0000007E
+#define B_HDA_DPLBASE_BUF_EN 0x00000001
+#define R_HDA_DPUBASE 0x74
+#define B_HDA_DPUBASE_UBA 0xFFFFFFFF
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h
new file mode 100644
index 0000000..ff91dbf
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLan.h
@@ -0,0 +1,196 @@
+/** @file
+ Register names for PCH LAN device
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_LAN_H_
+#define _PCH_REGS_LAN_H_
+
+//
+// LAN Controller Registers (D25:F0)
+//
+#define PCI_BUS_NUMBER_PCH_LAN 0
+#define PCI_DEVICE_NUMBER_PCH_LAN 25
+#define PCI_FUNCTION_NUMBER_PCH_LAN 0
+
+#define R_PCH_LAN_VENDOR_ID 0x00
+#define V_PCH_LAN_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LAN_DEVICE_ID 0x02
+#define V_PCH_LPTH_LAN_DEVICE_ID 0x8C33
+#define V_PCH_LPTLP_LAN_DEVICE_ID 0x155A
+#define R_PCH_LAN_CMD 0x04
+#define B_PCH_LAN_CMD_INTR_DIS BIT10
+#define B_PCH_LAN_CMD_FBE BIT9
+#define B_PCH_LAN_CMD_SERR_EN BIT8
+#define B_PCH_LAN_CMD_WCC BIT7
+#define B_PCH_LAN_CMD_PER BIT6
+#define B_PCH_LAN_CMD_PSE BIT5
+#define B_PCH_LAN_CMD_PMWE BIT4
+#define B_PCH_LAN_CMD_SCE BIT3
+#define B_PCH_LAN_CMD_BME BIT2
+#define B_PCH_LAN_CMD_MSE BIT1
+#define B_PCH_LAN_CMD_IOSE BIT0
+#define R_PCH_LAN_STS 0x06
+#define B_PCH_LAN_STS_DPE BIT15
+#define B_PCH_LAN_STS_SSE BIT14
+#define B_PCH_LAN_STS_RMA BIT13
+#define B_PCH_LAN_STS_RTA BIT12
+#define B_PCH_LAN_STS_STA BIT11
+#define B_PCH_LAN_STS_DEV_STS (BIT10 | BIT9)
+#define B_PCH_LAN_STS_DPED BIT8
+#define B_PCH_LAN_STS_FB2BC BIT7
+#define B_PCH_LAN_STS_66MHZ_CAP BIT5
+#define B_PCH_LAN_STS_CAP_LST BIT4
+#define B_PCH_LAN_STS_INTR_STS BIT3
+#define R_PCH_LAN_RID 0x08
+#define B_PCH_LAN_RID 0xFF
+#define R_PCH_LAN_CC 0x09
+#define S_PCH_LAN_CC 3
+#define B_PCH_LAN_CC 0xFFFFFF
+#define R_PCH_LAN_CLS 0x0C
+#define B_PCH_LAN_CLS 0xFF
+#define R_PCH_LAN_PLT 0x0D
+#define B_PCH_LAN_PLT 0xFF
+#define R_PCH_LAN_HEADTYPE 0x0E
+#define B_PCH_LAN_HEADTYPE 0xFF
+#define R_PCH_LAN_MEM_BASE_A 0x10
+#define B_PCH_LAN_MBARA_BA 0xFFFF8000
+#define B_PCH_LAN_MBARA_MSIZE 0x00007FF0
+#define B_PCH_LAN_MBARA_PM BIT3
+#define B_PCH_LAN_MBARA_MT (BIT2 | BIT1)
+#define B_PCH_LAN_MBARA_MIOS BIT0
+#define R_PCH_LAN_MBARB 0x14
+#define B_PCH_LAN_MBARB_BA 0xFFFFF000
+#define B_PCH_LAN_MBARB_MSIZE 0x00000FF0
+#define B_PCH_LAN_MBARB_PM BIT3
+#define B_PCH_LAN_MBARB_MT (BIT2 | BIT1)
+#define B_PCH_LAN_MBARB_MIOS BIT0
+#define R_PCH_LAN_MBARC 0x18
+#define B_PCH_LAN_MBARC_BA 0xFFFFFFE0
+#define B_PCH_LAN_MBARC_IOSIZE 0x0000001E
+#define B_PCH_LAN_MBARC_MIOS BIT0
+#define R_PCH_LAN_SVID 0x2C
+#define B_PCH_LAN_SVID 0xFFFF
+#define R_PCH_LAN_SID 0x2E
+#define B_PCH_LAN_SID 0xFFFF
+#define R_PCH_LAN_ERBA 0x30
+#define B_PCH_LAN_ERBA 0xFFFFFFFF
+#define R_PCH_LAN_CAP_PTR 0x34
+#define B_PCH_LAN_CAP_PTR 0xFF
+#define R_PCH_LAN_INTR 0x3C
+#define B_PCH_LAN_INTR_IPIN 0xFF00
+#define B_PCH_LAN_INTR_ILINE 0x00FF
+#define V_PCH_LAN_MEM_LENGTH 0x8000
+#define N_PCH_LAN_MEM_ALIGN 15
+#define R_PCH_LAN_LTR_CAP 0xA8
+#define R_PCH_LAN_CLIST1 0xC8
+#define B_PCH_LAN_CLIST1_NEXT 0xFF00
+#define B_PCH_LAN_CLIST1_CID 0x00FF
+#define R_PCH_LAN_PMC 0xCA
+#define B_PCH_LAN_PMC_PMES 0xF800
+#define B_PCH_LAN_PMC_D2S BIT10
+#define B_PCH_LAN_PMC_D1S BIT9
+#define B_PCH_LAN_PMC_AC (BIT8 | BIT7 | BIT6)
+#define B_PCH_LAN_PMC_DSI BIT5
+#define B_PCH_LAN_PMC_PMEC BIT3
+#define B_PCH_LAN_PMC_VS (BIT2 | BIT1 | BIT0)
+#define R_PCH_LAN_PMCS 0xCC
+#define B_PCH_LAN_PMCS_PMES BIT15
+#define B_PCH_LAN_PMCS_DSC (BIT14 | BIT13)
+#define B_PCH_LAN_PMCS_DSL 0x1E00
+#define V_PCH_LAN_PMCS_DSL0 0x0000
+#define V_PCH_LAN_PMCS_DSL3 0x0600
+#define V_PCH_LAN_PMCS_DSL4 0x0800
+#define V_PCH_LAN_PMCS_DSL7 0x0E00
+#define V_PCH_LAN_PMCS_DSL8 0x1000
+#define B_PCH_LAN_PMCS_PMEE BIT8
+#define B_PCH_LAN_PMCS_PS (BIT1 | BIT0)
+#define V_PCH_LAN_PMCS_PS0 0x00
+#define V_PCH_LAN_PMCS_PS3 0x03
+#define R_PCH_LAN_DR 0xCF
+#define B_PCH_LAN_DR 0xFF
+#define R_PCH_LAN_CLIST2 0xD0
+#define B_PCH_LAN_CLIST2_NEXT 0xFF00
+#define B_PCH_LAN_CLIST2_CID 0x00FF
+#define R_PCH_LAN_MCTL 0xD2
+#define B_PCH_LAN_MCTL_CID BIT7
+#define B_PCH_LAN_MCTL_MME (BIT6 | BIT5 | BIT4)
+#define B_PCH_LAN_MCTL_MMC (BIT3 | BIT2 | BIT1)
+#define B_PCH_LAN_MCTL_MSIE BIT0
+#define R_PCH_LAN_MADDL 0xD4
+#define B_PCH_LAN_MADDL 0xFFFFFFFF
+#define R_PCH_LAN_MADDH 0xD8
+#define B_PCH_LAN_MADDH 0xFFFFFFFF
+#define R_PCH_LAN_MDAT 0xDC
+#define B_PCH_LAN_MDAT 0xFFFFFFFF
+#define R_PCH_LAN_FLRCAP 0xE0
+#define B_PCH_LAN_FLRCAP_NEXT 0xFF00
+#define B_PCH_LAN_FLRCAP_CID 0x00FF
+#define V_PCH_LAN_FLRCAP_CID_SSEL0 0x13
+#define V_PCH_LAN_FLRCAP_CID_SSEL1 0x09
+#define R_PCH_LAN_FLRCLV 0xE2
+#define B_PCH_LAN_FLRCLV_FLRC_SSEL0 BIT9
+#define B_PCH_LAN_FLRCLV_TXP_SSEL0 BIT8
+#define B_PCH_LAN_FLRCLV_VSCID_SSEL1 0xF000
+#define B_PCH_LAN_FLRCLV_CAPVER_SSEL1 0x0F00
+#define B_PCH_LAN_FLRCLV_CAPLNG 0x00FF
+#define R_PCH_LAN_DEVCTRL 0xE4
+#define B_PCH_LAN_DEVCTRL BIT0
+//
+// Gigabit LAN Capabilities and Status Registers (Memory space)
+//
+#define R_PCH_MBARA_GBECSR1 0x0000
+#define B_PCH_MBARA_GBECSR1_PHYPDN BIT24
+#define R_PCH_MBARA_GBECSR2 0x0018
+#define B_PCH_MBARA_GBECSR2_PHYPDEN BIT20
+#define R_PCH_MBARA_GBECSR3 0x0020
+#define B_PCH_MBARA_GBECSR3_RB BIT28
+#define B_PCH_MBARA_GBECSR3_MDI_TYPE (BIT27 | BIT26)
+#define B_PCH_MBARA_GBECSR3_DATA 0x0000FFFF
+#define R_PCH_MBARA_GBECSR4 0x002C
+#define B_PCH_MBARA_GBECSR4_WIV BIT31
+#define B_PCH_MBARA_GBECSR4_WESB BIT30
+#define R_PCH_MBARA_GBECSR5 0x0F00
+#define B_PCH_MBARA_GBECSR5_SWFLAG BIT5
+#define R_PCH_MBARA_GBECSR6 0x0F10
+#define B_PCH_MBARA_GBECSR6_GGD BIT6
+#define B_PCH_MBARA_GBECSR6_GbE_DIS BIT3
+#define B_PCH_MBARA_GBECSR6_LPLUND BIT2
+#define B_PCH_MBARA_GBECSR6_LPLUD BIT1
+#define R_PCH_MBARA_GBECSR7 0x5400
+#define R_PCH_MBARA_GBECSR8 0x5404
+#define B_PCH_MBARA_GBECSR8_RAH 0x0000FFFF
+#define R_PCH_MBARA_GBECSR9 0x5800
+#define B_PCH_MBARA_GBECSR9_APME BIT0
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h
new file mode 100644
index 0000000..c922e27
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsLpc.h
@@ -0,0 +1,1018 @@
+/** @file
+ Register names for PCH LPC device
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_LPC_H_
+#define _PCH_REGS_LPC_H_
+
+//
+// PCI to LPC Bridge Registers (D31:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LPC 31
+#define PCI_FUNCTION_NUMBER_PCH_LPC 0
+
+#define PCH_HPET_BDF_MAX 8
+
+typedef enum {
+ LptHB0 = 0,
+ LptHC0,
+ LptHC1,
+ LptHC2,
+ LptLpB0,
+ LptLpB1,
+ LptLpB2,
+ PchSteppingMax
+} PCH_STEPPING;
+
+#define R_PCH_LPC_VENDOR_ID 0x00
+#define V_PCH_LPC_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LPC_DEVICE_ID 0x02
+
+//
+// LynxPoint Desktop LPC Device IDs
+//
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_SUPER_SKU 0x8C42 ///< LynxPoint Desktop Super SKU
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_0 0x8C44 ///< Intel Z87 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_1 0x8C46 ///< Intel Z85 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_2 0x8C4A ///< Intel H87 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_3 0x8C4C ///< Intel Q85 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_4 0x8C4E ///< Intel Q87 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_5 0x8C50 ///< Intel B85 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_DT_6 0x8C5C ///< Intel H81 Chipset
+
+//
+// LynxPoint Mobile LPC Device IDs
+//
+#define V_PCH_LPTH_LPC_DEVICE_ID_MB_SUPER_SKU 0x8C41 ///< LynxPoint Mobile Super SKU
+#define V_PCH_LPTH_LPC_DEVICE_ID_MB_0 0x8C49 ///< Intel HM86 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_MB_1 0x8C4B ///< Intel HM87 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_MB_2 0x8C4F ///< Intel QM87 Chipset
+
+//
+// Lynxpoint Server/WS LPC Device IDs
+//
+#define V_PCH_LPTH_LPC_DEVICE_ID_SVR_0 0x8C52 ///< Server Essential SKU Intel C222 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_SVR_1 0x8C54 ///< Server Standard SKU Intel C224 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_SVR_2 0x8C56 ///< Server Advanced SKU Intel C226 Chipset
+#define V_PCH_LPTH_LPC_DEVICE_ID_SVR_3 0x8C58 ///< WS SKU
+
+#define V_PCH_LPTLP_LPC_DEVICE_ID_UNFUSE 0x9C40 ///< LynxPoint LP Unfuse
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_SUPER_SKU 0x9C41 ///< LynxPoint LP Mobile Super SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_0 0x9C42 ///< LynxPoint LP Mobile TBD SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_1 0x9C43 ///< LynxPoint LP Mobile Premium SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_2 0x9C44 ///< LynxPoint LP Mobile TBD SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_3 0x9C45 ///< LynxPoint LP Mobile Mainstream SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_4 0x9C46 ///< LynxPoint LP Mobile TBD SKU
+#define V_PCH_LPTLP_LPC_DEVICE_ID_MB_5 0x9C47 ///< LynxPoint LP Mobile Value SKU
+
+#define R_PCH_LPC_COMMAND 0x04
+#define B_PCH_LPC_COMMAND_FBE 0x0200
+#define B_PCH_LPC_COMMAND_SERR_EN 0x0100
+#define B_PCH_LPC_COMMAND_WCC 0x0080
+#define B_PCH_LPC_COMMAND_PER 0x0040
+#define B_PCH_LPC_COMMAND_VPS 0x0020
+#define B_PCH_LPC_COMMAND_PMWE 0x0010
+#define B_PCH_LPC_COMMAND_SCE 0x0008
+#define B_PCH_LPC_COMMAND_BME 0x0004
+#define B_PCH_LPC_COMMAND_MSE 0x0002
+#define B_PCH_LPC_COMMAND_IOSE 0x0001
+#define R_PCH_LPC_DEV_STS 0x06
+#define B_PCH_LPC_DEV_STS_DPE 0x8000
+#define B_PCH_LPC_DEV_STS_SSE 0x4000
+#define B_PCH_LPC_DEV_STS_RMA 0x2000
+#define B_PCH_LPC_DEV_STS_RTA 0x1000
+#define B_PCH_LPC_DEV_STS_STA 0x0800
+#define B_PCH_LPC_DEV_STS_DEVT_STS 0x0600
+#define B_PCH_LPC_DEV_STS_MDPED 0x0100
+#define B_PCH_LPC_DEV_STS_FB2B 0x0080
+#define B_PCH_LPC_DEV_STS_UDF 0x0040
+#define B_PCH_LPC_DEV_STS_66MHZ_CAP 0x0020
+#define R_PCH_LPC_RID 0x08
+#define V_PCH_LPT_LPC_RID_0 0x00
+#define V_PCH_LPT_LPC_RID_1 0x01
+#define V_PCH_LPT_LPC_RID_2 0x02
+#define V_PCH_LPT_LPC_RID_3 0x03
+#define V_PCH_LPT_LPC_RID_4 0x04
+#define V_PCH_LPT_LPC_RID_5 0x05
+#define R_PCH_LPC_PI 0x09
+#define R_PCH_LPC_SCC 0x0A
+#define R_PCH_LPC_BCC 0x0B
+#define R_PCH_LPC_PLT 0x0D
+#define R_PCH_LPC_HEADTYP 0x0E
+#define B_PCH_LPC_HEADTYP_MFD BIT7
+#define B_PCH_LPC_HEADTYP_HT 0x7F
+#define R_PCH_LPC_SS 0x2C
+#define B_PCH_LPC_SS_SSID 0xFFFF0000
+#define B_PCH_LPC_SS_SSVID 0x0000FFFF
+#define R_PCH_LPC_ACPI_BASE 0x40
+#define B_PCH_LPC_ACPI_BASE_BAR 0xFFFC
+#define R_PCH_LPC_ACPI_CNT 0x44
+#define B_PCH_LPC_ACPI_CNT_ACPI_EN 0x80
+#define B_PCH_LPC_ACPI_CNT_SCI_IRG_SEL 0x07
+#define R_PCH_LPC_GPIO_BASE 0x48
+#define B_PCH_LPC_GPIO_BASE_BAR 0xFFFC
+#define R_PCH_LPC_GPIO_CNT 0x4C
+#define B_PCH_LPC_GPIO_CNT_GPIO_EN 0x10
+#define B_PCH_LPC_GPIO_LOCKDOWN_EN 0x01
+#define R_PCH_LPC_VLW_VBDF 0x50
+#define B_PCH_LPC_VLW_VBDF 0xFFFF
+#define R_PCH_LPC_VLW_VCTRL 0x54
+#define B_PCH_LPC_VLW_VCTRL_VCLE BIT15
+#define B_PCH_LPC_VLW_VCTRL_FERRVDMDEN BIT5
+#define B_PCH_LPC_VLW_VCTRL_NMIVMEN BIT4
+#define B_PCH_LPC_VLW_VCTRL_INITVMEN BIT3
+#define B_PCH_LPC_VLW_VCTRL_SMIVMEN BIT2
+#define B_PCH_LPC_VLW_VCTRL_INTRVMEN BIT1
+#define B_PCH_LPC_VLW_VCTRL_A20VMEN BIT0
+#define R_PCH_LPC_PIRQA_ROUT 0x60
+#define R_PCH_LPC_PIRQB_ROUT 0x61
+#define R_PCH_LPC_PIRQC_ROUT 0x62
+#define R_PCH_LPC_PIRQD_ROUT 0x63
+
+//
+// Bit values are the same for R_PCH_LPC_PIRQA_ROUT to R_PCH_LPC_PIRQH_ROUT
+//
+#define B_PCH_LPC_PIRQX_ROUT_IRQEN 0x80
+#define B_PCH_LPC_PIRQX_ROUT 0x0F
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_3 0x03
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_4 0x04
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_5 0x05
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_6 0x06
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_7 0x07
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_9 0x09
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_10 0x0A
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_11 0x0B
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_12 0x0C
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_14 0x0E
+#define V_PCH_LPC_PIRQX_ROUT_IRQ_15 0x0F
+#define R_PCH_LPC_SERIRQ_CNT 0x64
+#define B_PCH_LPC_SERIRQ_CNT_SIRQEN 0x80
+#define B_PCH_LPC_SERIRQ_CNT_SIRQMD 0x40
+#define B_PCH_LPC_SERIRQ_CNT_SIRQSZ 0x3C
+#define N_PCH_LPC_SERIRQ_CNT_SIRQSZ 2
+#define B_PCH_LPC_SERIRQ_CNT_SFPW 0x03
+#define N_PCH_LPC_SERIRQ_CNT_SFPW 0
+#define V_PCH_LPC_SERIRQ_CNT_SFPW_4CLK 0x00
+#define V_PCH_LPC_SERIRQ_CNT_SFPW_6CLK 0x01
+#define V_PCH_LPC_SERIRQ_CNT_SFPW_8CLK 0x02
+#define R_PCH_LPC_PIRQE_ROUT 0x68
+#define R_PCH_LPC_PIRQF_ROUT 0x69
+#define R_PCH_LPC_PIRQG_ROUT 0x6A
+#define R_PCH_LPC_PIRQH_ROUT 0x6B
+#define R_PCH_LPC_IOXAPIC 0x6C
+#define B_PCH_LPC_IOXAPIC_BUS 0xFF00
+#define B_PCH_LPC_IOXAPIC_DEVICE 0x00F8
+#define B_PCH_LPC_IOXAPIC_FUNC 0x0007
+#define R_PCH_LPC_HPET0 0x70
+#define B_PCH_LPC_HPET0_BUS 0xFF00
+#define B_PCH_LPC_HPET0_DEVICE 0x00F8
+#define B_PCH_LPC_HPET0_FUNC 0x0007
+#define R_PCH_LPC_HPET1 0x72
+#define B_PCH_LPC_HPET1_BUS 0xFF00
+#define B_PCH_LPC_HPET1_DEVICE 0x00F8
+#define B_PCH_LPC_HPET1_FUNC 0x0007
+#define R_PCH_LPC_HPET2 0x74
+#define B_PCH_LPC_HPET2_BUS 0xFF00
+#define B_PCH_LPC_HPET2_DEVICE 0x00F8
+#define B_PCH_LPC_HPET2_FUNC 0x0007
+#define R_PCH_LPC_HPET3 0x76
+#define B_PCH_LPC_HPET3_BUS 0xFF00
+#define B_PCH_LPC_HPET3_DEVICE 0x00F8
+#define B_PCH_LPC_HPET3_FUNC 0x0007
+#define R_PCH_LPC_HPET4 0x78
+#define B_PCH_LPC_HPET4_BUS 0xFF00
+#define B_PCH_LPC_HPET4_DEVICE 0x00F8
+#define B_PCH_LPC_HPET4_FUNC 0x0007
+#define R_PCH_LPC_HPET5 0x7A
+#define B_PCH_LPC_HPET5_BUS 0xFF00
+#define B_PCH_LPC_HPET5_DEVICE 0x00F8
+#define B_PCH_LPC_HPET5_FUNC 0x0007
+#define R_PCH_LPC_HPET6 0x7C
+#define B_PCH_LPC_HPET6_BUS 0xFF00
+#define B_PCH_LPC_HPET6_DEVICE 0x00F8
+#define B_PCH_LPC_HPET6_FUNC 0x0007
+#define R_PCH_LPC_HPET7 0x7E
+#define B_PCH_LPC_HPET7_BUS 0xFF00
+#define B_PCH_LPC_HPET7_DEVICE 0x00F8
+#define B_PCH_LPC_HPET7_FUNC 0x0007
+#define R_PCH_LPC_IO_DEC 0x80
+#define B_PCH_LPC_FDD_DEC 0x1000
+#define B_PCH_LPC_LPT_DEC 0x0300
+#define B_PCH_LPC_COMB_DEC 0x0070
+#define V_PCH_LPC_COMB_3F8 0x00
+#define V_PCH_LPC_COMB_2F8 0x10
+#define V_PCH_LPC_COMB_220 0x20
+#define V_PCH_LPC_COMB_228 0x30
+#define V_PCH_LPC_COMB_238 0x40
+#define V_PCH_LPC_COMB_2E8 0x50
+#define V_PCH_LPC_COMB_338 0x60
+#define V_PCH_LPC_COMB_3E8 0x70
+#define B_PCH_LPC_COMA_DEC 0x0007
+#define V_PCH_LPC_COMA_3F8 0x00
+#define V_PCH_LPC_COMA_2F8 0x01
+#define V_PCH_LPC_COMA_220 0x02
+#define V_PCH_LPC_COMA_228 0x03
+#define V_PCH_LPC_COMA_238 0x04
+#define V_PCH_LPC_COMA_2E8 0x05
+#define V_PCH_LPC_COMA_338 0x06
+#define V_PCH_LPC_COMA_3E8 0x07
+#define R_PCH_LPC_ENABLES 0x82
+#define B_PCH_LPC_ENABLES_CNF2_EN 0x2000
+#define B_PCH_LPC_ENABLES_CNF1_EN 0x1000
+#define B_PCH_LPC_ENABLES_MC_EN 0x0800
+#define B_PCH_LPC_ENABLES_KBC_EN 0x0400
+#define B_PCH_LPC_ENABLES_GAMEH_EN 0x0200
+#define B_PCH_LPC_ENABLES_GAMEL_EN 0x0100
+#define B_PCH_LPC_ENABLES_FDD_EN 0x0008
+#define B_PCH_LPC_ENABLES_LPT_EN 0x0004
+#define B_PCH_LPC_ENABLES_COMB_EN 0x0002
+#define B_PCH_LPC_ENABLES_COMA_EN 0x0001
+#define R_PCH_LPC_GEN1_DEC 0x84
+#define B_PCH_LPC_GEN1_DEC_IODRA 0x00FC0000
+#define B_PCH_LPC_GEN1_DEC_IOBAR 0x0000FFFC
+#define B_PCH_LPC_GEN1_DEC_EN 0x00000001
+#define R_PCH_LPC_GEN2_DEC 0x88
+#define R_PCH_LPC_GEN3_DEC 0x8C
+#define R_PCH_LPC_GEN4_DEC 0x90
+#define R_PCH_LPC_ULKMC 0x94
+#define B_PCH_LPC_ULKMC_SMIBYENDPS BIT15
+#define B_PCH_LPC_ULKMC_TRAPBY64W BIT11
+#define B_PCH_LPC_ULKMC_TRAPBY64R BIT10
+#define B_PCH_LPC_ULKMC_TRAPBY60W BIT9
+#define B_PCH_LPC_ULKMC_TRAPBY60R BIT8
+#define B_PCH_LPC_ULKMC_SMIATENDPS BIT7
+#define B_PCH_LPC_ULKMC_PSTATE BIT6
+#define B_PCH_LPC_ULKMC_A20PASSEN BIT5
+#define B_PCH_LPC_ULKMC_USBSMIEN BIT4
+#define B_PCH_LPC_ULKMC_64WEN BIT3
+#define B_PCH_LPC_ULKMC_64REN BIT2
+#define B_PCH_LPC_ULKMC_60WEN BIT1
+#define B_PCH_LPC_ULKMC_60REN BIT0
+#define R_PCH_LPC_LGMR 0x98
+#define B_PCH_LPC_LGMR_MA 0xFFFF0000
+#define B_PCH_LPC_LGMR_LMRD_EN BIT0
+
+#define R_PCH_LPC_FWH_BIOS_SEL 0xD0
+#define B_PCH_LPC_FWH_BIOS_SEL_F8 0xF0000000
+#define B_PCH_LPC_FWH_BIOS_SEL_F0 0x0F000000
+#define B_PCH_LPC_FWH_BIOS_SEL_E8 0x00F00000
+#define B_PCH_LPC_FWH_BIOS_SEL_E0 0x000F0000
+#define B_PCH_LPC_FWH_BIOS_SEL_D8 0x0000F000
+#define B_PCH_LPC_FWH_BIOS_SEL_D0 0x00000F00
+#define B_PCH_LPC_FWH_BIOS_SEL_C8 0x000000F0
+#define B_PCH_LPC_FWH_BIOS_SEL_C0 0x0000000F
+#define R_PCH_LPC_FWH_BIOS_SEL2 0xD4
+#define B_PCH_LPC_FWH_BIOS_SEL2_70 0xF000
+#define B_PCH_LPC_FWH_BIOS_SEL2_60 0x0F00
+#define B_PCH_LPC_FWH_BIOS_SEL2_50 0x00F0
+#define B_PCH_LPC_FWH_BIOS_SEL2_40 0x000F
+#define R_PCH_LPC_FWH_BIOS_DEC 0xD8
+#define B_PCH_LPC_FWH_BIOS_DEC_F8 0x8000
+#define B_PCH_LPC_FWH_BIOS_DEC_F0 0x4000
+#define B_PCH_LPC_FWH_BIOS_DEC_E8 0x2000
+#define B_PCH_LPC_FWH_BIOS_DEC_E0 0x1000
+#define B_PCH_LPC_FWH_BIOS_DEC_D8 0x0800
+#define B_PCH_LPC_FWH_BIOS_DEC_D0 0x0400
+#define B_PCH_LPC_FWH_BIOS_DEC_C8 0x0200
+#define B_PCH_LPC_FWH_BIOS_DEC_C0 0x0100
+#define B_PCH_LPC_FWH_BIOS_LEG_F 0x0080
+#define B_PCH_LPC_FWH_BIOS_LEG_E 0x0040
+#define B_PCH_LPC_FWH_BIOS_DEC_70 0x0008
+#define B_PCH_LPC_FWH_BIOS_DEC_60 0x0004
+#define B_PCH_LPC_FWH_BIOS_DEC_50 0x0002
+#define B_PCH_LPC_FWH_BIOS_DEC_40 0x0001
+#define R_PCH_LPC_BIOS_CNTL 0xDC
+#define S_PCH_LPC_BIOS_CNTL 1
+#define B_PCH_LPC_BIOS_CNTL_SMM_BWP 0x20 ///< SMM BIOS write protect disable
+#define B_PCH_LPC_BIOS_CNTL_TSS 0x10
+#define V_PCH_LPC_BIOS_CNTL_SRC 0x0C
+#define V_PCH_SRC_PREF_EN_CACHE_EN 0x08
+#define V_PCH_SRC_PREF_DIS_CACHE_DIS 0x04
+#define V_PCH_SRC_PREF_DIS_CACHE_EN 0x00
+#define B_PCH_LPC_BIOS_CNTL_BLE 0x02
+#define B_PCH_LPC_BIOS_CNTL_BIOSWE 0x01
+#define N_PCH_LPC_BIOS_CNTL_BLE 1
+#define N_PCH_LPC_BIOS_CNTL_BIOSWE 0
+#define R_PCH_LPC_FDCAP 0xE0
+#define B_PCH_LPC_FDCAP_NEXT 0xFF00
+#define B_PCH_LPC_FDCAP_CID 0x00FF
+#define R_PCH_LPC_FDLEN 0xE2
+#define B_PCH_LPC_FDLEN 0xFF
+#define R_PCH_LPC_FDVER 0xE3
+#define B_PCH_LPC_FDVER_VSCID 0xF0
+#define B_PCH_LPC_FDVER_CV 0x0F
+#define R_PCH_LPC_FVECIDX 0xE4
+#define B_PCH_LPC_FVECIDX_IDX 0x0000003C
+#define R_PCH_LPC_FVECD 0xE8
+#define R_PCH_LPC_FVEC0 0x00
+#define B_PCH_LPC_FVEC0_USB_PORT_CAP 0x00000C00
+#define V_PCH_LPC_FVEC0_USB_14_PORT 0x00000000
+#define V_PCH_LPC_FVEC0_USB_12_PORT 0x00000400
+#define V_PCH_LPC_FVEC0_USB_10_PORT 0x00000800
+#define B_PCH_LPC_FVEC0_SATA_RAID_CAP 0x00000080
+#define B_PCH_LPC_FVEC0_SATA_PORT23_CAP 0x00000040
+#define B_PCH_LPC_FVEC0_SATA_PORT1_6GB_CAP 0x00000008
+#define B_PCH_LPC_FVEC0_SATA_PORT0_6GB_CAP 0x00000004
+#define B_PCH_LPC_FVEC0_PCI_CAP 0x00000002
+#define R_PCH_LPC_FVEC1 0x01
+#define B_PCH_LPC_FVEC1_USB_R_CAP 0x00400000
+#define R_PCH_LPC_FVEC2 0x02
+#define B_PCH_LPC_FVEC2_IATT_CAP 0x00400000 ///< Intel Anti-Theft Technology Capability
+#define V_PCH_LPC_FVEC2_PCIE_PORT78_CAP 0x00200000
+#define V_PCH_LPC_FVEC2_PCH_IG_SUPPORT_CAP 0x00020000 ///< PCH Integrated Graphics Support Capability
+#define R_PCH_LPC_FVEC3 0x03
+#define B_PCH_LPC_FVEC3_DCMI_CAP 0x00002000 ///< Data Center Manageability Interface (DCMI) Capability
+#define B_PCH_LPC_FVEC3_NM_CAP 0x00001000 ///< Node Manager Capability
+#define R_PCH_LPC_RCBA 0xF0
+#define B_PCH_LPC_RCBA_BAR 0xFFFFC000
+#define B_PCH_LPC_RCBA_EN 0x00000001
+
+#define R_PCH_LPC_GEN_PMCON_1 0xA0
+#define B_PCH_LPC_GEN_PMCON_PER_SMI_SEL 0x0003
+#define V_PCH_LPC_GEN_PMCON_PER_SMI_64S 0x0000
+#define V_PCH_LPC_GEN_PMCON_PER_SMI_32S 0x0001
+#define V_PCH_LPC_GEN_PMCON_PER_SMI_16S 0x0002
+#define V_PCH_LPC_GEN_PMCON_PER_SMI_8S 0x0003
+#define B_PCH_LPC_GEN_PMCON_CLKRUN_EN 0x0004
+#define B_PCH_LPC_GEN_PMCON_PSEUDO_CLKRUN_EN 0x0008
+#define B_PCH_LPC_GEN_PMCON_SMI_LOCK 0x0010
+#define B_PCH_LPC_GEN_PMCON_PWRBTN_LVL 0x0200
+#define B_PCH_LPC_GEN_PMCON_BIOS_PCI_EXP_EN 0x0400
+#define B_PCH_LPC_GEN_PMCON_REQ_CLKRUN_BBCLKGATE 0x0800
+#define B_PCH_LPC_GEN_PMCON_ALLOW_SPXB_CG_INC0 0x1000
+#define B_PCH_LPC_GEN_PMCON_ALLOW_PLL_SD_INC0 0x2000
+#define R_PCH_LPC_GEN_PMCON_2 0xA2
+#define B_PCH_LPC_GEN_PMCON_PWROK_FLR 0x01
+#define B_PCH_LPC_GEN_PMCON_SYSPWR_FLR 0x02
+#define B_PCH_LPC_GEN_PMCON_MIN_SLP_S4 0x04
+#define B_PCH_LPC_GEN_PMCON_CTS 0x08
+#define B_PCH_LPC_GEN_PMCON_SRS 0x10
+#define B_PCH_LPC_GEN_PMCON_MEM_SR 0x20
+#define B_PCH_LPC_GEN_PMCON_DRAM_INIT 0x80
+#define B_PCH_LPC_GEN_PMCON_SX_PP_EN 0x0800
+#define B_PCH_LPC_GEN_PMCON_AG3_PP_EN 0x1000
+#define B_PCH_LPC_GEN_PMCON_DSX_PP_DIS 0x2000
+#define B_PCH_LPC_GEN_PMCON_DC_PP_DIS 0x4000
+#define R_PCH_LPC_GEN_PMCON_3 0xA4
+#define B_PCH_LPC_GEN_PMCON_PME_B0_S5_DIS BIT15
+#define B_PCH_LPC_GEN_PMCON_SUS_PWR_FLR BIT14
+#define B_PCH_LPC_GEN_PMCON_WOL_ENABLE_OVERRIDE BIT13
+#define B_PCH_LPC_GEN_PMCON_DISABLE_SX_STRETCH BIT12
+#define B_PCH_LPC_GEN_PMCON_SLP_S3_MAW 0xC00
+#define V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_60US 0x000
+#define V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_1MS 0x400
+#define V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_50MS 0x800
+#define V_PCH_LPC_GEN_PMCON_SLP_S3_MAW_2S 0xC00
+#define B_PCH_LPC_GEN_PMCON_GEN_RST_STS BIT9
+#define B_PCH_LPC_GEN_PMCON_SWSMI_RTSL 0xC0
+#define V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_64MS 0xC0
+#define V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_32MS 0x80
+#define V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_16MS 0x40
+#define V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_1_5MS 0x00
+#define B_PCH_LPC_GEN_PMCON_SLP_S4_MAW 0x30
+#define V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_1S 0x30
+#define V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_2S 0x20
+#define V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_3S 0x10
+#define V_PCH_LPC_GEN_PMCON_SLP_S4_MAW_4S 0x00
+#define B_PCH_LPC_GEN_PMCON_SLP_S4_ASE 0x08
+#define B_PCH_LPC_GEN_PMCON_RTC_PWR_STS 0x04
+#define B_PCH_LPC_GEN_PMCON_PWR_FLR 0x02
+#define B_PCH_LPC_GEN_PMCON_AFTERG3_EN 0x01
+#define R_PCH_LPC_GEN_PMCON_LOCK 0xA6
+#define B_PCH_LPC_GEN_PMCON_LOCK_S4_STRET_LD BIT2 ///< Lock down SLP_S3/SLP_S4 Minimum Assertion width
+#define B_PCH_LPC_GEN_PMCON_LOCK_ABASE_LK BIT1 ///< Lock ACPI BASE at 0x40, only cleared by reset when set
+#define R_PCH_LPC_CIR4 0xA9 ///< Chipset Initialization Register 4
+#define R_PCH_LPC_BM_BREAK_EN2 0xAA
+#define B_PCH_LPC_BM_BREAK_EN2_SATA3 BIT0
+#define R_PCH_LPC_BM_BREAK_EN 0xAB
+#define B_PCH_LPC_BM_BREAK_EN_STORAGE BIT7
+#define B_PCH_LPC_BM_BREAK_EN_PCIE BIT6
+#define B_PCH_LPC_BM_BREAK_EN_EHCI BIT2
+#define B_PCH_LPC_BM_BREAK_EN_HDA BIT0
+#define R_PCH_LPC_PMIR 0xAC
+#define B_PCH_LPC_PMIR_CF9LOCK BIT31 ///< CF9h Lockdown
+#define B_PCH_LPC_PMIR_CF9GR BIT20 ///< CF9h Global Reset
+#define B_PCH_LPC_PMIR_SKIP_HOST_RST_HS BIT19
+
+#define R_PCH_LPC_GPI_ROUT 0xB8
+#define B_PCH_LPC_GPI_ROUT_0 (BIT1 | BIT0)
+#define B_PCH_LPC_GPI_ROUT_1 (BIT3 | BIT2)
+#define B_PCH_LPC_GPI_ROUT_2 (BIT5 | BIT4)
+#define B_PCH_LPC_GPI_ROUT_3 (BIT7 | BIT6)
+#define B_PCH_LPC_GPI_ROUT_4 (BIT9 | BIT8)
+#define B_PCH_LPC_GPI_ROUT_5 (BIT11 | BIT10)
+#define B_PCH_LPC_GPI_ROUT_6 (BIT13 | BIT12)
+#define B_PCH_LPC_GPI_ROUT_7 (BIT15 | BIT14)
+#define B_PCH_LPC_GPI_ROUT_8 (BIT17 | BIT16)
+#define B_PCH_LPC_GPI_ROUT_9 (BIT19 | BIT18)
+#define B_PCH_LPC_GPI_ROUT_10 (BIT21 | BIT20)
+#define B_PCH_LPC_GPI_ROUT_11 (BIT23 | BIT22)
+#define B_PCH_LPC_GPI_ROUT_12 (BIT25 | BIT24)
+#define B_PCH_LPC_GPI_ROUT_13 (BIT27 | BIT26)
+#define B_PCH_LPC_GPI_ROUT_14 (BIT29 | BIT28)
+#define B_PCH_LPC_GPI_ROUT_15 (BIT31 | BIT30)
+
+#define R_PCH_LPC_GPI_ROUT2 0xBC
+#define B_PCH_LPC_GPI_ROUT2_17 (BIT1 | BIT0)
+#define B_PCH_LPC_GPI_ROUT2_19 (BIT3 | BIT2)
+#define B_PCH_LPC_GPI_ROUT2_21 (BIT5 | BIT4)
+#define B_PCH_LPC_GPI_ROUT2_22 (BIT7 | BIT6)
+#define B_PCH_LPC_GPI_ROUT2_43 (BIT9 | BIT8)
+#define B_PCH_LPC_GPI_ROUT2_56 (BIT11 | BIT10)
+#define B_PCH_LPC_GPI_ROUT2_57 (BIT13 | BIT12)
+#define B_PCH_LPC_GPI_ROUT2_60 (BIT15 | BIT14)
+
+#define R_PCH_LP_LPC_GPI_ROUT0 0x30
+#define R_PCH_LP_LPC_GPI_ROUT1 0x34
+#define R_PCH_LP_LPC_GPI_ROUT2 0x38
+
+#define R_PCH_LPC_MDAP 0xC0
+#define B_PCH_LPC_MDAP_POLICY_EN BIT31
+#define B_PCH_LPC_MDAP_PDMA_EN BIT30
+#define B_PCH_LPC_MDAP_VALUE 0x0001FFFF
+//
+// APM Registers
+//
+#define R_PCH_APM_CNT 0xB2
+#define R_PCH_APM_STS 0xB3
+
+//
+// ACPI and legacy I/O register offsets from PMBASE
+//
+#define R_PCH_ACPI_PM1_STS 0x00
+#define S_PCH_ACPI_PM1_STS 2
+#define B_PCH_ACPI_PM1_STS_WAK 0x8000
+#define B_PCH_ACPI_PM1_STS_PRBTNOR 0x0800
+#define B_PCH_ACPI_PM1_STS_RTC 0x0400
+#define B_PCH_ACPI_PM1_STS_PWRBTN 0x0100
+#define B_PCH_ACPI_PM1_STS_GBL 0x0020
+#define B_PCH_ACPI_PM1_STS_BM 0x0010
+#define B_PCH_ACPI_PM1_STS_TMROF 0x0001
+#define N_PCH_ACPI_PM1_STS_WAK 15
+#define N_PCH_ACPI_PM1_STS_PRBTNOR 11
+#define N_PCH_ACPI_PM1_STS_RTC 10
+#define N_PCH_ACPI_PM1_STS_PWRBTN 8
+#define N_PCH_ACPI_PM1_STS_GBL 5
+#define N_PCH_ACPI_PM1_STS_BM 4
+#define N_PCH_ACPI_PM1_STS_TMROF 0
+
+#define R_PCH_ACPI_PM1_EN 0x02
+#define S_PCH_ACPI_PM1_EN 2
+#define B_PCH_ACPI_PM1_EN_RTC 0x0400
+#define B_PCH_ACPI_PM1_EN_PWRBTN 0x0100
+#define B_PCH_ACPI_PM1_EN_GBL 0x0020
+#define B_PCH_ACPI_PM1_EN_TMROF 0X0001
+#define N_PCH_ACPI_PM1_EN_RTC 10
+#define N_PCH_ACPI_PM1_EN_PWRBTN 8
+#define N_PCH_ACPI_PM1_EN_GBL 5
+#define N_PCH_ACPI_PM1_EN_TMROF 0
+
+#define R_PCH_ACPI_PM1_CNT 0x04
+#define S_PCH_ACPI_PM1_CNT 4
+#define B_PCH_ACPI_PM1_CNT_SLP_EN 0x00002000
+#define B_PCH_ACPI_PM1_CNT_SLP_TYP 0x00001C00
+#define V_PCH_ACPI_PM1_CNT_S0 0x00000000
+#define V_PCH_ACPI_PM1_CNT_S1 0x00000400
+#define V_PCH_ACPI_PM1_CNT_S3 0x00001400
+#define V_PCH_ACPI_PM1_CNT_S4 0x00001800
+#define V_PCH_ACPI_PM1_CNT_S5 0x00001C00
+#define B_PCH_ACPI_PM1_CNT_GBL_RLS 0x00000004
+#define B_PCH_ACPI_PM1_CNT_BM_RLD 0x00000002
+#define B_PCH_ACPI_PM1_CNT_SCI_EN 0x00000001
+
+#define R_PCH_ACPI_PM1_TMR 0x08
+#define V_PCH_ACPI_TMR_FREQUENCY 3579545
+#define B_PCH_ACPI_PM1_TMR_VAL 0xFFFFFF
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL 0x1000000 ///< The timer is 24 bit overflow
+
+#define R_PCH_ACPI_GPE0_STS_127_96 0x8C
+#define S_PCH_ACPI_GPE0_STS_127_96 4
+#define B_PCH_ACPI_GPE0_STS_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_STS_127_96_GP27 BIT16
+#define B_PCH_ACPI_GPE0_STS_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_STS_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_STS_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_STS_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_STS_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK BIT7
+#define B_PCH_ACPI_GPE0_STS_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_STS_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_STS_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_STS_127_96_PME 11
+#define N_PCH_ACPI_GPE0_STS_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_STS_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_STS_127_96_RI 8
+#define N_PCH_ACPI_GPE0_STS_127_96_SMB_WAK 7
+#define N_PCH_ACPI_GPE0_STS_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_STS_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0_EN_127_96 0x9C
+#define S_PCH_ACPI_GPE0_EN_127_96 4
+#define B_PCH_ACPI_GPE0_EN_127_96_WADT BIT18
+#define B_PCH_ACPI_GPE0_EN_127_96_GP27 BIT16
+#define B_PCH_ACPI_GPE0_EN_127_96_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0_EN_127_96_ME_SCI BIT12
+#define B_PCH_ACPI_GPE0_EN_127_96_PME BIT11
+#define B_PCH_ACPI_GPE0_EN_127_96_BATLOW BIT10
+#define B_PCH_ACPI_GPE0_EN_127_96_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0_EN_127_96_RI BIT8
+#define B_PCH_ACPI_GPE0_EN_127_96_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0_EN_127_96_SWGPE BIT2
+#define B_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0_EN_127_96_PME_B0 13
+#define N_PCH_ACPI_GPE0_EN_127_96_USB3 12
+#define N_PCH_ACPI_GPE0_EN_127_96_PME 11
+#define N_PCH_ACPI_GPE0_EN_127_96_BATLOW 10
+#define N_PCH_ACPI_GPE0_EN_127_96_PCI_EXP 9
+#define N_PCH_ACPI_GPE0_EN_127_96_RI 8
+#define N_PCH_ACPI_GPE0_EN_127_96_TC0SCI 6
+#define N_PCH_ACPI_GPE0_EN_127_96_SWGPE 2
+#define N_PCH_ACPI_GPE0_EN_127_96_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0a_STS 0x20
+#define S_PCH_ACPI_GPE0a_STS 4
+#define B_PCH_ACPI_GPE0a_STS_GPInn 0xFFFF0000
+#define B_PCH_ACPI_GPE0a_STS_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0a_STS_PME BIT11
+#define B_PCH_ACPI_GPE0a_STS_BATLOW BIT10
+#define B_PCH_ACPI_GPE0a_STS_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0a_STS_RI BIT8
+#define B_PCH_ACPI_GPE0a_STS_SMB_WAK BIT7
+#define B_PCH_ACPI_GPE0a_STS_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0a_STS_SWGPE BIT2
+#define B_PCH_ACPI_GPE0a_STS_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0a_STS_PME_B0 13
+#define N_PCH_ACPI_GPE0a_STS_PME 11
+#define N_PCH_ACPI_GPE0a_STS_BATLOW 10
+#define N_PCH_ACPI_GPE0a_STS_PCI_EXP 9
+#define N_PCH_ACPI_GPE0a_STS_RI 8
+#define N_PCH_ACPI_GPE0a_STS_SMB_WAK 7
+#define N_PCH_ACPI_GPE0a_STS_TC0SCI 6
+#define N_PCH_ACPI_GPE0a_STS_SWGPE 2
+#define N_PCH_ACPI_GPE0a_STS_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0b_STS 0x24
+#define S_PCH_ACPI_GPE0b_STS 4
+#define B_PCH_ACPI_GPE0b_STS_GP60 BIT31
+#define B_PCH_ACPI_GPE0b_STS_GP57 BIT30
+#define B_PCH_ACPI_GPE0b_STS_GP56 BIT29
+#define B_PCH_ACPI_GPE0b_STS_GP43 BIT28
+#define B_PCH_ACPI_GPE0b_STS_GP22 BIT27
+#define B_PCH_ACPI_GPE0b_STS_GP21 BIT26
+#define B_PCH_ACPI_GPE0b_STS_GP19 BIT25
+#define B_PCH_ACPI_GPE0b_STS_GP17 BIT24
+#define B_PCH_ACPI_GPE0b_STS_WADT BIT6
+#define B_PCH_ACPI_GPE0b_STS_ME_SCI BIT4
+#define B_PCH_ACPI_GPE0b_STS_GP27 BIT3
+
+#define R_PCH_ACPI_GPE0a_EN 0x28
+#define S_PCH_ACPI_GPE0a_EN 4
+#define B_PCH_ACPI_GPE0a_EN_GPInn 0xFFFF0000
+#define B_PCH_ACPI_GPE0a_EN_PME_B0 BIT13
+#define B_PCH_ACPI_GPE0a_EN_PME BIT11
+#define B_PCH_ACPI_GPE0a_EN_BATLOW BIT10
+#define B_PCH_ACPI_GPE0a_EN_PCI_EXP BIT9
+#define B_PCH_ACPI_GPE0a_EN_RI BIT8
+#define B_PCH_ACPI_GPE0a_EN_TC0SCI BIT6
+#define B_PCH_ACPI_GPE0a_EN_SWGPE BIT2
+#define B_PCH_ACPI_GPE0a_EN_HOT_PLUG BIT1
+#define N_PCH_ACPI_GPE0a_EN_USB4 14
+#define N_PCH_ACPI_GPE0a_EN_PME_B0 13
+#define N_PCH_ACPI_GPE0a_EN_USB3 12
+#define N_PCH_ACPI_GPE0a_EN_PME 11
+#define N_PCH_ACPI_GPE0a_EN_BATLOW 10
+#define N_PCH_ACPI_GPE0a_EN_PCI_EXP 9
+#define N_PCH_ACPI_GPE0a_EN_RI 8
+#define N_PCH_ACPI_GPE0a_EN_TC0SCI 6
+#define N_PCH_ACPI_GPE0a_EN_SWGPE 2
+#define N_PCH_ACPI_GPE0a_EN_HOT_PLUG 1
+
+#define R_PCH_ACPI_GPE0b_EN 0x2C
+#define S_PCH_ACPI_GPE0b_EN 4
+#define B_PCH_ACPI_GPE0b_EN_GP60 BIT31
+#define B_PCH_ACPI_GPE0b_EN_GP57 BIT30
+#define B_PCH_ACPI_GPE0b_EN_GP56 BIT29
+#define B_PCH_ACPI_GPE0b_EN_GP43 BIT28
+#define B_PCH_ACPI_GPE0b_EN_GP22 BIT27
+#define B_PCH_ACPI_GPE0b_EN_GP21 BIT26
+#define B_PCH_ACPI_GPE0b_EN_GP19 BIT25
+#define B_PCH_ACPI_GPE0b_EN_GP17 BIT24
+#define B_PCH_ACPI_GPE0b_EN_WADT BIT6
+#define B_PCH_ACPI_GPE0b_EN_ME_SCI BIT4
+#define B_PCH_ACPI_GPE0b_EN_GP27 BIT3
+
+#define R_PCH_SMI_EN 0x30
+#define S_PCH_SMI_EN 4
+#define B_PCH_SMI_EN_LEGACY_USB3 BIT31
+#define B_PCH_SMI_EN_GPIO_UNLOCK_SMI BIT27
+#define B_PCH_SMI_EN_INTEL_USB2 BIT18
+#define B_PCH_SMI_EN_LEGACY_USB2 BIT17
+#define B_PCH_SMI_EN_PERIODIC BIT14
+#define B_PCH_SMI_EN_TCO BIT13
+#define B_PCH_SMI_EN_MCSMI BIT11
+#define B_PCH_SMI_EN_BIOS_RLS BIT7
+#define B_PCH_SMI_EN_SWSMI_TMR BIT6
+#define B_PCH_SMI_EN_APMC BIT5
+#define B_PCH_SMI_EN_ON_SLP_EN BIT4
+#define B_PCH_SMI_EN_LEGACY_USB BIT3
+#define B_PCH_SMI_EN_BIOS BIT2
+#define B_PCH_SMI_EN_EOS BIT1
+#define B_PCH_SMI_EN_GBL_SMI BIT0
+#define N_PCH_SMI_EN_LEGACY_USB3 31
+#define N_PCH_SMI_EN_GPIO_UNLOCK 27
+#define N_PCH_SMI_EN_INTEL_USB2 18
+#define N_PCH_SMI_EN_LEGACY_USB2 17
+#define N_PCH_SMI_EN_PERIODIC 14
+#define N_PCH_SMI_EN_TCO 13
+#define N_PCH_SMI_EN_MCSMI 11
+#define N_PCH_SMI_EN_BIOS_RLS 7
+#define N_PCH_SMI_EN_SWSMI_TMR 6
+#define N_PCH_SMI_EN_APMC 5
+#define N_PCH_SMI_EN_ON_SLP_EN 4
+#define N_PCH_SMI_EN_LEGACY_USB 3
+#define N_PCH_SMI_EN_BIOS 2
+#define N_PCH_SMI_EN_EOS 1
+#define N_PCH_SMI_EN_GBL_SMI 0
+
+#define R_PCH_SMI_STS 0x34
+#define S_PCH_SMI_STS 4
+#define B_PCH_SMI_STS_LEGACY_USB3 BIT31
+#define B_PCH_SMI_STS_GPIO_UNLOCK BIT27
+#define B_PCH_SMI_STS_SPI BIT26
+#define B_PCH_SMI_STS_MONITOR BIT21
+#define B_PCH_SMI_STS_PCI_EXP BIT20
+#define B_PCH_SMI_STS_PATCH BIT19
+#define B_PCH_SMI_STS_INTEL_USB2 BIT18
+#define B_PCH_SMI_STS_LEGACY_USB2 BIT17
+#define B_PCH_SMI_STS_SMBUS BIT16
+#define B_PCH_SMI_STS_SERIRQ BIT15
+#define B_PCH_SMI_STS_PERIODIC BIT14
+#define B_PCH_SMI_STS_TCO BIT13
+#define B_PCH_SMI_STS_DEVMON BIT12
+#define B_PCH_SMI_STS_MCSMI BIT11
+#define B_PCH_SMI_STS_GPIO_SMI BIT10
+#define B_PCH_SMI_STS_GPE1 BIT10
+#define B_PCH_SMI_STS_GPE0 BIT9
+#define B_PCH_SMI_STS_PM1_STS_REG BIT8
+#define B_PCH_SMI_STS_SWSMI_TMR BIT6
+#define B_PCH_SMI_STS_APM BIT5
+#define B_PCH_SMI_STS_ON_SLP_EN BIT4
+#define B_PCH_SMI_STS_LEGACY_USB BIT3
+#define B_PCH_SMI_STS_BIOS BIT2
+#define N_PCH_SMI_STS_LEGACY_USB3 31
+#define N_PCH_SMI_STS_GPIO_UNLOCK 27
+#define N_PCH_SMI_STS_SPI 26
+#define N_PCH_SMI_STS_MONITOR 21
+#define N_PCH_SMI_STS_PCI_EXP 20
+#define N_PCH_SMI_STS_PATCH 19
+#define N_PCH_SMI_STS_INTEL_USB2 18
+#define N_PCH_SMI_STS_LEGACY_USB2 17
+#define N_PCH_SMI_STS_SMBUS 16
+#define N_PCH_SMI_STS_SERIRQ 15
+#define N_PCH_SMI_STS_PERIODIC 14
+#define N_PCH_SMI_STS_TCO 13
+#define N_PCH_SMI_STS_DEVMON 12
+#define N_PCH_SMI_STS_MCSMI 11
+#define N_PCH_SMI_STS_GPE1 10
+#define N_PCH_SMI_STS_GPE0 9
+#define N_PCH_SMI_STS_PM1_STS_REG 8
+#define N_PCH_SMI_STS_SWSMI_TMR 6
+#define N_PCH_SMI_STS_APM 5
+#define N_PCH_SMI_STS_ON_SLP_EN 4
+#define N_PCH_SMI_STS_LEGACY_USB 3
+#define N_PCH_SMI_STS_BIOS 2
+
+#define R_PCH_LPTH_ALT_GP_SMI_EN 0x38
+#define S_PCH_LPTH_ALT_GP_SMI_EN 2
+#define R_PCH_LPTH_ALT_GP_SMI_STS 0x3A
+#define S_PCH_LPTH_ALT_GP_SMI_STS 2
+#define V_PCH_LPTH_ALT_GP_SMI_GPIBASE 0
+#define S_PCH_LPTH_ALT_GP_SMI_GPISIZE 16
+
+#define R_PCH_LPTLP_ALT_GP_SMI_EN 0x54
+#define S_PCH_LPTLP_ALT_GP_SMI_EN 4
+#define R_PCH_LPTLP_ALT_GP_SMI_STS 0x50
+#define S_PCH_LPTLP_ALT_GP_SMI_STS 4
+#define V_PCH_LPTLP_ALT_GP_SMI_GPIBASE 32
+#define S_PCH_LPTLP_ALT_GP_SMI_GPISIZE 16
+
+//
+// USB Per-Port Registers Write Control
+//
+#define R_PCH_UPRWC 0x3C
+#define S_PCH_UPRWC 2
+#define B_PCH_UPRWC_WR_EN_SMI_STS 0x0100
+#define B_PCH_UPRWC_WR_EN 0x0002
+#define B_PCH_UPRWC_WR_EN_SMI_EN 0x0001
+
+#define R_PCH_ACPI_GPE_CNTL 0x42
+#define B_PCH_ACPI_GPE_CNTL_SWGPE_CTRL BIT1
+
+#define R_PCH_DEVACT_STS 0x44
+#define S_PCH_DEVACT_STS 2
+#define B_PCH_DEVACT_STS_MASK 0x13E1
+#define B_PCH_DEVACT_STS_KBC 0x1000
+#define B_PCH_DEVACT_STS_PIRQDH 0x0200
+#define B_PCH_DEVACT_STS_PIRQCG 0x0100
+#define B_PCH_DEVACT_STS_PIRQBF 0x0080
+#define B_PCH_DEVACT_STS_PIRQAE 0x0040
+#define N_PCH_DEVACT_STS_KBC 12
+#define N_PCH_DEVACT_STS_PIRQDH 9
+#define N_PCH_DEVACT_STS_PIRQCG 8
+#define N_PCH_DEVACT_STS_PIRQBF 7
+#define N_PCH_DEVACT_STS_PIRQAE 6
+
+#define R_PCH_ACPI_PM2_CNT 0x50
+#define B_PCH_ACPI_PM2_CNT_ARB_DIS 0x01
+
+#define R_PCH_OC_WDT_CTL 0x54
+#define B_PCH_OC_WDT_CTL_RLD BIT31
+#define B_PCH_OC_WDT_CTL_ICCSURV_STS BIT25
+#define B_PCH_OC_WDT_CTL_NO_ICCSURV_STS BIT24
+#define B_PCH_OC_WDT_CTL_FORCE_ALL BIT15
+#define B_PCH_OC_WDT_CTL_EN BIT14
+#define B_PCH_OC_WDT_CTL_ICCSURV BIT13
+#define B_PCH_OC_WDT_CTL_LCK BIT12
+#define B_PCH_OC_WDT_CTL_TOV_MASK 0x3FF
+#define B_PCH_OC_WDT_CTL_FAILURE_STS BIT23
+#define B_PCH_OC_WDT_CTL_UNXP_RESET_STS BIT22
+#define B_PCH_OC_WDT_CTL_AFTER_POST 0x3F0000
+#define V_PCH_OC_WDT_CTL_STATUS_FAILURE 1
+#define V_PCH_OC_WDT_CTL_STATUS_OK 0
+
+#define R_PCH_ALT_GPI_SMI_EN2 0x5C
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP60_SMI_EN BIT7
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP57_SMI_EN BIT6
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP56_SMI_EN BIT5
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP43_SMI_EN BIT4
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP22_SMI_EN BIT3
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP21_SMI_EN BIT2
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP19_SMI_EN BIT1
+#define B_PCH_ALT_GPI_SMI_EN2_ALT_GP17_SMI_EN BIT0
+#define R_PCH_ALT_GPI_SMI_STS2 0x5E
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP60_SMI_STS BIT7
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP57_SMI_STS BIT6
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP56_SMI_STS BIT5
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP43_SMI_STS BIT4
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP22_SMI_STS BIT3
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP21_SMI_STS BIT2
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP19_SMI_STS BIT1
+#define B_PCH_ALT_GPI_SMI_STS2_ALT_GP17_SMI_STS BIT0
+
+//
+// TCO register I/O map
+//
+#define PCH_TCO_BASE 0x60
+
+#define R_PCH_TCO_RLD 0x0
+#define R_PCH_TCO_DAT_IN 0x2
+#define R_PCH_TCO_DAT_OUT 0x3
+#define R_PCH_TCO1_STS 0x04
+#define S_PCH_TCO1_STS 2
+#define B_PCH_TCO1_STS_DMISERR 0x1000
+#define B_PCH_TCO1_STS_DMISMI 0x0400
+#define B_PCH_TCO1_STS_DMISCI 0x0200
+#define B_PCH_TCO1_STS_BIOSWR 0x0100
+#define B_PCH_TCO1_STS_NEWCENTURY 0x0080
+#define B_PCH_TCO1_STS_TIMEOUT 0x0008
+#define B_PCH_TCO1_STS_TCO_INT 0x0004
+#define B_PCH_TCO1_STS_SW_TCO_SMI 0x0002
+#define B_PCH_TCO1_STS_NMI2SMI 0001
+#define N_PCH_TCO1_STS_DMISMI 10
+#define N_PCH_TCO1_STS_BIOSWR 8
+#define N_PCH_TCO1_STS_NEWCENTURY 7
+#define N_PCH_TCO1_STS_TIMEOUT 3
+#define N_PCH_TCO1_STS_SW_TCO_SMI 1
+#define N_PCH_TCO1_STS_NMI2SMI 0
+
+#define R_PCH_TCO2_STS 0x06
+#define S_PCH_TCO2_STS 2
+#define B_PCH_TCO2_STS_SMLINK_SLV_SMI BIT4
+#define B_PCH_TCO2_STS_BAD_BIOS BIT3
+#define B_PCH_TCO2_STS_BOOT BIT2
+#define B_PCH_TCO2_STS_SECOND_TO BIT1
+#define B_PCH_TCO2_STS_INTRD_DET BIT0
+#define N_PCH_TCO2_STS_INTRD_DET 0
+
+#define R_PCH_TCO1_CNT 0x08
+#define S_PCH_TCO1_CNT 2
+#define B_PCH_TCO_CNT_LOCK BIT12
+#define B_PCH_TCO_CNT_TMR_HLT BIT11
+#define B_PCH_TCO_CNT_NMI2SMI_EN BIT9
+#define B_PCH_TCO_CNT_NMI_NOW BIT8
+#define N_PCH_TCO_CNT_NMI2SMI_EN 9
+
+#define R_PCH_TCO2_CNT 0x0A
+#define S_PCH_TCO2_CNT 2
+#define B_PCH_TCO2_CNT_OS_POLICY 0x0030
+#define B_PCH_TCO2_CNT_GPI11_ALERT_DISABLE 0x0008
+#define B_PCH_TCO2_CNT_INTRD_SEL 0x0006
+#define N_PCH_TCO2_CNT_INTRD_SEL 2
+
+#define R_PCH_TCO_MESSAGE1 0x0C
+#define R_PCH_TCO_MESSAGE2 0x0D
+#define R_PCH_TCO_WDCNT 0x0E
+#define R_PCH_TCO_SW_IRQ_GEN 0x10
+#define B_PCH_TCO_IRQ12_CAUSE BIT1
+#define B_PCH_TCO_IRQ1_CAUSE BIT0
+#define R_PCH_TCO_TMR 0x12
+
+//
+// GPIO Init register offsets from GPIOBASE
+//
+#define R_PCH_GPIO_USE_SEL 0x00
+#define R_PCH_GPIO_IO_SEL 0x04
+#define R_PCH_GPIO_LVL 0x0C
+#define R_PCH_GPIO_IOAPIC_SEL 0x10
+#define V_PCH_GPIO_IOAPIC_SEL 0xFFFF
+#define R_PCH_GPIO_BLINK 0x18
+#define R_PCH_GPIO_SER_BLINK 0x1C
+#define R_PCH_GPIO_SB_CMDSTS 0x20
+#define B_PCH_GPIO_SB_CMDSTS_DLS_MASK 0x00C00000 ///< Data length select
+#define B_PCH_GPIO_SB_CMDSTS_DRS_MASK 0x003F0000 ///< Data rate select
+#define B_PCH_GPIO_SB_CMDSTS_BUSY BIT8
+#define B_PCH_GPIO_SB_CMDSTS_GO BIT0
+#define R_PCH_GPIO_SB_DATA 0x24
+#define R_PCH_GPIO_NMI_EN 0x28
+#define B_PCH_GPIO_NMI_EN 0xFFFF
+#define R_PCH_GPIO_NMI_STS 0x2A
+#define B_PCH_GPIO_NMI_STS 0xFFFF
+#define R_PCH_GPIO_GPI_INV 0x2C
+#define R_PCH_GPIO_USE_SEL2 0x30
+#define R_PCH_GPIO_IO_SEL2 0x34
+#define R_PCH_GPIO_LVL2 0x38
+#define R_PCH_GPIO_USE_SEL3 0x40
+#define R_PCH_GPIO_IO_SEL3 0x44
+#define R_PCH_GPIO_LVL3 0x48
+
+#define R_PCH_GP_RST_SEL 0x60
+#define S_PCH_GP_RST_SEL 4
+#define R_PCH_GP_RST_SEL2 0x64
+#define S_PCH_GP_RST_SEL2 4
+#define R_PCH_GP_RST_SEL3 0x68
+#define S_PCH_GP_RST_SEL3 4
+
+typedef struct {
+ UINT16 GpioOwn : 1;
+ UINT16 GpiRout : 1;
+ UINT16 GpiIe : 1;
+ UINT16 GpioUseSel : 1;
+ UINT16 GpioIoSel : 1;
+ UINT16 GpiInv : 1;
+ UINT16 GpiLxEb : 1;
+ UINT16 GpoLvl : 1;
+ UINT16 GpiWp : 2;
+ UINT16 GpinDis : 1;
+ UINT16 Reserved : 5;
+} PCH_GPIO_DEFINITION;
+
+#define R_PCH_GPIO_OWN0 0x00
+#define B_PCH_GPIO_OWN0_GPIO_USE_SEL BIT0
+#define B_PCH_GPIO_OWN0_GPIO_IO_SEL BIT2
+#define B_PCH_GPIO_OWN0_GPI_INV BIT3
+#define B_PCH_GPIO_OWN0_GPI_LxEB BIT4
+#define B_PCH_GPIO_OWN0_GPI_LVL BIT30
+#define B_PCH_GPIO_OWN0_GPO_LVL BIT31
+
+#define V_PCH_GPIO_OWN_GPIO 0x01
+#define V_PCH_GPIO_OWN_ACPI 0x00
+
+#define V_PCH_GPIO_USE_SEL_NATIVE 0x00
+#define V_PCH_GPIO_USE_SEL_GPIO 0x01
+
+#define V_PCH_GPIO_IO_SEL_OUT 0x00
+#define V_PCH_GPIO_IO_SEL_IN 0x01
+
+#define V_PCH_GPO_LVL_LOW 0x00
+#define V_PCH_GPO_LVL_HIGH 0x01
+
+#define V_PCH_GPI_LVL_NORMAL 0x00
+#define V_PCH_GPI_LVL_INVERTED 0x01
+
+#define V_PCH_GPI_LxEB_EDGE 0x00
+#define V_PCH_GPI_LxEB_LEVEL 0x01
+
+#define V_PCH_GPINDIS_ENABLE 0x00
+#define V_PCH_GPINDIS_DISABLE 0x01
+
+#define V_PCH_GPIWP_NONE 0x00
+#define V_PCH_GPIWP_DOWN 0x01
+#define V_PCH_GPIWP_UP 0x02
+
+#define R_PCH_GPIO_ROUT0 0x30
+#define V_PCH_GPIO_ROUT0_NMI_SMI 0x01
+#define V_PCH_GPIO_ROUT0_SCI 0x00
+
+#define R_PCH_GPIO_GC 0x7C
+#define R_PCH_GPI_IS0 0x80
+#define R_PCH_GPI_IS1 0x84
+#define R_PCH_GPI_IS2 0x88
+#define V_PCH_GPI_IS_CLEARALL 0xFFFFFFFF
+
+#define R_PCH_GPI_IE0 0x90
+#define V_PCH_GPI_IE_APIC_DISABLED 0x00
+#define V_PCH_GPI_IE_APIC_ENABLED 0x01
+
+#define R_PCH_GPI_IE1 0x94
+#define R_PCH_GPI_IE2 0x98
+#define V_PCH_GPI_IE_CLEARALL 0x00000000
+
+#define R_PCH_GP_N_CONFIG0 0x100
+#define R_PCH_GP_X_CONFIG0(n) (R_PCH_GP_N_CONFIG0 + ((n) * 0x08))
+#define R_PCH_GP_18_CONFIG0 R_PCH_GP_X_CONFIG0(18)
+#define R_PCH_GP_19_CONFIG0 R_PCH_GP_X_CONFIG0(19)
+#define R_PCH_GP_20_CONFIG0 R_PCH_GP_X_CONFIG0(20)
+#define R_PCH_GP_21_CONFIG0 R_PCH_GP_X_CONFIG0(21)
+#define R_PCH_GP_22_CONFIG0 R_PCH_GP_X_CONFIG0(22)
+#define R_PCH_GP_23_CONFIG0 R_PCH_GP_X_CONFIG0(23)
+#define R_PCH_GP_29_CONFIG0 R_PCH_GP_X_CONFIG0(29)
+#define R_PCH_GP_30_CONFIG0 R_PCH_GP_X_CONFIG0(30)
+#define R_PCH_GP_60_CONFIG0 R_PCH_GP_X_CONFIG0(60)
+#define R_PCH_GP_73_CONFIG0 R_PCH_GP_X_CONFIG0(73)
+#define R_PCH_GP_83_CONFIG0 R_PCH_GP_X_CONFIG0(83) ///< SPI0
+#define R_PCH_GP_87_CONFIG0 R_PCH_GP_X_CONFIG0(87) ///< SPI1
+#define R_PCH_GP_91_CONFIG0 R_PCH_GP_X_CONFIG0(91) ///< UART0
+#define V_PCH_GPIO_PIN_MAX 95
+
+//
+// Processor interface registers
+//
+#define R_PCH_NMI_SC 0x61
+#define B_PCH_NMI_SC_SERR_NMI_STS BIT7
+#define B_PCH_NMI_SC_IOCHK_NMI_STS BIT6
+#define B_PCH_NMI_SC_TMR2_OUT_STS BIT5
+#define B_PCH_NMI_SC_REF_TOGGLE BIT4
+#define B_PCH_NMI_SC_IOCHK_NMI_EN BIT3
+#define B_PCH_NMI_SC_PCI_SERR_EN BIT2
+#define B_PCH_NMI_SC_SPKR_DAT_EN BIT1
+#define B_PCH_NMI_SC_TIM_CNT2_EN BIT0
+#define R_PCH_NMI_EN 0x70
+#define B_PCH_NMI_EN_NMI_EN BIT7
+
+//
+// RTC register
+//
+#define R_PCH_RTC_INDEX 0x70
+#define R_PCH_RTC_TARGET 0x71
+#define R_PCH_RTC_EXT_INDEX 0x72
+#define R_PCH_RTC_EXT_TARGET 0x73
+#define R_PCH_RTC_REGA 0x0A
+#define B_PCH_RTC_REGA_UIP 0x80
+#define R_PCH_RTC_REGB 0x0B
+#define B_PCH_RTC_REGB_SET 0x80
+#define B_PCH_RTC_REGB_PIE 0x40
+#define B_PCH_RTC_REGB_AIE 0x20
+#define B_PCH_RTC_REGB_UIE 0x10
+#define B_PCH_RTC_REGB_DM 0x04
+#define B_PCH_RTC_REGB_HOURFORM 0x02
+#define R_PCH_RTC_REGC 0x0C
+#define R_PCH_RTC_REGD 0x0D
+
+//
+// Reset Generator I/O Port
+//
+#define R_PCH_RST_CNT 0xCF9
+#define B_PCH_RST_CNT_FULL_RST BIT3
+#define B_PCH_RST_CNT_RST_CPU BIT2
+#define B_PCH_RST_CNT_SYS_RST BIT1
+#define V_PCH_RST_CNT_FULLRESET 0x0E
+#define V_PCH_RST_CNT_HARDRESET 0x06
+#define V_PCH_RST_CNT_SOFTRESET 0x04
+#define V_PCH_RST_CNT_HARDSTARTSTATE 0x02
+#define V_PCH_RST_CNT_SOFTSTARTSTATE 0x00
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsPcie.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsPcie.h
new file mode 100644
index 0000000..7fb2afa
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsPcie.h
@@ -0,0 +1,548 @@
+/** @file
+ Register names for PCH PCI-E root port devices
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_PCIE_H_
+#define _PCH_REGS_PCIE_H_
+
+#define LPTH_PCIE_MAX_ROOT_PORTS 8
+#define LPTLP_PCIE_MAX_ROOT_PORTS 6
+
+//
+// PCH PCI Express Root Ports (D28:F0~5)
+//
+#define PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS 28
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 0
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 1
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 2
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 3
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5 4
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6 5
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7 6
+#define PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8 7
+#define R_PCH_PCIE_VENDOR_ID 0x00
+#define V_PCH_PCIE_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_PCIE_DEVICE_ID 0x02
+
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT1 0x8C10 ///< PCI Express Root Port #1, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT2 0x8C12 ///< PCI Express Root Port #2, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT3 0x8C14 ///< PCI Express Root Port #3, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT4 0x8C16 ///< PCI Express Root Port #4, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT5 0x8C18 ///< PCI Express Root Port #5, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT6 0x8C1A ///< PCI Express Root Port #6, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT7 0x8C1C ///< PCI Express Root Port #7, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_PORT8 0x8C1E ///< PCI Express Root Port #8, LPT
+#define V_PCH_LPTH_PCIE_DEVICE_ID_MB_SUBD 0x2448 ///< Mobile with subtractive decode enable
+#define V_PCH_LPTH_PCIE_DEVICE_ID_DT_SUBD 0x244E ///< Desktop with subtractive decode enable
+
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT1 0x9C10 ///< PCI Express Root Port #1, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT1_ALT 0x9C11 ///< PCI Express Root Port #1, LPTLP PCIe Device ID bit[0] fuse = 1
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT2 0x9C12 ///< PCI Express Root Port #2, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT2_ALT 0x9C13 ///< PCI Express Root Port #2, LPTLP PCIe Device ID bit[0] fuse = 1
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT3 0x9C14 ///< PCI Express Root Port #3, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT3_ALT 0x9C15 ///< PCI Express Root Port #3, LPTLP PCIe Device ID bit[0] fuse = 1
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT4 0x9C16 ///< PCI Express Root Port #4, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT4_ALT 0x9C17 ///< PCI Express Root Port #4, LPTLP PCIe Device ID bit[0] fuse = 1
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT5 0x9C18 ///< PCI Express Root Port #5, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT5_ALT 0x9C19 ///< PCI Express Root Port #5, LPTLP PCIe Device ID bit[0] fuse = 1
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT6 0x9C1A ///< PCI Express Root Port #6, LPTLP PCIe Device ID bit[0] fuse = 0
+#define V_PCH_LPTLP_PCIE_DEVICE_ID_PORT6_ALT 0x9C1B ///< PCI Express Root Port #6, LPTLP PCIe Device ID bit[0] fuse = 1
+
+#define R_PCH_PCIE_PCICMD 0x04
+#define S_PCH_PCIE_PCICMD 2
+#define B_PCH_PCIE_PCICMD_ID BIT10
+#define B_PCH_PCIE_PCICMD_FBE BIT9
+#define B_PCH_PCIE_PCICMD_SEE BIT8
+#define B_PCH_PCIE_PCICMD_WCC BIT7
+#define B_PCH_PCIE_PCICMD_PER BIT6
+#define B_PCH_PCIE_PCICMD_VPS BIT5
+#define B_PCH_PCIE_PCICMD_PMWE BIT4
+#define B_PCH_PCIE_PCICMD_SCE BIT3
+#define B_PCH_PCIE_PCICMD_BME BIT2
+#define B_PCH_PCIE_PCICMD_MSE BIT1
+#define B_PCH_PCIE_PCICMD_IOSE BIT0
+#define R_PCH_PCIE_PCISTS 0x06
+#define S_PCH_PCIE_PCISTS 2
+#define B_PCH_PCIE_PCISTS_DPE BIT15
+#define B_PCH_PCIE_PCISTS_SSE BIT14
+#define B_PCH_PCIE_PCISTS_RMA BIT13
+#define B_PCH_PCIE_PCISTS_RTA BIT12
+#define B_PCH_PCIE_PCISTS_STA BIT11
+#define B_PCH_PCIE_PCISTS_DEV_STS (BIT10 | BIT9)
+#define B_PCH_PCIE_PCISTS_DPED BIT8
+#define B_PCH_PCIE_PCISTS_FB2BC BIT7
+#define B_PCH_PCIE_PCISTS_66MHZ_CAP BIT5
+#define B_PCH_PCIE_PCISTS_CAP_LST BIT4
+#define B_PCH_PCIE_PCISTS_INTR_STS BIT3
+#define R_PCH_PCIE_RID 0x08
+#define B_PCH_PCIE_RID 0xFF
+#define R_PCH_PCIE_PI 0x09
+#define B_PCH_PCIE_PI 0xFF
+#define R_PCH_PCIE_SCC 0x0A
+#define B_PCH_PCIE_SCC 0xFF
+#define V_PCH_PCIE_SCC_04 0x04
+#define V_PCH_PCIE_SCC_00 0x00
+#define R_PCH_PCIE_BCC 0x0B
+#define B_PCH_PCIE_BCC 0xFF
+#define R_PCH_PCIE_CLS 0x0C
+#define B_PCH_PCIE_CLS 0xFF
+#define R_PCH_PCIE_PLT 0x0D
+#define B_PCH_PCIE_PLT_LC 0xF8
+#define R_PCH_PCIE_HEADTYPE 0x0E
+#define B_PCH_PCIE_HEADTYPE_MFD BIT7
+#define B_PCH_PCIE_HEADTYPE_CL 0x7F
+#define V_PCH_PCIE_HEADTYPE_CL_01 0x01
+#define V_PCH_PCIE_HEADTYPE_CL_00 0x00
+#define R_PCH_PCIE_BNUM 0x18
+#define B_PCH_PCIE_BNUM_SBBN 0x00FF0000
+#define B_PCH_PCIE_BNUM_SCBN 0x0000FF00
+#define B_PCH_PCIE_BNUM_PBN 0x000000FF
+#define R_PCH_PCIE_SLT 0x1B
+#define B_PCH_PCIE_SLT 0xFF
+#define R_PCH_PCIE_IOBL 0x1C
+#define B_PCH_PCIE_IOBL_IOLA 0xF000
+#define B_PCH_PCIE_IOBL_IOLC 0x0F00
+#define B_PCH_PCIE_IOBL_IOBA 0x00F0
+#define B_PCH_PCIE_IOBL_IOBC 0x000F
+#define R_PCH_PCIE_SSTS 0x1E
+#define S_PCH_PCIE_SSTS 2
+#define B_PCH_PCIE_SSTS_DPE BIT15
+#define B_PCH_PCIE_SSTS_RSE BIT14
+#define B_PCH_PCIE_SSTS_RMA BIT13
+#define B_PCH_PCIE_SSTS_RTA BIT12
+#define B_PCH_PCIE_SSTS_STA BIT11
+#define B_PCH_PCIE_SSTS_SDTS (BIT10 | BIT9)
+#define B_PCH_PCIE_SSTS_DPD BIT8
+#define B_PCH_PCIE_SSTS_SFBC BIT7
+#define B_PCH_PCIE_SSTS_SC66 BIT5
+#define R_PCH_PCIE_MBL 0x20
+#define B_PCH_PCIE_MBL_ML 0xFFF00000
+#define B_PCH_PCIE_MBL_MB 0x0000FFF0
+#define R_PCH_PCIE_PMBL 0x24
+#define B_PCH_PCIE_PMBL_PML 0xFFF00000
+#define B_PCH_PCIE_PMBL_I64L 0x000F0000
+#define B_PCH_PCIE_PMBL_PMB 0x0000FFF0
+#define B_PCH_PCIE_PMBL_I64B 0x0000000F
+#define R_PCH_PCIE_PMBU32 0x28
+#define B_PCH_PCIE_PMBU32 0xFFFFFFFF
+#define R_PCH_PCIE_PMLU32 0x2C
+#define B_PCH_PCIE_PMLU32 0xFFFFFFFF
+#define R_PCH_PCIE_CAPP 0x34
+#define B_PCH_PCIE_CAPP 0xFF
+#define R_PCH_PCIE_INTR 0x3C
+#define B_PCH_PCIE_INTR_IPIN 0xFF00
+#define B_PCH_PCIE_INTR_ILINE 0x00FF
+#define R_PCH_PCIE_BCTRL 0x3E
+#define S_PCH_PCIE_BCTRL 2
+#define B_PCH_PCIE_BCTRL_DTSE BIT11
+#define B_PCH_PCIE_BCTRL_DTS BIT10
+#define B_PCH_PCIE_BCTRL_SDT BIT9
+#define B_PCH_PCIE_BCTRL_PDT BIT8
+#define B_PCH_PCIE_BCTRL_FBE BIT7
+#define B_PCH_PCIE_BCTRL_SBR BIT6
+#define B_PCH_PCIE_BCTRL_MAM BIT5
+#define B_PCH_PCIE_BCTRL_V16 BIT4
+#define B_PCH_PCIE_BCTRL_VE BIT3
+#define B_PCH_PCIE_BCTRL_IE BIT2
+#define B_PCH_PCIE_BCTRL_SE BIT1
+#define B_PCH_PCIE_BCTRL_PERE BIT0
+#define R_PCH_PCIE_CLIST 0x40
+#define B_PCH_PCIE_CLIST_NEXT 0xFF00
+#define B_PCH_PCIE_CLIST_CID 0x00FF
+#define R_PCH_PCIE_XCAP 0x42
+#define S_PCH_PCIE_XCAP 2
+#define B_PCH_PCIE_XCAP_IMN 0x3E00
+#define B_PCH_PCIE_XCAP_SI BIT8
+#define B_PCH_PCIE_XCAP_DT 0x00F0
+#define B_PCH_PCIE_XCAP_CV 0x000F
+#define R_PCH_PCIE_DCAP 0x44
+#define S_PCH_PCIE_DCAP 4
+#define B_PCH_PCIE_DCAP_CSPS 0x0C000000
+#define B_PCH_PCIE_DCAP_CSPV 0x03FC0000
+#define B_PCH_PCIE_DCAP_RBER BIT15
+#define B_PCH_PCIE_DCAP_PIP BIT14
+#define B_PCH_PCIE_DCAP_AIP BIT13
+#define B_PCH_PCIE_DCAP_ABP BIT12
+#define B_PCH_PCIE_DCAP_E1AL 0x00000E00
+#define B_PCH_PCIE_DCAP_E0AL 0x000001C0
+#define B_PCH_PCIE_DCAP_ETFS BIT5
+#define B_PCH_PCIE_DCAP_PFS 0x00000018
+#define B_PCH_PCIE_DCAP_MPS 0x00000007
+#define R_PCH_PCIE_DCTL 0x48
+#define S_PCH_PCIE_DCTL 2
+#define B_PCH_PCIE_DCTL_MRRS 0x7000
+#define B_PCH_PCIE_DCTL_ENS BIT11
+#define B_PCH_PCIE_DCTL_APME BIT10
+#define B_PCH_PCIE_DCTL_PFE BIT9
+#define B_PCH_PCIE_DCTL_ETFE BIT8
+#define B_PCH_PCIE_DCTL_MPS (BIT7 | BIT6 | BIT5)
+#define B_PCH_PCIE_DCTL_ERO BIT4
+#define B_PCH_PCIE_DCTL_URE BIT3
+#define B_PCH_PCIE_DCTL_FEE BIT2
+#define B_PCH_PCIE_DCTL_NFE BIT1
+#define B_PCH_PCIE_DCTL_CEE BIT0
+#define R_PCH_PCIE_DSTS 0x4A
+#define B_PCH_PCIE_DSTS_TDP BIT5
+#define B_PCH_PCIE_DSTS_APD BIT4
+#define B_PCH_PCIE_DSTS_URD BIT3
+#define B_PCH_PCIE_DSTS_FED BIT2
+#define B_PCH_PCIE_DSTS_NFED BIT1
+#define B_PCH_PCIE_DSTS_CED BIT0
+#define R_PCH_PCIE_LCAP 0x4C
+#define B_PCH_PCIE_LCAP_PN 0xFF000000
+#define V_PCH_PCIE_LCAP_PN1 (1 << 24)
+#define V_PCH_PCIE_LCAP_PN2 (2 << 24)
+#define V_PCH_PCIE_LCAP_PN3 (3 << 24)
+#define V_PCH_PCIE_LCAP_PN4 (4 << 24)
+#define V_PCH_PCIE_LCAP_PN5 (5 << 24)
+#define V_PCH_PCIE_LCAP_PN6 (6 << 24)
+#define V_PCH_PCIE_LCAP_PN7 (7 << 24)
+#define V_PCH_PCIE_LCAP_PN8 (8 << 24)
+#define B_PCH_PCIE_LCAP_LARC BIT20
+#define B_PCH_PCIE_LCAP_EL1 (BIT17 | BIT16 | BIT15)
+#define B_PCH_PCIE_LCAP_EL0 (BIT14 | BIT13 | BIT12)
+#define B_PCH_PCIE_LCAP_APMS (BIT11 | BIT10)
+#define V_PCH_PCIE_LCAP_APMS_L0S (1 << 10)
+#define V_PCH_PCIE_LCAP_APMS_L0S_L1 (3 << 10)
+#define B_PCH_PCIE_LCAP_MLW 0x000003F0
+#define B_PCH_PCIE_LCAP_MLS 0x0000000F
+#define R_PCH_PCIE_LCTL 0x50
+#define B_PCH_PCIE_LCTL_HAWD BIT9
+#define B_PCH_PCIE_LCTL_ES BIT7
+#define B_PCH_PCIE_LCTL_CCC BIT6
+#define B_PCH_PCIE_LCTL_RL BIT5
+#define B_PCH_PCIE_LCTL_LD BIT4
+#define B_PCH_PCIE_LCTL_RCBC BIT3
+#define B_PCH_PCIE_LCTL_APMC (BIT1 | BIT0)
+#define V_PCH_PCIE_LCTL_APMC_L0S 1
+#define V_PCH_PCIE_LCTL_APMC_L1 2
+#define V_PCH_PCIE_LCTL_APMC_L0S_L1 3
+#define R_PCH_PCIE_LSTS 0x52
+#define S_PCH_PCIE_LSTS 2
+#define B_PCH_PCIE_LSTS_DLLA BIT13
+#define B_PCH_PCIE_LSTS_SCC BIT12
+#define B_PCH_PCIE_LSTS_LT BIT11
+#define B_PCH_PCIE_LSTS_LTE BIT10
+#define B_PCH_PCIE_LSTS_NLW 0x03F0
+#define V_PCH_PCIE_LSTS_NLW_1 0x0010
+#define V_PCH_PCIE_LSTS_NLW_2 0x0020
+#define V_PCH_PCIE_LSTS_NLW_4 0x0040
+#define B_PCH_PCIE_LSTS_LS 0x000F
+#define R_PCH_PCIE_SLCAP 0x54
+#define S_PCH_PCIE_SLCAP 4
+#define B_PCH_PCIE_SLCAP_PSN 0xFFF80000
+#define B_PCH_PCIE_SLCAP_SLS 0x00018000
+#define B_PCH_PCIE_SLCAP_SLV 0x00007F80
+#define B_PCH_PCIE_SLCAP_HPC BIT6
+#define B_PCH_PCIE_SLCAP_HPS BIT5
+#define B_PCH_PCIE_SLCAP_PIP BIT4
+#define B_PCH_PCIE_SLCAP_AIP BIT3
+#define B_PCH_PCIE_SLCAP_MSP BIT2
+#define B_PCH_PCIE_SLCAP_PCP BIT1
+#define B_PCH_PCIE_SLCAP_ABP BIT0
+#define R_PCH_PCIE_SLCTL 0x58
+#define S_PCH_PCIE_SLCTL 2
+#define B_PCH_PCIE_SLCTL_LACE BIT12
+#define B_PCH_PCIE_SLCTL_PCC BIT10
+#define B_PCH_PCIE_SLCTL_HPE BIT5
+#define B_PCH_PCIE_SLCTL_PDE BIT3
+#define R_PCH_PCIE_SLSTS 0x5A
+#define S_PCH_PCIE_SLSTS 2
+#define B_PCH_PCIE_SLSTS_LASC BIT8
+#define B_PCH_PCIE_SLSTS_PDS BIT6
+#define B_PCH_PCIE_SLSTS_MS BIT5
+#define B_PCH_PCIE_SLSTS_PDC BIT3
+#define B_PCH_PCIE_SLSTS_MSC BIT2
+#define B_PCH_PCIE_SLSTS_PFD BIT1
+#define R_PCH_PCIE_RCTL 0x5C
+#define S_PCH_PCIE_RCTL 2
+#define B_PCH_PCIE_RCTL_PIE BIT3
+#define B_PCH_PCIE_RCTL_SFE BIT2
+#define B_PCH_PCIE_RCTL_SNE BIT1
+#define B_PCH_PCIE_RCTL_SCE BIT0
+#define R_PCH_PCIE_RSTS 0x60
+#define S_PCH_PCIE_RSTS 4
+#define B_PCH_PCIE_RSTS_PP BIT17
+#define B_PCH_PCIE_RSTS_PS BIT16
+#define B_PCH_PCIE_RSTS_RID 0x0000FFFF
+#define R_PCH_PCIE_DCAP2 0x64
+#define B_PCH_PCIE_DCAP2_CTDS BIT4
+#define B_PCH_PCIE_DCAP2_CTRS 0xF
+#define V_PCH_PCIE_DCAP2_CTRS_UNSUPPORTED 0x0
+#define V_PCH_PCIE_DCAP2_CTRS_RANGE_A 0x1
+#define V_PCH_PCIE_DCAP2_CTRS_RANGE_B 0x2
+#define V_PCH_PCIE_DCAP2_CTRS_RANGE_C 0x4
+#define V_PCH_PCIE_DCAP2_CTRS_RANGE_D 0x8
+#define R_PCH_PCIE_DCTL2 0x68
+#define B_PCH_PCIE_DCTL2_CTD BIT4
+#define B_PCH_PCIE_DCTL2_CTV 0xF
+#define V_PCH_PCIE_DCTL2_CTV_DEFAULT 0x0
+#define V_PCH_PCIE_DCTL2_CTV_40MS_50MS 0x5
+#define V_PCH_PCIE_DCTL2_CTV_160MS_170MS 0x6
+#define V_PCH_PCIE_DCTL2_CTV_400MS_500MS 0x9
+#define V_PCH_PCIE_DCTL2_CTV_1P6S_1P7S 0xA
+#define R_PCH_PCIE_LCTL2 0x70
+#define B_PCH_PCIE_LCTL2_TLS (BIT3 | BIT2 | BIT1 | BIT0)
+#define R_PCH_PCIE_MID 0x80
+#define S_PCH_PCIE_MID 2
+#define B_PCH_PCIE_MID_NEXT 0xFF00
+#define B_PCH_PCIE_MID_CID 0x00FF
+#define R_PCH_PCIE_MC 0x82
+#define S_PCH_PCIE_MC 2
+#define B_PCH_PCIE_MC_C64 BIT7
+#define B_PCH_PCIE_MC_MME (BIT6 | BIT5 | BIT4)
+#define B_PCH_PCIE_MC_MMC 0x000E
+#define B_PCH_PCIE_MC_MSIE BIT0
+#define R_PCH_PCIE_MA 0x84
+#define S_PCH_PCIE_MA 4
+#define B_PCH_PCIE_MA_ADDR 0xFFFFFFFC
+#define R_PCH_PCIE_MD 0x88
+#define S_PCH_PCIE_MD 2
+#define B_PCH_PCIE_MD_DATA 0xFFFF
+#define R_PCH_PCIE_SVCAP 0x90
+#define S_PCH_PCIE_SVCAP 2
+#define B_PCH_PCIE_SVCAP_NEXT 0xFF00
+#define B_PCH_PCIE_SVCAP_CID 0x00FF
+#define R_PCH_PCIE_SVID 0x94
+#define S_PCH_PCIE_SVID 4
+#define B_PCH_PCIE_SVID_SID 0xFFFF0000
+#define B_PCH_PCIE_SVID_SVID 0x0000FFFF
+#define R_PCH_PCIE_PMCAP 0xA0
+#define S_PCH_PCIE_PMCAP 2
+#define B_PCH_PCIE_PMCAP_NEXT 0xFF00
+#define B_PCH_PCIE_PMCAP_CID 0x00FF
+#define R_PCH_PCIE_PMC 0xA2
+#define S_PCH_PCIE_PMC 2
+#define B_PCH_PCIE_PMC_PMES 0xF800
+#define B_PCH_PCIE_PMC_D2S BIT10
+#define B_PCH_PCIE_PMC_D1S BIT9
+#define B_PCH_PCIE_PMC_AC 0x01C0
+#define B_PCH_PCIE_PMC_DSI BIT5
+#define B_PCH_PCIE_PMC_PMEC BIT3
+#define B_PCH_PCIE_PMC_VS 0x0007
+#define R_PCH_PCIE_PMCS 0xA4
+#define S_PCH_PCIE_PMCS 4
+#define B_PCH_PCIE_PMCS_BPCE BIT23
+#define B_PCH_PCIE_PMCS_B23S BIT22
+#define B_PCH_PCIE_PMCS_PMES BIT15
+#define B_PCH_PCIE_PMCS_PMEE BIT8
+#define B_PCH_PCIE_PMCS_PS (BIT1 | BIT0)
+#define V_PCH_PCIE_PMCS_D0 0x00
+#define V_PCH_PCIE_PMCS_D3H 0x03
+#define R_PCH_PCIE_CCFG 0xD0
+#define B_PCH_PCIE_CCFG_DCGEISMA BIT17
+#define R_PCH_PCIE_MPC2 0xD4
+#define S_PCH_PCIE_MPC2 4
+#define B_PCH_PCIE_MPC2_PCME BIT5
+#define B_PCH_PCIE_MPC2_ASPMCOEN BIT4
+#define B_PCH_PCIE_MPC2_ASPMCO (BIT3 | BIT2)
+#define V_PCH_PCIE_MPC2_ASPMCO_DISABLED 0
+#define V_PCH_PCIE_MPC2_ASPMCO_L0S 1 << 2
+#define V_PCH_PCIE_MPC2_ASPMCO_L1 2 << 2
+#define V_PCH_PCIE_MPC2_ASPMCO_L0S_L1 3 << 2
+#define B_PCH_PCIE_MPC2_EOIFD BIT1
+#define B_PCH_PCIE_MPC2_L1CTM BIT0
+#define R_PCH_PCIE_MPC 0xD8
+#define S_PCH_PCIE_MPC 4
+#define B_PCH_PCIE_MPC_PMCE BIT31
+#define B_PCH_PCIE_MPC_HPCE BIT30
+#define B_PCH_PCIE_MPC_LHO BIT29
+#define B_PCH_PCIE_MPC_ATE BIT28
+#define B_PCH_PCIE_MPC_MMBNCE BIT27
+#define B_PCH_PCIE_MPC_IRBNCE BIT26
+#define B_PCH_PCIE_MPC_IRRCE BIT25
+#define B_PCH_PCIE_MPC_BMERCE BIT24
+#define B_PCH_PCIE_MPC_FORCEDET BIT22
+#define B_PCH_PCIE_MPC_FCDL1E BIT21
+#define B_PCH_PCIE_MPC_UCEL (BIT20 | BIT19 | BIT18)
+#define B_PCH_PCIE_MPC_CCEL (BIT17 | BIT16 | BIT15)
+#define B_PCH_PCIE_MPC_PAE BIT7
+#define B_PCH_PCIE_MPC_MCTPSE BIT3
+#define B_PCH_PCIE_MPC_BT BIT2
+#define B_PCH_PCIE_MPC_HPME BIT1
+#define N_PCH_PCIE_MPC_HPME 1
+#define B_PCH_PCIE_MPC_PMME BIT0
+#define R_PCH_PCIE_SMSCS 0xDC
+#define S_PCH_PCIE_SMSCS 4
+#define B_PCH_PCIE_SMSCS_PMCS BIT31
+#define B_PCH_PCIE_SMSCS_HPCS BIT30
+#define B_PCH_PCIE_SMSCS_HPLAS BIT4
+#define N_PCH_PCIE_SMSCS_HPLAS 4
+#define B_PCH_PCIE_SMSCS_HPCCM BIT3
+#define B_PCH_PCIE_SMSCS_HPABM BIT2
+#define B_PCH_PCIE_SMSCS_HPPDM BIT1
+#define N_PCH_PCIE_SMSCS_HPPDM 1
+#define B_PCH_PCIE_SMSCS_PMMS BIT0
+#define R_PCH_PCIE_RPDCGEN 0xE1
+#define S_PCH_PCIE_RPDCGEN 1
+#define B_PCH_PCIE_RPDCGEN_RPSCGEN BIT7
+#define B_PCH_PCIE_RPDCGEN_POCGE BIT6
+#define B_PCH_PCIE_RPDCGEN_LCLKREQEN BIT5
+#define B_PCH_PCIE_RPDCGEN_BBCLKREQEN BIT4
+#define B_PCH_PCIE_RPDCGEN_SRDLCGEN BIT3
+#define B_PCH_PCIE_RPDCGEN_SRDBCGEN BIT2
+#define B_PCH_PCIE_RPDCGEN_RPDLCGEN BIT1
+#define B_PCH_PCIE_RPDCGEN_RPDBCGEN BIT0
+#define R_PCH_PCIE_RPPGEN 0xE2
+#define B_PCH_PCIE_RPPGEN_PTOTOP BIT6
+#define B_PCH_PCIE_RPPGEN_LMSDOCGE BIT5
+#define B_PCH_PCIE_RPPGEN_SEOCGE BIT4
+#define R_PCH_PCIE_PECR1 0xE8
+#define S_PCH_PCIE_PECR1 4
+#define B_PCH_PCIE_PECR1_FIELD_2 BIT1
+#define V_PCH_PCIE_PECR1_FIELD_3 (BIT3 | BIT2)
+#define R_PCH_PCIE_PECR3 0xEC
+#define B_PCH_PCIE_PECR3_SDCDID BIT1 ///< Subtractive Decode Compatibility Device ID
+#define B_PCH_PCIE_PECR3_SDE BIT0 ///< Subtractive Decode Enable
+#define R_PCH_PCIE_STRPFUSECFG 0xFC
+#define B_PCH_PCIE_STRPFUSECFG_SATAP3_PCIEP6L0_MODE (BIT23 | BIT22)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP2_PCIEP6L1_MODE (BIT21 | BIT20)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP5_PCIEP2_MODE (BIT23 | BIT22)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP4_PCIEP1_MODE (BIT21 | BIT20)
+#define B_PCH_PCIE_STRPFUSECFG_GBE_PCIE_PEN (BIT19)
+#define B_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL (BIT18 | BIT17 | BIT16)
+#define N_PCH_PCIE_STRPFUSECFG_GBE_PCIEPORTSEL 16
+#define B_PCH_PCIE_STRPFUSECFG_RPC (BIT15 | BIT14)
+#define V_PCH_PCIE_STRPFUSECFG_RPC_1_1_1_1 (0)
+#define V_PCH_PCIE_STRPFUSECFG_RPC_2_1_1 (BIT14)
+#define V_PCH_PCIE_STRPFUSECFG_RPC_2_2 (BIT15)
+#define V_PCH_PCIE_STRPFUSECFG_RPC_4 (BIT15 | BIT14)
+#define N_PCH_PCIE_STRPFUSECFG_RPC_4 14
+#define B_PCH_PCIE_STRPFUSECFG_SATAP3_PCIEP6L0_MODE_FUSE (BIT13 | BIT12)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP2_PCIEP6L1_MODE_FUSE (BIT11 | BIT10)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP5_PCIEP2_MODE_FUSE (BIT13 | BIT12)
+#define B_PCH_PCIE_STRPFUSECFG_SATAP4_PCIEP1_MODE_FUSE (BIT11 | BIT10)
+#define B_PCH_PCIE_STRPFUSECFG_mPHYIOPMDIS (BIT9)
+#define B_PCH_PCIE_STRPFUSECFG_PLLSHTDWNDIS (BIT8)
+#define B_PCH_PCIE_STRPFUSECFG_STPGATEDIS (BIT7)
+#define B_PCH_PCIE_STRPFUSECFG_ASPMDIS (BIT6)
+#define B_PCH_PCIE_STRPFUSECFG_LDCGDIS (BIT5)
+#define B_PCH_PCIE_STRPFUSECFG_LTCGDIS (BIT4)
+#define B_PCH_PCIE_STRPFUSECFG_BDCGDIS (BIT3)
+#define B_PCH_PCIE_STRPFUSECFG_DESKTOPMOB (BIT1)
+#define R_PCH_PCIE_AECH 0x100
+#define R_PCH_PCIE_UES 0x104
+#define S_PCH_PCIE_UES 4
+#define B_PCH_PCIE_UES_URE BIT20
+#define B_PCH_PCIE_UES_EE BIT19
+#define B_PCH_PCIE_UES_MT BIT18
+#define B_PCH_PCIE_UES_RO BIT17
+#define B_PCH_PCIE_UES_UC BIT16
+#define B_PCH_PCIE_UES_CA BIT15
+#define B_PCH_PCIE_UES_CT BIT14
+#define B_PCH_PCIE_UES_FCPE BIT13
+#define B_PCH_PCIE_UES_PT BIT12
+#define B_PCH_PCIE_UES_DLPE BIT4
+#define B_PCH_PCIE_UES_TE BIT0
+#define R_PCH_PCIE_UEM 0x108
+#define S_PCH_PCIE_UEM 4
+#define B_PCH_PCIE_UEM_URE BIT20
+#define B_PCH_PCIE_UEM_EE BIT19
+#define B_PCH_PCIE_UEM_MT BIT18
+#define B_PCH_PCIE_UEM_RO BIT17
+#define B_PCH_PCIE_UEM_UC BIT16
+#define B_PCH_PCIE_UEM_CA BIT15
+#define B_PCH_PCIE_UEM_CT BIT14
+#define B_PCH_PCIE_UEM_FCPE BIT13
+#define B_PCH_PCIE_UEM_PT BIT12
+#define B_PCH_PCIE_UEM_DLPE BIT4
+#define B_PCH_PCIE_UEM_TE BIT0
+#define R_PCH_PCIE_UEV 0x10C
+#define S_PCH_PCIE_UEV 4
+#define B_PCH_PCIE_UEV_URE BIT20
+#define B_PCH_PCIE_UEV_EE BIT19
+#define B_PCH_PCIE_UEV_MT BIT18
+#define B_PCH_PCIE_UEV_RO BIT17
+#define B_PCH_PCIE_UEV_UC BIT16
+#define B_PCH_PCIE_UEV_CA BIT15
+#define B_PCH_PCIE_UEV_CT BIT14
+#define B_PCH_PCIE_UEV_FCPE BIT13
+#define B_PCH_PCIE_UEV_PT BIT12
+#define B_PCH_PCIE_UEV_DLPE BIT4
+#define B_PCH_PCIE_UEV_TE BIT0
+#define R_PCH_PCIE_CES 0x110
+#define S_PCH_PCIE_CES 4
+#define B_PCH_PCIE_CES_ANFES BIT13
+#define B_PCH_PCIE_CES_RTT BIT12
+#define B_PCH_PCIE_CES_RNR BIT8
+#define B_PCH_PCIE_CES_BD BIT7
+#define B_PCH_PCIE_CES_BT BIT6
+#define B_PCH_PCIE_CES_RE BIT0
+#define R_PCH_PCIE_CEM 0x114
+#define S_PCH_PCIE_CEM 4
+#define B_PCH_PCIE_CEM_ANFEM BIT13
+#define B_PCH_PCIE_CEM_RTT BIT12
+#define B_PCH_PCIE_CEM_RNR BIT8
+#define B_PCH_PCIE_CEM_BD BIT7
+#define B_PCH_PCIE_CEM_BT BIT6
+#define B_PCH_PCIE_CEM_RE BIT0
+#define R_PCH_PCIE_AECC 0x118
+#define S_PCH_PCIE_AECC 4
+#define B_PCH_PCIE_AECC_ECE BIT8
+#define B_PCH_PCIE_AECC_ECC BIT7
+#define B_PCH_PCIE_AECC_EGE BIT6
+#define B_PCH_PCIE_AECC_EGC BIT5
+#define B_PCH_PCIE_AECC_FEP 0x0000001F
+#define R_PCH_PCIE_RES 0x130
+#define S_PCH_PCIE_RES 4
+#define B_PCH_PCIE_RES_AEMN 0xF8000000
+#define B_PCH_PCIE_RES_FEMR BIT6
+#define B_PCH_PCIE_RES_NFEMR BIT5
+#define B_PCH_PCIE_RES_FUF BIT4
+#define B_PCH_PCIE_RES_MENR BIT3
+#define B_PCH_PCIE_RES_ENR BIT2
+#define B_PCH_PCIE_RES_MCR BIT1
+#define B_PCH_PCIE_RES_CR BIT0
+#define R_PCH_PCIE_PECR2 0x320
+#define S_PCH_PCIE_PECR2 4
+#define B_PCH_PCIE_PECR2_FIELD_1 BIT21
+#define R_PCH_PCIE_PEETM 0x324
+#define S_PCH_PCIE_PEETM 1
+#define B_PCH_PCIE_PEETM_BAU BIT2
+#define R_PCH_PCIE_PEC1 0x330
+#define S_PCH_PCIE_PEC1 4
+#define B_PCH_PCIE_PEC1_FIELD_1 0xFF
+#define R_PCH_PCIE_LTROVR 0x400
+#define R_PCH_PCIE_LTROVR2 0x404
+#define R_PCH_PCIE_L1SECH 0x200
+#define V_PCH_PCIE_L1SECH_L1SUBST_CAP_ID 0x1E
+#define R_PCH_PCIE_L1SCAP 0x204
+#define R_PCH_PCIE_PCIEPMECTL 0x420
+#define B_PCH_PCIE_PCIEPMECTL_FDPGE BIT31
+#define B_PCH_PCIE_PCIEPMECTL_DLSULPGE BIT30
+#define B_PCH_PCIE_PCIEPMECTL_DLSULDLSD BIT29
+#define B_PCH_PCIE_PCIEPMECTL_L1LE BIT17
+#define V_PCH_PCIE_PCIEPMECTL_L1LTRTLV (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4)
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsRcrb.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsRcrb.h
new file mode 100644
index 0000000..a5206e4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsRcrb.h
@@ -0,0 +1,483 @@
+/** @file
+ Register names for PCH Chipset Configuration Registers
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_RCRB_H_
+#define _PCH_REGS_RCRB_H_
+
+//
+// Chipset configuration registers (Memory space)
+// RCBA
+//
+#define R_PCH_RCRB_CIR0050 0x0050
+#define B_PCH_RCRB_CIR0_TCLOCKDN BIT31
+#define R_PCH_RCRB_RPFN 0x0404 ///< Root Port Function Number & Hide for PCI Express Root Ports
+#define B_PCH_RCRB_RPFN_RP8CH BIT31 ///< Root Port 8 Hide
+#define B_PCH_RCRB_RPFN_RP8FN (BIT30 | BIT29 | BIT28) ///< Root Port 8 Function Number
+#define B_PCH_RCRB_RPFN_RP7CH BIT27 ///< Root Port 7 Hide
+#define B_PCH_RCRB_RPFN_RP7FN (BIT26 | BIT25 | BIT24) ///< Root Port 7 Function Number
+#define B_PCH_RCRB_RPFN_RP6CH BIT23 ///< Root Port 6 Hide
+#define B_PCH_RCRB_RPFN_RP6FN (BIT22 | BIT21 | BIT20) ///< Root Port 6 Function Number
+#define B_PCH_RCRB_RPFN_RP5CH BIT19 ///< Root Port 5 Hide
+#define B_PCH_RCRB_RPFN_RP5FN (BIT18 | BIT17 | BIT16) ///< Root Port 5 Function Number
+#define B_PCH_RCRB_RPFN_RP4CH BIT15 ///< Root Port 4 Hide
+#define B_PCH_RCRB_RPFN_RP4FN (BIT14 | BIT13 | BIT12) ///< Root Port 4 Function Number
+#define B_PCH_RCRB_RPFN_RP3CH BIT11 ///< Root Port 3 Hide
+#define B_PCH_RCRB_RPFN_RP3FN (BIT10 | BIT9 | BIT8) ///< Root Port 3 Function Number
+#define B_PCH_RCRB_RPFN_RP2CH BIT7 ///< Root Port 2 Hide
+#define B_PCH_RCRB_RPFN_RP2FN (BIT6 | BIT5 | BIT4) ///< Root Port 2 Function Number
+#define B_PCH_RCRB_RPFN_RP1CH BIT3 ///< Root Port 1 Hide
+#define B_PCH_RCRB_RPFN_RP1FN (BIT2 | BIT1 | BIT0) ///< Root Port 1 Function Number
+#define S_PCH_RCRB_PRFN_RP_FIELD 4 ///< 4 bits per root port
+#define R_PCH_RCRB_CIR0900 0x0900
+#define R_PCH_RCRB_CIR1100 0x1100
+#define R_PCH_RCRB_TRSR 0x1E00 ///< Trap Status Register
+#define B_PCH_RCRB_TRSR_CTSS 0x000F ///< Cycle Trap SMI# Status mask
+#define R_PCH_RCRB_TRCR 0x1E10 ///< Trapped Cycle Register
+#define S_PCH_RCRB_TRCR 8
+#define B_PCH_RCRB_TRCR_RWI BIT24
+#define B_PCH_RCRB_TRCR_AHBE 0x00000000000F0000
+#define B_PCH_RCRB_TRCR_TIOA 0x000000000000FFFC
+#define R_PCH_RCRB_TRWDR 0x1E18 ///< Trap Write Data Register
+#define S_PCH_RCRB_TRWDR 8
+#define B_PCH_RCRB_TRWDR_TIOD 0x00000000FFFFFFFF
+#define R_PCH_RCRB_IO_TRAP_0 0x1E80 ///< Trap Configuration Register
+#define R_PCH_RCRB_IO_TRAP_1 0x1E88 ///< Trap Configuration Register
+#define R_PCH_RCRB_IO_TRAP_2 0x1E90 ///< Trap Configuration Register
+#define R_PCH_RCRB_IO_TRAP_3 0x1E98 ///< Trap Configuration Register
+#define B_PCH_RCRB_IO_TRAP_RWM BIT17 ///< 49 - 32 for 32 bit access
+#define B_PCH_RCRB_IO_TRAP_RWIO BIT16 ///< 48 - 32 for 32 bit access
+#define N_PCH_RCRB_IO_TRAP_RWIO (48 - 32) ///< for 32 bit access
+#define B_PCH_RCRB_IO_TRAP_BEM 0x000000F000000000
+#define B_PCH_RCRB_IO_TRAP_TBE 0x0000000F00000000
+#define B_PCH_RCRB_IO_TRAP_ADMA 0x0000000000FC0000
+#define B_PCH_RCRB_IO_TRAP_IOAD 0x000000000000FFFC
+#define B_PCH_RCRB_IO_TRAP_TRSE BIT0 ///< Trap and SMI# Enable
+#define R_PCH_RCRB_V0CTL 0x2014 ///< Virtual channel 0 resource control
+#define B_PCH_RCRB_V0CTL_EN BIT31
+#define B_PCH_RCRB_V0CTL_ID (7 << 24) ///< Bit[26:24]
+#define N_PCH_RCRB_V0CTL_ID 24
+#define V_PCH_RCRB_V0CTL_ETVM_MASK 0xFC00
+#define V_PCH_RCRB_V0CTL_TVM_MASK 0x7E
+#define R_PCH_RCRB_V0STS 0x201A ///< Virtual channel 0 status
+#define B_PCH_RCRB_V0STS_NP BIT1
+#define R_PCH_RCRB_V1CTL 0x2020 ///< Virtual channel 1 resource control
+#define B_PCH_RCRB_V1CTL_EN BIT31
+#define B_PCH_RCRB_V1CTL_ID (0x0F << 24) ///< Bit[27:24]
+#define N_PCH_RCRB_V1CTL_ID 24
+#define V_PCH_RCRB_V1CTL_ETVM_MASK 0xFC00
+#define V_PCH_RCRB_V1CTL_TVM_MASK 0xFE
+#define R_PCH_RCRB_V1STS 0x2026 ///< Virtual channel 1 status
+#define B_PCH_RCRB_V1STS_NP BIT1
+#define R_PCH_RCRB_CIR2030 0x2030 ///< Priority Virtual Channel resource control
+#define R_PCH_RCRB_CIR2040 0x2040 ///< Priority Virtual Channel resource control
+#define R_PCH_RCRB_CIR2088 0x2088
+#define R_PCH_RCRB_REC 0x20AC
+#define B_PCH_RCRB_REC_DPDP (BIT31)
+#define R_PCH_RCRB_LCAP 0x21A4 ///< Link capabilities
+#define B_PCH_RCRB_LCAP_EL1 (BIT17 | BIT16 | BIT15)
+#define B_PCH_RCRB_LCAP_EL0 (BIT14 | BIT13 | BIT12)
+#define B_PCH_RCRB_LCAP_APMS (BIT11 | BIT10) ///< L0 is supported on DMI
+#define B_PCH_RCRB_LCAP_MLW 0x000003F0
+#define B_PCH_RCRB_LCAP_MLS 0x0000000F
+#define R_PCH_RCRB_LCTL 0x21A8 ///< Link control
+#define B_PCH_RCRB_LCTL_ES BIT7
+#define B_PCH_RCRB_LCTL_APMC (BIT1 | BIT0)
+#define V_PCH_RCRB_LCTL_APMC_DIS 0x00
+#define V_PCH_RCRB_LCTL_APMC_L0S_EN 0x01
+#define R_PCH_RCRB_LSTS 0x21AA
+#define B_PCH_RCRB_LSTS_NLW 0x03F0
+#define B_PCH_RCRB_LSTS_LS 0x000F
+#define R_PCH_RCRB_DMIC 0x2234 ///< DMI control register
+#define B_PCH_H_RCRB_DMIC_DMICGEN (BIT3 | BIT2 | BIT1 | BIT0) ///< DMI Clock Gate Enable for PCH H
+#define B_PCH_LP_RCRB_DMIC_DMICGEN (BIT3 | BIT2 | BIT1 | BIT0) ///< DMI Clock Gate Enable for PCH LP
+#define R_PCH_RCRB_CIR2238 0x2238 ///< Chipset Initialization Register 2238
+#define R_PCH_RCBA_CIR228C 0x228C ///< Chipset Initialization Register 228C
+#define R_PCH_RCRB_DMC 0x2304 ///< DMI Miscellaneous Control Register
+#define R_PCH_RCRB_CIR2314 0x2314
+#define R_PCH_RCRB_CIR2320 0x2320
+#define R_PCH_RCRB_IOBPIRI 0x2330 ///< IOBP Indexed Register Index
+#define B_PCH_RCRB_IOBPIRI_IOBPIS 0xFF000000 ///< IOBP Interface Select
+#define V_PCH_RCRB_IOBPIRI_IOBPIS_SATA 0xEA000000 ///< SATA (Ports 0 and Ports 1)
+#define V_PCH_RCRB_IOBPIRI_IOBPIS_DMI 0xEB000000 ///< DMI
+#define V_PCH_RCRB_IOBPIRI_IOBPIS_PCIE 0xEC000000 ///< PCIe
+#define B_PCH_RCRB_IOBPIRI_IOBPFS 0xFFFF ///< IOBP Function Select
+#define R_PCH_RCRB_IOBPD 0x2334 ///< IOBP Indexed Register Data
+#define R_PCH_RCRB_IOBPS 0x2338 ///< IOBP Status
+#define B_PCH_RCRB_IOBPS_IOBPIA 0xFF00 ///< IOBP Interface Access
+#define V_PCH_RCRB_IOBPS_IOBPIA_R 0x0600 ///< Read access
+#define V_PCH_RCRB_IOBPS_IOBPIA_W 0x0700 ///< Write access
+#define B_PCH_RCRB_IOBPS (BIT2 | BIT1) ///< Status for the transaction
+#define V_PCH_RCRB_IOBPS_SUCCESS 0 ///< Successful
+#define V_PCH_RCRB_IOBPS_UNSUCCESS BIT1 ///< Unsuccessful
+#define V_PCH_RCRB_IOBPS_POWEREDDOWN BIT2 ///< Powered Down
+#define B_PCH_RCRB_IOBPS_BUSY BIT0
+#define R_PCH_RCRB_TCTL 0x3000 ///< TCO Configuration register
+#define B_PCH_RCRB_TCTL_IE BIT7 ///< TCO IRQ Enable
+#define B_PCH_RCRB_TCTL_IS (BIT2 | BIT1 | BIT0) ///< TCO IRQ Select
+#define V_PCH_RCRB_TCTL_IRQ_9 0x00
+#define V_PCH_RCRB_TCTL_IRQ_10 0x01
+#define V_PCH_RCRB_TCTL_IRQ_11 0x02
+#define V_PCH_RCRB_TCTL_IRQ_20 0x04 ///< only if APIC enabled
+#define V_PCH_RCRB_TCTL_IRQ_21 0x05 ///< only if APIC enabled
+#define V_PCH_RCRB_TCTL_IRQ_22 0x06 ///< only if APIC enabled
+#define V_PCH_RCRB_TCTL_IRQ_23 0x07 ///< only if APIC enabled
+#define R_PCH_RCRB_D31IP 0x3100 ///< Device 31 interrupt pin
+#define B_PCH_RCRB_D31IP_TTIP (BIT27 | BIT26 | BIT25 | BIT24)
+#define V_PCH_RCRB_D31IP_TTIP_INTA (1 << 24)
+#define V_PCH_RCRB_D31IP_TTIP_INTB (2 << 24)
+#define V_PCH_RCRB_D31IP_TTIP_INTC (3 << 24)
+#define V_PCH_RCRB_D31IP_TTIP_INTD (4 << 24)
+#define B_PCH_RCRB_D31IP_SIP2 (BIT23 | BIT22 | BIT21 | BIT20)
+#define V_PCH_RCRB_D31IP_SIP2_INTA (1 << 20)
+#define V_PCH_RCRB_D31IP_SIP2_INTB (2 << 20)
+#define V_PCH_RCRB_D31IP_SIP2_INTC (3 << 20)
+#define V_PCH_RCRB_D31IP_SIP2_INTD (4 << 20)
+#define B_PCH_RCRB_D31IP_SMIP (BIT15 | BIT14 | BIT13 | BIT12)
+#define V_PCH_RCRB_D31IP_SMIP_INTA (1 << 12)
+#define V_PCH_RCRB_D31IP_SMIP_INTB (2 << 12)
+#define V_PCH_RCRB_D31IP_SMIP_INTC (3 << 12)
+#define V_PCH_RCRB_D31IP_SMIP_INTD (4 << 12)
+#define B_PCH_RCRB_D31IP_SIP (BIT11 | BIT10 | BIT9 | BIT8)
+#define V_PCH_RCRB_D31IP_SIP_INTA (1 << 8)
+#define V_PCH_RCRB_D31IP_SIP_INTB (2 << 8)
+#define V_PCH_RCRB_D31IP_SIP_INTC (3 << 8)
+#define V_PCH_RCRB_D31IP_SIP_INTD (4 << 8)
+#define B_PCH_RCRB_D31IP_LIP (BIT3 | BIT2 | BIT1 | BIT0)
+#define R_PCH_RCRB_D29IP 0x3108 ///< Device 29 interrupt pin
+#define B_PCH_RCRB_D29IP_E1P (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D29IP_E1P_INTA (1 << 0)
+#define V_PCH_RCRB_D29IP_E1P_INTB (2 << 0)
+#define V_PCH_RCRB_D29IP_E1P_INTC (3 << 0)
+#define V_PCH_RCRB_D29IP_E1P_INTD (4 << 0)
+#define R_PCH_RCRB_D28IP 0x310C ///< Device 28 interrupt pin
+#define B_PCH_RCRB_D28IP_P8IP (BIT31 | BIT30 | BIT29 | BIT28)
+#define V_PCH_RCRB_D28IP_P8IP_INTA (1 << 28)
+#define V_PCH_RCRB_D28IP_P8IP_INTB (2 << 28)
+#define V_PCH_RCRB_D28IP_P8IP_INTC (3 << 28)
+#define V_PCH_RCRB_D28IP_P8IP_INTD (4 << 28)
+#define B_PCH_RCRB_D28IP_P7IP (BIT27 | BIT26 | BIT25 | BIT24)
+#define V_PCH_RCRB_D28IP_P7IP_INTA (1 << 24)
+#define V_PCH_RCRB_D28IP_P7IP_INTB (2 << 24)
+#define V_PCH_RCRB_D28IP_P7IP_INTC (3 << 24)
+#define V_PCH_RCRB_D28IP_P7IP_INTD (4 << 24)
+#define B_PCH_RCRB_D28IP_P6IP (BIT23 | BIT22 | BIT21 | BIT20)
+#define V_PCH_RCRB_D28IP_P6IP_INTA (1 << 20)
+#define V_PCH_RCRB_D28IP_P6IP_INTB (2 << 20)
+#define V_PCH_RCRB_D28IP_P6IP_INTC (3 << 20)
+#define V_PCH_RCRB_D28IP_P6IP_INTD (4 << 20)
+#define B_PCH_RCRB_D28IP_P5IP (BIT19 | BIT18 | BIT17 | BIT16)
+#define V_PCH_RCRB_D28IP_P5IP_INTA (1 << 16)
+#define V_PCH_RCRB_D28IP_P5IP_INTB (2 << 16)
+#define V_PCH_RCRB_D28IP_P5IP_INTC (3 << 16)
+#define V_PCH_RCRB_D28IP_P5IP_INTD (4 << 16)
+#define B_PCH_RCRB_D28IP_P4IP (BIT15 | BIT14 | BIT13 | BIT12)
+#define V_PCH_RCRB_D28IP_P4IP_INTA (1 << 12)
+#define V_PCH_RCRB_D28IP_P4IP_INTB (2 << 12)
+#define V_PCH_RCRB_D28IP_P4IP_INTC (3 << 12)
+#define V_PCH_RCRB_D28IP_P4IP_INTD (4 << 12)
+#define B_PCH_RCRB_D28IP_P3IP (BIT11 | BIT10 | BIT9 | BIT8)
+#define V_PCH_RCRB_D28IP_P3IP_INTA (1 << 8)
+#define V_PCH_RCRB_D28IP_P3IP_INTB (2 << 8)
+#define V_PCH_RCRB_D28IP_P3IP_INTC (3 << 8)
+#define V_PCH_RCRB_D28IP_P3IP_INTD (4 << 8)
+#define B_PCH_RCRB_D28IP_P2IP (BIT7 | BIT6 | BIT5 | BIT4)
+#define V_PCH_RCRB_D28IP_P2IP_INTA (1 << 4)
+#define V_PCH_RCRB_D28IP_P2IP_INTB (2 << 4)
+#define V_PCH_RCRB_D28IP_P2IP_INTC (3 << 4)
+#define V_PCH_RCRB_D28IP_P2IP_INTD (4 << 4)
+#define B_PCH_RCRB_D28IP_P1IP (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D28IP_P1IP_INTA (1 << 0)
+#define V_PCH_RCRB_D28IP_P1IP_INTB (2 << 0)
+#define V_PCH_RCRB_D28IP_P1IP_INTC (3 << 0)
+#define V_PCH_RCRB_D28IP_P1IP_INTD (4 << 0)
+#define R_PCH_RCRB_D27IP 0x3110 ///< Device 27 interrupt pin
+#define B_PCH_RCRB_D27IP_ZIP (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D27IP_ZIP_INTA (1 << 0)
+#define V_PCH_RCRB_D27IP_ZIP_INTB (2 << 0)
+#define V_PCH_RCRB_D27IP_ZIP_INTC (3 << 0)
+#define V_PCH_RCRB_D27IP_ZIP_INTD (4 << 0)
+#define R_PCH_RCRB_D26IP 0x3114 ///< Device 26 interrupt pin
+#define B_PCH_RCRB_D26IP_E2P (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D26IP_E2P_INTA (1 << 0)
+#define V_PCH_RCRB_D26IP_E2P_INTB (2 << 0)
+#define V_PCH_RCRB_D26IP_E2P_INTC (3 << 0)
+#define V_PCH_RCRB_D26IP_E2P_INTD (4 << 0)
+#define R_PCH_RCRB_D25IP 0x3118 ///< Device 25 interrupt pin
+#define B_PCH_RCRB_D25IP_LIP (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D25IP_LIP_INTA (1 << 0)
+#define V_PCH_RCRB_D25IP_LIP_INTB (2 << 0)
+#define V_PCH_RCRB_D25IP_LIP_INTC (3 << 0)
+#define V_PCH_RCRB_D25IP_LIP_INTD (4 << 0)
+#define R_PCH_RCRB_D22IP 0x3124 ///< Device 22 interrupt pin
+#define B_PCH_RCRB_D22IP_KTIP (BIT15 | BIT14 | BIT13 | BIT12)
+#define V_PCH_RCRB_D22IP_KTIP_INTA (1 << 12)
+#define V_PCH_RCRB_D22IP_KTIP_INTB (2 << 12)
+#define V_PCH_RCRB_D22IP_KTIP_INTC (3 << 12)
+#define V_PCH_RCRB_D22IP_KTIP_INTD (4 << 12)
+#define B_PCH_RCRB_D22IP_IDERIP (BIT11 | BIT10 | BIT9 | BIT8)
+#define V_PCH_RCRB_D22IP_IDERIP_INTA (1 << 8)
+#define V_PCH_RCRB_D22IP_IDERIP_INTB (2 << 8)
+#define V_PCH_RCRB_D22IP_IDERIP_INTC (3 << 8)
+#define V_PCH_RCRB_D22IP_IDERIP_INTD (4 << 8)
+#define B_PCH_RCRB_D22IP_MEI2IP (BIT7 | BIT6 | BIT5 | BIT4)
+#define V_PCH_RCRB_D22IP_MEI2IP_INTA (1 << 4)
+#define V_PCH_RCRB_D22IP_MEI2IP_INTB (2 << 4)
+#define V_PCH_RCRB_D22IP_MEI2IP_INTC (3 << 4)
+#define V_PCH_RCRB_D22IP_MEI2IP_INTD (4 << 4)
+#define B_PCH_RCRB_D22IP_MEI1IP (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D22IP_MEI1IP_INTA (1 << 0)
+#define V_PCH_RCRB_D22IP_MEI1IP_INTB (2 << 0)
+#define V_PCH_RCRB_D22IP_MEI1IP_INTC (3 << 0)
+#define V_PCH_RCRB_D22IP_MEI1IP_INTD (4 << 0)
+#define R_PCH_RCRB_D20IP 0x3128 ///< Device 20 interrupt pin
+#define B_PCH_RCRB_D20IP_XHCIP (BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_RCRB_D20IP_XHCIP_INTA (1 << 0)
+#define V_PCH_RCRB_D20IP_XHCIP_INTB (2 << 0)
+#define V_PCH_RCRB_D20IP_XHCIP_INTC (3 << 0)
+#define V_PCH_RCRB_D20IP_XHCIP_INTD (4 << 0)
+#define R_PCH_RCRB_D31IR 0x3140 ///< Device 31 interrupt route
+#define R_PCH_RCRB_D29IR 0x3144 ///< Device 29 interrupt route
+#define R_PCH_RCRB_D28IR 0x3146 ///< Device 28 interrupt route
+#define R_PCH_RCRB_D27IR 0x3148 ///< Device 27 interrupt route
+#define R_PCH_RCRB_D26IR 0x314C ///< Device 26 interrupt route
+#define R_PCH_RCRB_D25IR 0x3150 ///< Device 25 interrupt route
+#define R_PCH_RCRB_D23IR 0x3158 ///< Device 23 interrupt route
+#define R_PCH_RCRB_D22IR 0x315C ///< Device 22 interrupt route
+#define R_PCH_RCRB_D20IR 0x3160 ///< Device 20 interrupt route
+#define R_PCH_RCRB_D21IR 0x3164 ///< Device 21 interrupt route
+#define B_PCH_RCRB_D21IR_IE BIT15
+#define R_PCH_RCRB_D19IR 0x3168 ///< Device 19 interrupt route
+#define B_PCH_RCRB_D19IR_IS (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_RCRB_D19IR_IE BIT15
+#define B_PCH_RCRB_DXXIR_IDR_MASK (BIT14 | BIT13 | BIT12)
+#define V_PCH_RCRB_DXXIR_IDR_PIRQA 0
+#define V_PCH_RCRB_DXXIR_IDR_PIRQB BIT12
+#define V_PCH_RCRB_DXXIR_IDR_PIRQC BIT13
+#define V_PCH_RCRB_DXXIR_IDR_PIRQD (BIT13 | BIT12)
+#define V_PCH_RCRB_DXXIR_IDR_PIRQE BIT14
+#define V_PCH_RCRB_DXXIR_IDR_PIRQF (BIT14 | BIT12)
+#define V_PCH_RCRB_DXXIR_IDR_PIRQG (BIT14 | BIT13)
+#define V_PCH_RCRB_DXXIR_IDR_PIRQH (BIT14 | BIT13 | BIT12)
+#define V_PCH_RCRB_DXXIR_ICR_PIRQA 0
+#define V_PCH_RCRB_DXXIR_ICR_PIRQB BIT8
+#define V_PCH_RCRB_DXXIR_ICR_PIRQC BIT9
+#define V_PCH_RCRB_DXXIR_ICR_PIRQD (BIT9 | BIT8)
+#define V_PCH_RCRB_DXXIR_ICR_PIRQE BIT10
+#define V_PCH_RCRB_DXXIR_ICR_PIRQF (BIT10 | BIT8)
+#define V_PCH_RCRB_DXXIR_ICR_PIRQG (BIT10 | BIT9)
+#define V_PCH_RCRB_DXXIR_ICR_PIRQH (BIT10 | BIT9 | BIT8)
+#define V_PCH_RCRB_DXXIR_IBR_PIRQA 0
+#define V_PCH_RCRB_DXXIR_IBR_PIRQB BIT4
+#define V_PCH_RCRB_DXXIR_IBR_PIRQC BIT5
+#define V_PCH_RCRB_DXXIR_IBR_PIRQD (BIT5 | BIT4)
+#define V_PCH_RCRB_DXXIR_IBR_PIRQE BIT6
+#define V_PCH_RCRB_DXXIR_IBR_PIRQF (BIT6 | BIT4)
+#define V_PCH_RCRB_DXXIR_IBR_PIRQG (BIT6 | BIT5)
+#define V_PCH_RCRB_DXXIR_IBR_PIRQH (BIT6 | BIT5 | BIT4)
+#define V_PCH_RCRB_DXXIR_IAR_PIRQA 0
+#define V_PCH_RCRB_DXXIR_IAR_PIRQB BIT0
+#define V_PCH_RCRB_DXXIR_IAR_PIRQC BIT1
+#define V_PCH_RCRB_DXXIR_IAR_PIRQD (BIT1 | BIT0)
+#define V_PCH_RCRB_DXXIR_IAR_PIRQE BIT2
+#define V_PCH_RCRB_DXXIR_IAR_PIRQF (BIT2 | BIT0)
+#define V_PCH_RCRB_DXXIR_IAR_PIRQG (BIT2 | BIT1)
+#define V_PCH_RCRB_DXXIR_IAR_PIRQH (BIT2 | BIT1 | BIT0)
+#define R_PCH_RCRB_OIC 0x31FE ///< Other Interrupt Control
+#define B_PCH_RCRB_OIC_OA24_39_D BIT11
+#define B_PCH_RCRB_OIC_CEN BIT9 ///< Coprocessor Error Enable
+#define B_PCH_RCRB_OIC_AEN BIT8 ///< APIC Enable
+#define V_PCH_RCRB_OIC_ASEL 0xFF
+#define R_PCH_IO_APIC_INDEX 0xFEC00000
+#define R_PCH_IO_APIC_DATA 0xFEC00010
+#define N_PCH_IO_APIC_ASEL 12
+#define R_PCH_RCRB_PRSTS 0x3310
+#define B_PCH_RCRB_PRSTS_PM_WD_TMR BIT15 ///< Power Management Watchdog Timer
+#define B_PCH_RCRB_PRSTS_VE_WD_TMR_STS BIT7 ///< VE Watchdog Timer Status
+#define B_PCH_RCRB_PRSTS_ME_WD_TMR_STS BIT6 ///< Management Engine Watchdog Timer Status
+#define B_PCH_RCRB_PRSTS_WOL_OVR_WK_STS BIT5
+#define B_PCH_RCRB_PRSTS_FIELD_1 BIT4
+#define B_PCH_RCRB_PRSTS_ME_HOST_PWRDN BIT3
+#define B_PCH_RCRB_PRSTS_ME_HRST_WARM_STS BIT2
+#define B_PCH_RCRB_PRSTS_ME_HRST_COLD_STS BIT1
+#define B_PCH_RCRB_PRSTS_ME_WAKE_STS BIT0
+#define R_PCH_RCRB_CIR3314 0x3314
+#define R_PCH_RCRB_PM_CFG 0x3318 ///< Power Management Configuration
+#define R_PCH_RCRB_PM_CFG_RTC_DS_WAKE_DIS BIT21 ///< RTC Wake from Deep S4/S5 Disable
+#define B_PCH_RCRB_PM_CFG_SSMAW_MASK (BIT19 | BIT18) ///< SLP_SUS# Min Assertion Width
+#define V_PCH_RCRB_PM_CFG_SSMAW_4S (BIT19 | BIT18) ///< 4 seconds
+#define V_PCH_RCRB_PM_CFG_SSMAW_1S BIT19 ///< 1 second
+#define V_PCH_RCRB_PM_CFG_SSMAW_0_5S BIT18 ///< 0.5 second (500ms)
+#define V_PCH_RCRB_PM_CFG_SSMAW_0S 0 ///< 0 second
+#define B_PCH_RCRB_PM_CFG_SAMAW_MASK (BIT17 | BIT16) ///< SLP_A# Min Assertion Width
+#define V_PCH_RCRB_PM_CFG_SAMAW_2S (BIT17 | BIT16) ///< 2 seconds
+#define V_PCH_RCRB_PM_CFG_SAMAW_98ms BIT17 ///< 98ms
+#define V_PCH_RCRB_PM_CFG_SAMAW_4S BIT16 ///< 4 seconds
+#define V_PCH_RCRB_PM_CFG_SAMAW_0S 0 ///< 0 second
+#define B_PCH_RCRB_PM_CFG_RPCD_MASK (BIT9 | BIT8) ///< Reset Power Cycle Duration
+#define V_PCH_RCRB_PM_CFG_RPCD_1S (BIT9 | BIT8) ///< 1-2 seconds
+#define V_PCH_RCRB_PM_CFG_RPCD_2S BIT9 ///< 2-3 seconds
+#define V_PCH_RCRB_PM_CFG_RPCD_3S BIT8 ///< 3-4 seconds
+#define V_PCH_RCRB_PM_CFG_RPCD_4S 0 ///< 4-5 seconds (Default)
+#define R_PCH_RCRB_CIR3324 0x3324
+#define R_PCH_RCRB_DEEP_S3_POL 0x3328 ///< Deep S3 Power Policies
+#define B_PCH_RCRB_DEEP_S3_POL_DPS3_EN_DC BIT1 ///< Deep S3 Enable in DC Mode
+#define B_PCH_RCRB_DEEP_S3_POL_DPS3_EN_AC BIT0 ///< Deep S3 Enable in AC Mode
+#define R_PCH_RCRB_DEEP_S4_POL 0x332C ///< Deep S4 Power Policies
+#define B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC BIT1 ///< Deep S4 Enable in DC Mode
+#define B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_AC BIT0 ///< Deep S4 Enable in AC Mode
+#define R_PCH_RCRB_DEEP_S5_POL 0x3330 ///< Deep S5 Power Policies
+#define B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC BIT15 ///< Deep S5 Enable in DC Mode
+#define B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_AC BIT14 ///< Deep S5 Enable in AC Mode
+#define R_PCH_RCRB_PM_CFG2 0x333C ///< Power Management Configuration Reg 2
+#define B_PCH_RCRB_PM_CFG2_DRAM_RESET_CTL (1 << 26) ///< DRAM RESET# control
+#define R_PCH_RCRB_CIR3340 0x3340
+#define R_PCH_RCRB_CIR3344 0x3344
+#define R_PCH_RCRB_CIR3348 0x3348
+#define R_PCH_RCRB_CIR3350 0x3350
+#define R_PCH_RCRB_CIR3360 0x3360
+#define R_PCH_RCRB_CIR3368 0x3368
+#define R_PCH_RCRB_CIR3378 0x3378
+#define R_PCH_RCRB_CIR337C 0x337C
+#define R_PCH_RCRB_CIR3388 0x3388
+#define R_PCH_RCRB_CIR3390 0x3390
+#define R_PCH_RCRB_CIR33A0 0x33A0
+#define R_PCH_RCRB_CIR33B0 0x33B0
+#define R_PCH_RCRB_CIR33C0 0x33C0
+#define PMSYNC_TPR_CONFIG 0x33C4
+#define B_PMSYNC_TPR_CONFIG_LOCK BIT31
+#define PMSYNC_TPR_CONFIG2 0x33CC
+#define R_PCH_RCRB_PMSYNC 0x33C8
+#define B_PCH_RCRB_PMSYNC_GPIO_D_SEL BIT11
+#define B_PCH_RCRB_PMSYNC_GPIO_C_SEL BIT10
+#define B_PCH_RCRB_PMSYNC_GPIO_B_SEL BIT9
+#define B_PCH_RCRB_PMSYNC_GPIO_A_SEL BIT8
+#define R_PCH_RCRB_CIR33D0 0x33D0
+#define R_PCH_RCRB_CIR33D4 0x33D4
+#define R_PCH_RCRB_RTC_CONF 0x3400 ///< RTC Configuration register
+#define S_PCH_RCRB_RTC_CONF 4
+#define B_PCH_RCRB_RTC_CONF_UCMOS_LOCK BIT4
+#define B_PCH_RCRB_RTC_CONF_LCMOS_LOCK BIT3
+#define B_PCH_RCRB_RTC_CONF_UCMOS_EN BIT2 ///< Upper CMOS bank enable
+#define R_PCH_RCRB_HPTC 0x3404 ///< High Performance Timer Configuration
+#define B_PCH_RCRB_HPTC_AE BIT7 ///< Address enable
+#define B_PCH_RCRB_HPTC_AS (BIT1 | BIT0) ///< Address selection
+#define R_PCH_PCH_HPET_CONFIG 0xFED00000
+#define N_PCH_HPET_ADDR_ASEL 12
+#define R_PCH_RCRB_GCS 0x3410 ///< General Control and Status
+#define B_PCH_RCRB_GCS_FLRCSSEL BIT12
+#define B_PCH_H_RCRB_GCS_BBS (BIT11 | BIT10) ///< Boot BIOS straps for Pch-H
+#define V_PCH_H_RCRB_GCS_BBS_SPI (3 << 10) ///< Boot BIOS strapped to SPI for Pch-H
+#define V_PCH_H_RCRB_GCS_BBS_LPC (0 << 10) ///< Boot BIOS strapped to LPC for Pch-H
+#define B_PCH_LP_RCRB_GCS_BBS BIT10 ///< Boot BIOS straps for Pch-Lp
+#define V_PCH_LP_RCRB_GCS_BBS_SPI 0 ///< Boot BIOS strapped to SPI for Pch-Lp
+#define V_PCH_LP_RCRB_GCS_BBS_LPC BIT10 ///< Boot BIOS strapped to LPC for Pch-Lp
+#define B_PCH_RCRB_GCS_SERM BIT9 ///< Server Error Reporting Mode
+#define B_PCH_RCRB_GCS_NR BIT5 ///< No Reboot strap
+#define B_PCH_RCRB_GCS_AME BIT4 ///< Alternate Access Mode Enable
+#define B_PCH_RCRB_GCS_SPS BIT3 ///< Shutdown Policy Select
+#define B_PCH_RCRB_GCS_RPR BIT2 ///< Reserved Page Route
+#define B_PCH_RCRB_GCS_BILD BIT0 ///< BIOS Interface Lock-Down
+#define R_PCH_RCRB_BUC 0x3414 ///< Backed Up Control
+#define B_PCH_RCRB_BUC_LAN_DIS BIT5 ///< LAN Disable
+#define B_PCH_RCRB_BUC_SDO BIT4 ///< Daylight Savings Override
+#define B_PCH_RCRB_BUC_TS BIT0 ///< Top Swap
+#define R_PCH_RCRB_FUNC_DIS 0x3418 ///< Function Disable Register
+#define B_PCH_RCRB_FUNC_DIS_XHCI BIT27 ///< XHCI controller disable
+#define B_PCH_RCRB_FUNC_DIS_SATA2 BIT25 ///< Serial ATA 2 disable
+#define B_PCH_RCRB_FUNC_DIS_THERMAL BIT24 ///< Thermal Throttle Disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT8 BIT23 ///< PCI Express port 8 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT7 BIT22 ///< PCI Express port 7 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT6 BIT21 ///< PCI Express port 6 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT5 BIT20 ///< PCI Express port 5 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT4 BIT19 ///< PCI Express port 4 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT3 BIT18 ///< PCI Express port 3 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT2 BIT17 ///< PCI Express port 2 disable
+#define B_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 BIT16 ///< PCI Express port 1 disable
+#define N_PCH_RCRB_FUNC_DIS_PCI_EX_PORT1 16
+#define B_PCH_RCRB_FUNC_DIS_EHCI1 BIT15 ///< EHCI controller 1 disable
+#define B_PCH_RCRB_FUNC_DIS_LPC_BRIDGE BIT14 ///< LPC Bridge disable
+#define B_PCH_RCRB_FUNC_DIS_EHCI2 BIT13 ///< EHCI controller 2 disable
+#define B_PCH_RCRB_FUNC_DIS_AZALIA BIT4 ///< Azalia disable
+#define B_PCH_RCRB_FUNC_DIS_SMBUS BIT3 ///< SMBUS disable
+#define B_PCH_RCRB_FUNC_DIS_SATA1 BIT2 ///< Serial ATA disable
+#define B_PCH_RCRB_FUNC_DIS_ADSP BIT1 ///< Audio DSP disable
+#define B_PCH_RCRB_FUNC_DIS_FUNCTION_0 BIT0 ///< Function 0 disable
+#define R_PCH_RCRB_CG 0x341C ///< Clock Gating
+#define B_PCH_RCRB_CG_EN_DCG_BLA BIT30 ///< Platform Essential Cluster BLA unit Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_SCG_GSX BIT29 ///< GSX Static Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_DCG_GPIO BIT28 ///< GPIO Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_DCG_HPET BIT27 ///< HPET Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_CG_GPEC BIT26 ///< Generic Platform Essential Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_SCG_8254 BIT25 ///< 8254 Static Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_SCG_8237 BIT24 ///< 8237 Static Clock Gate Enable
+
+#define B_PCH_RCRB_CG_EN_DCG_LPC BIT31 ///< Legacy(LPC) Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_SCG_LAN BIT23 ///< LAN Static Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_DCG_HDA BIT22 ///< HDA Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_SCG_HDA BIT21 ///< HDA Static Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_DCG_PCI BIT16 ///< PCI Dynamic Clock Gate Enable
+#define B_PCH_RCRB_CG_EN_CG_SMBUS BIT5 ///< SMBUS Static Clock Gating Enable
+#define R_PCH_RCRB_FDSW 0x3420 ///< Function Disable SUS well
+#define B_PCH_RCRB_FDSW_FDSWL BIT7 ///< Function Disable SUS well lockdown
+#define R_PCH_RCRB_DISPBDF 0x3424 ///< Display Bus, Device and Function Initialization
+#define B_PCH_RCRB_DISPBDF_DBN 0xFF00 ///< Display Bus Number
+#define B_PCH_RCRB_DISPBDF_DDN 0x00F8 ///< Display Device Number
+#define B_PCH_RCRB_DISPBDF_DFN 0x0007 ///< Display Function Number
+#define R_PCH_RCRB_FD2 0x3428 ///< Function Disable 2
+#define B_PCH_RCRB_FD2_KTD BIT4 ///< KT Disable
+#define B_PCH_RCRB_FD2_IRERD BIT3 ///< IDE-R Disable
+#define B_PCH_RCRB_FD2_MEI2D BIT2 ///< Intel MEI #2 Disable
+#define B_PCH_RCRB_FD2_MEI1D BIT1 ///< Intel MEI #1 Disable
+#define B_PCH_RCRB_FD2_DBDFEN BIT0 ///< Display BDF Enable
+#define R_PCH_RCRB_CIR3A28 0x3A28
+#define R_PCH_RCRB_CIR3A2C 0x3A2C
+#define R_PCH_RCRB_CIR3A6C 0x3A6C
+#define R_PCH_RCRB_CIR3A80 0x3A80
+#define R_PCH_RCRB_CIR3A84 0x3A84
+#define R_PCH_RCRB_CIR3A88 0x3A88
+#define R_PCH_RCRB_GSX_CTRL 0x3454 ///< GSX Control
+#define B_PCH_RCRB_GSX_BAR_ENABLE BIT4 ///< GSX BAR Enable
+#define R_PCH_RCRB_INT_ACPIIRQEN 0x31E0 ///< ACPI IRQ Control
+
+#define B_PCH_RCRB_INT_ACPIIRQEN_A15E BIT15 ///< ACPI IRQ15 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A14E BIT14 ///< ACPI IRQ14 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A13E BIT13 ///< ACPI IRQ13 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A7E BIT7 ///< ACPI IRQ7 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A6E BIT6 ///< ACPI IRQ6 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A5E BIT5 ///< ACPI IRQ5 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A4E BIT4 ///< ACPI IRQ4 Enable
+#define B_PCH_RCRB_INT_ACPIIRQEN_A3E BIT3 ///< ACPI IRQ3 Enable
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSata.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSata.h
new file mode 100644
index 0000000..add2c1e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSata.h
@@ -0,0 +1,703 @@
+/** @file
+ Register names for PCH SATA controllers
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_SATA_H_
+#define _PCH_REGS_SATA_H_
+
+//
+// SATA Controller 1 Registers (D31:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_SATA 31
+#define PCI_FUNCTION_NUMBER_PCH_SATA 2
+#define R_PCH_SATA_VENDOR_ID 0x00
+#define V_PCH_SATA_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_SATA_DEVICE_ID 0x02
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_IDE 0x8C00 ///< Desktop IDE Mode (Ports 0,1, 2 and 3)
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_AHCI 0x8C02 ///< Desktop AHCI Mode (Ports 0-5)
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_RAID 0x8C04 ///< Desktop RAID 0/1/5/10 Mode, based on D31:F2:9Ch[7]
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_PREM 0x8C06 ///< Desktop RAID 0/1/5/10 Mode, based on D31:F2:9Ch[7]
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_ALTDIS 0x2822 ///< Desktop RAID 0/1/5/10 Mode, based on D31:F2:9Ch[9][7]
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_RAID_SERVER 0x2826 ///< Server RAID 0/1/5/10 Mode, based on D31:F2:9Ch[9][7]
+#define V_PCH_LPTH_SATA2_DEVICE_ID_D_IDE 0x8C08 ///< Controller 2, Desktop IDE Mode, 2 ports
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_IDE 0x8C01 ///< Mobile IDE Mode, port 0, 1, 4, 5
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_AHCI 0x8C03 ///< Mobile AHCI Mode, port 0, 1, 4 5
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_RAID 0x8C05 ///< Mobile RAID 0/1/5/10 Mode, based on D31:F2:9Ch[7]
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_RAID_PREM 0x8C07 ///< Mobile RAID 0/1/5/10 Mode, based on D31:F2:9Ch[7]
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_RAID_ALTDIS 0x282A ///< Mobile RAID 0/1/5/10 Mode, based on D31:F2:9Ch[7]
+#define V_PCH_LPTH_SATA2_DEVICE_ID_M_IDE 0x8C09 ///< Controller 2, Mobile IDE, 2 ports
+#define V_PCH_LPTH_SATA_DEVICE_ID_D_RAID1 0x8C0E ///< SATA Controller 1 (RAID 1/RRT Only)
+#define V_PCH_LPTH_SATA_DEVICE_ID_M_RAID1 0x8C0F ///< SATA Controller 1 (RAID 1/RRT Only) - Mobile
+
+//
+// SATA Controller 2 Registers (D31:F5)
+//
+#define PCI_DEVICE_NUMBER_PCH_SATA2 31
+#define PCI_FUNCTION_NUMBER_PCH_SATA2 5
+#define R_PCH_SATA2_VENDOR_ID 0x00
+#define V_PCH_SATA2_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_SATA2_DEVICE_ID 0x02
+
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_TEST0 0x9C00 ///< SATA Controller 1 (TEST Mode only)
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_TEST1 0x9C01 ///< SATA Controller 1 (TEST Mode only) - Mobile
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_AHCI0 0x9C02 ///< SATA Controller 1 (AHCI)
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_AHCI1 0x9C03 ///< SATA Controller 1 (AHCI) - Mobile
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID0 0x9C04 ///< SATA Controller 1 (RAID 0/1/5/10) - NOT premium
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_ALTDIS0 0x2822 ///< SATA Controller 1 (RAID 0/1/5/10) - NOT premium - Alternate ID
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID1 0x9C05 ///< SATA Controller 1 (RAID 0/1/5/10) - NOT premium - Mobile
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_ALTDIS1 0x282A ///< SATA Controller 1 (RAID 0/1/5/10) - NOT premium - Mobile - Alternate ID
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_PREM0 0x9C06 ///< SATA Controller 1 (RAID 0/1/5/10) - premium
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID_PREM1 0x9C07 ///< SATA Controller 1 (RAID 0/1/5/10) - premium - Mobile
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID2 0x9C0E ///< SATA Controller 1 (RAID 1/RRT Only)
+#define V_PCH_LPTLP_SATA_DEVICE_ID_M_RAID3 0x9C0F ///< SATA Controller 1 (RAID 1/RRT Only) - Mobile
+
+//
+// SATA Controller common Registers
+//
+#define R_PCH_SATA_COMMAND 0x04
+#define B_PCH_SATA_COMMAND_INT_DIS BIT10
+#define B_PCH_SATA_COMMAND_FBE BIT9
+#define B_PCH_SATA_COMMAND_SERR_EN BIT8
+#define B_PCH_SATA_COMMAND_WCC BIT7
+#define B_PCH_SATA_COMMAND_PER BIT6
+#define B_PCH_SATA_COMMAND_VPS BIT5
+#define B_PCH_SATA_COMMAND_PMWE BIT4
+#define B_PCH_SATA_COMMAND_SCE BIT3
+#define B_PCH_SATA_COMMAND_BME BIT2
+#define B_PCH_SATA_COMMAND_MSE BIT1
+#define B_PCH_SATA_COMMAND_IOSE BIT0
+#define R_PCH_SATA_PCISTS 0x06
+#define B_PCH_SATA_PCISTS_DPE BIT15
+#define B_PCH_SATA_PCISTS_RMA BIT13
+#define B_PCH_SATA_PCISTS_DEV_STS_MASK (BIT10 | BIT9)
+#define B_PCH_SATA_PCISTS_DPED BIT8
+#define B_PCH_SATA_PCISTS_CAP_LIST BIT4
+#define B_PCH_SATA_PCISTS_ITNS BIT3
+#define R_PCH_SATA_RID 0x08
+#define R_PCH_SATA_PI_REGISTER 0x09
+#define B_PCH_SATA_PI_REGISTER_SNC BIT3
+#define B_PCH_SATA_PI_REGISTER_SNE BIT2
+#define B_PCH_SATA_PI_REGISTER_PNC BIT1
+#define B_PCH_SATA_PI_REGISTER_PNE BIT0
+#define R_PCH_SATA_SUB_CLASS_CODE 0x0A
+#define V_PCH_SATA_SUB_CLASS_CODE_IDE 0x01
+#define V_PCH_SATA_SUB_CLASS_CODE_AHCI 0x06
+#define V_PCH_SATA_SUB_CLASS_CODE_RAID 0x04
+#define R_PCH_SATA_BCC 0x0B
+#define B_PCH_SATA_BCC 0xFF
+#define R_PCH_SATA_PMLT 0x0D
+#define B_PCH_SATA_PMLT 0xFF
+#define R_PCH_SATA_HTYPE 0x0E
+#define B_PCH_SATA_HTYPE_MFD BIT7
+#define B_PCH_SATA_HTYPE_HL 0x7F
+#define R_PCH_SATA_PCMD_BAR 0x10
+#define B_PCH_SATA_PCMD_BAR_BA 0x0000FFF8
+#define B_PCH_SATA_PCMD_BAR_RTE BIT0
+#define R_PCH_SATA_PCNL_BAR 0x14
+#define B_PCH_SATA_PCNL_BAR_BA 0x0000FFFC
+#define B_PCH_SATA_PCNL_BAR_RTE BIT0
+#define R_PCH_SATA_SCMD_BAR 0x18
+#define B_PCH_SATA_SCMD_BAR_BA 0x0000FFF8
+#define B_PCH_SATA_SCMD_BAR_RTE BIT0
+#define R_PCH_SATA_SCNL_BAR 0x1C
+#define B_PCH_SATA_SCNL_BAR_BA 0x0000FFFC
+#define B_PCH_SATA_SCNL_BAR_RTE BIT0
+#define R_PCH_SATA_BUS_MASTER_BAR 0x20
+#define B_PCH_SATA_BUS_MASTER_BAR_BA 0x0000FFE0
+#define B_PCH_SATA_BUS_MASTER_BAR_BA4 BIT4
+#define B_PCH_SATA_BUS_MASTER_BAR_RTE BIT0
+#define R_PCH_SATA_SIDP_BAR 0x24
+#define R_PCH_SATA_AHCI_BAR 0x24
+#define B_PCH_SATA_AHCI_BAR_BA 0xFFFFF800
+#define V_PCH_SATA_AHCI_BAR_LENGTH 0x800
+#define N_PCH_SATA_AHCI_BAR_ALIGNMENT 11
+#define B_PCH_SATA_AHCI_BAR_PF BIT3
+#define B_PCH_SATA_AHCI_BAR_TP (BIT2 | BIT1)
+#define B_PCH_SATA_AHCI_BAR_RTE BIT0
+#define R_PCH_SATA_AHCI_SVID 0x2C
+#define B_PCH_SATA_AHCI_SVID 0xFFFF
+#define R_PCH_SATA_AHCI_SID 0x2E
+#define B_PCH_SATA_AHCI_SID 0xFFFF
+#define R_PCH_SATA_AHCI_CAP_PTR 0x34
+#define B_PCH_SATA_AHCI_CAP_PTR 0xFF
+#define R_PCH_SATA_AHCI_INTLN 0x3C
+#define B_PCH_SATA_AHCI_INTLN 0xFF
+#define R_PCH_SATA_AHCI_INTPN 0x3D
+#define B_PCH_SATA_AHCI_INTPN 0xFF
+#define R_PCH_SATA_TIMP 0x40
+#define R_PCH_SATA_TIMS 0x42
+#define B_PCH_SATA_TIM_IDE BIT15 ///< IDE Decode Enable
+#define R_PCH_SATA_PID 0x70
+#define B_PCH_SATA_PID_NEXT 0xFF00
+#define V_PCH_SATA_PID_NEXT_0 0xB000
+#define V_PCH_SATA_PID_NEXT_1 0xA800
+#define B_PCH_SATA_PID_CID 0x00FF
+#define R_PCH_SATA_PC 0x72
+#define S_PCH_SATA_PC 2
+#define B_PCH_SATA_PC_PME (BIT15 | BIT14 | BIT13 | BIT12 | BIT11)
+#define V_PCH_SATA_PC_PME_0 0x0000
+#define V_PCH_SATA_PC_PME_1 0x4000
+#define B_PCH_SATA_PC_D2_SUP BIT10
+#define B_PCH_SATA_PC_D1_SUP BIT9
+#define B_PCH_SATA_PC_AUX_CUR (BIT8 | BIT7 | BIT6)
+#define B_PCH_SATA_PC_DSI BIT5
+#define B_PCH_SATA_PC_PME_CLK BIT3
+#define B_PCH_SATA_PC_VER (BIT2 | BIT1 | BIT0)
+#define R_PCH_SATA_PMCS 0x74
+#define B_PCH_SATA_PMCS_PMES BIT15
+#define B_PCH_SATA_PMCS_PMEE BIT8
+#define B_PCH_SATA_PMCS_NSFRST BIT3
+#define V_PCH_SATA_PMCS_NSFRST_1 0x01
+#define V_PCH_SATA_PMCS_NSFRST_0 0x00
+#define B_PCH_SATA_PMCS_PS (BIT1 | BIT0)
+#define V_PCH_SATA_PMCS_PS_3 0x03
+#define V_PCH_SATA_PMCS_PS_0 0x00
+#define R_PCH_SATA_MID 0x80
+#define B_PCH_SATA_MID_NEXT 0xFF00
+#define B_PCH_SATA_MID_CID 0x00FF
+#define R_PCH_SATA_MC 0x82
+#define B_PCH_SATA_MC_C64 BIT7
+#define B_PCH_SATA_MC_MME (BIT6 | BIT5 | BIT4)
+#define V_PCH_SATA_MC_MME_4 0x04
+#define V_PCH_SATA_MC_MME_2 0x02
+#define V_PCH_SATA_MC_MME_1 0x01
+#define V_PCH_SATA_MC_MME_0 0x00
+#define B_PCH_SATA_MC_MMC (BIT3 | BIT2 | BIT1)
+#define V_PCH_SATA_MC_MMC_4 0x04
+#define V_PCH_SATA_MC_MMC_0 0x00
+#define B_PCH_SATA_MC_MSIE BIT0
+#define V_PCH_SATA_MC_MSIE_1 0x01
+#define V_PCH_SATA_MC_MSIE_0 0x00
+#define R_PCH_SATA_MA 0x84
+#define B_PCH_SATA_MA 0xFFFFFFFC
+#define R_PCH_SATA_MD 0x88
+#define B_PCH_SATA_MD_MSIMD 0xFFFF
+#define R_PCH_SATA_MAP 0x90
+#define B_PCH_H_SATA_MAP_SPD (BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_LP_SATA_MAP_SPD (BIT11 | BIT10 | BIT9 | BIT8)
+#define B_PCH_SATA_PORT5_DISABLED BIT13
+#define B_PCH_SATA_PORT4_DISABLED BIT12
+#define B_PCH_SATA_PORT3_DISABLED BIT11
+#define B_PCH_SATA_PORT2_DISABLED BIT10
+#define B_PCH_SATA_PORT1_DISABLED BIT9
+#define B_PCH_SATA_PORT0_DISABLED BIT8
+#define B_PCH_SATA2_MAP_SPD (BIT9 | BIT8)
+#define B_PCH_SATA2_PORT5_DISABLED BIT9
+#define B_PCH_SATA2_PORT4_DISABLED BIT8
+#define B_PCH_SATA_MAP_SMS_MASK (BIT7 | BIT6)
+#define V_PCH_SATA_MAP_SMS_LOOBACK_TESTMODE 0x00
+#define V_PCH_SATA_MAP_SMS_IDE 0x00
+#define V_PCH_SATA_MAP_SMS_AHCI 0x40
+#define V_PCH_SATA_MAP_SMS_RAID 0x80
+#define B_PCH_SATA_PORT_TO_CONTROLLER_CFG BIT5
+#define R_PCH_SATA_PCS 0x92
+#define S_PCH_SATA_PCS 0x2
+#define B_PCH_SATA_PCS_OOB_RETRY BIT15
+#define B_PCH_SATA_PCS_PORT5_DET BIT13
+#define B_PCH_SATA_PCS_PORT4_DET BIT12
+#define B_PCH_SATA_PCS_PORT3_DET BIT11
+#define B_PCH_SATA_PCS_PORT2_DET BIT10
+#define B_PCH_SATA_PCS_PORT1_DET BIT9
+#define B_PCH_SATA_PCS_PORT0_DET BIT8
+#define B_PCH_SATA_PCS_PORT5_EN BIT5
+#define B_PCH_SATA_PCS_PORT4_EN BIT4
+#define B_PCH_SATA_PCS_PORT3_EN BIT3
+#define B_PCH_SATA_PCS_PORT2_EN BIT2
+#define B_PCH_SATA_PCS_PORT1_EN BIT1
+#define B_PCH_SATA_PCS_PORT0_EN BIT0
+#define B_PCH_SATA2_PCS_PORT5_DET BIT9
+#define B_PCH_SATA2_PCS_PORT4_DET BIT8
+#define B_PCH_SATA2_PCS_PORT5_EN BIT1
+#define B_PCH_SATA2_PCS_PORT4_EN BIT0
+#define R_PCH_SATA_SCLKCG 0x94
+#define B_PCH_SATA_SCLKCG_PORT5_PCD BIT29
+#define B_PCH_SATA_SCLKCG_PORT4_PCD BIT28
+#define B_PCH_SATA_SCLKCG_PORT3_PCD BIT27
+#define B_PCH_SATA_SCLKCG_PORT2_PCD BIT26
+#define B_PCH_SATA_SCLKCG_PORT1_PCD BIT25
+#define B_PCH_SATA_SCLKCG_PORT0_PCD BIT24
+#define B_PCH_SATA_SCLKCG_POP3_DEVSLP BIT15
+#define R_PCH_SATA_SCLKGC 0x9C
+#define B_PCH_SATA_SCLKGC_AIE BIT7
+#define B_PCH_SATA_SCLKGC_AIES BIT6
+#define B_PCH_SATA_SCLKGC_SATATM_MASK 0x7C
+#define B_PCH_SATA_SCLKGC_SATATM_EN (BIT3 | BIT2)
+#define B_PCH_SATA_SCLKGC_SATA4PMIND BIT0
+#define R_PCH_SATA_SIRI 0xA0
+#define B_PCH_SATA_SIRI_IDX 0xFC
+#define R_PCH_SATA_STRD 0xA4
+#define B_PCH_SATA_STRD_DTA 0xFFFFFFFF
+#define R_PCH_SATA_CR0 0xA8
+#define B_PCH_SATA_CR0_MAJREV 0x00F00000
+#define B_PCH_SATA_CR0_MINREV 0x000F0000
+#define B_PCH_SATA_CR0_NEXT 0x0000FF00
+#define B_PCH_SATA_CR0_CAP 0x000000FF
+#define R_PCH_SATA_CR1 0xAC
+#define B_PCH_SATA_CR1_BAROFST 0xFFF0
+#define B_PCH_SATA_CR1_BARLOC 0x000F
+#define R_PCH_SATA_FLR_CID 0xB0
+#define B_PCH_SATA_FLR_CID_NEXT 0xFF00
+#define B_PCH_SATA_FLR_CID 0x00FF
+#define V_PCH_SATA_FLR_CID_1 0x0009
+#define V_PCH_SATA_FLR_CID_0 0x0013
+#define R_PCH_SATA_FLR_CLV 0xB2
+#define B_PCH_SATA_FLR_CLV_FLRC_FLRCSSEL_0 BIT9
+#define B_PCH_SATA_FLR_CLV_TXPC_FLRCSSEL_0 BIT8
+#define B_PCH_SATA_FLR_CLV_VSCID_FLRCSSEL_0 0x00FF
+#define B_PCH_SATA_FLR_CLV_VSCID_FLRCSSEL_1 0x00FF
+#define V_PCH_SATA_FLR_CLV_VSCID_FLRCSSEL 0x0006
+#define R_PCH_SATA_FLRC 0xB4
+#define B_PCH_SATA_FLRC_TXP BIT8
+#define B_PCH_SATA_FLRC_INITFLR BIT0
+#define R_PCH_SATA_ATC 0xC0
+#define B_PCH_SATA_ATC_SST BIT3
+#define B_PCH_SATA_ATC_SPT BIT2
+#define B_PCH_SATA_ATC_PST BIT1
+#define B_PCH_SATA_ATC_PMT BIT0
+#define R_PCH_SATA_ATS 0xC4
+#define B_PCH_SATA_ATS_SST BIT3
+#define B_PCH_SATA_ATS_SPT BIT2
+#define B_PCH_SATA_ATS_PST BIT1
+#define B_PCH_SATA_ATS_PMT BIT0
+#define R_PCH_SATA_SP 0xD0
+#define B_PCH_SATA_SP 0xFFFFFFFF
+#define R_PCH_SATA_BFCS 0xE0
+#define B_PCH_SATA_BFCS_P5BFI BIT15
+#define B_PCH_SATA_BFCS_P4BFI BIT14
+#define B_PCH_SATA_BFCS_P3BFI BIT13
+#define B_PCH_SATA_BFCS_P2BFI BIT12
+#define B_PCH_SATA_BFCS_P2BFS BIT11
+#define B_PCH_SATA_BFCS_P2BFF BIT10
+#define B_PCH_SATA_BFCS_P1BFI BIT9
+#define B_PCH_SATA_BFCS_P0BFI BIT8
+#define B_PCH_SATA_BFCS_BIST_FIS_T BIT7
+#define B_PCH_SATA_BFCS_BIST_FIS_A BIT6
+#define B_PCH_SATA_BFCS_BIST_FIS_S BIT5
+#define B_PCH_SATA_BFCS_BIST_FIS_L BIT4
+#define B_PCH_SATA_BFCS_BIST_FIS_F BIT3
+#define B_PCH_SATA_BFCS_BIST_FIS_P BIT2
+#define R_PCH_SATA_BFTD1 0xE4
+#define B_PCH_SATA_BFTD1 0xFFFFFFFF
+#define R_PCH_SATA_BFTD2 0xE8
+#define B_PCH_SATA_BFTD2 0xFFFFFFFF
+
+//
+// Serial ATA Index/Data Pair Superset Registers
+//
+#define R_PCH_SATA_SIDPBA_SINDX 0x00
+#define R_PCH_SATA_SIDPBA_SDATA 0x04
+#define V_PCH_SATA_AHCI_SINDX_RIDX_SCTL 0x01
+#define V_PCH_SATA_AHCI_SINDX_PIDX_PORT0 0x0000
+#define V_PCH_SATA_AHCI_SINDX_PIDX_PORT1 0x0200
+#define V_PCH_SATA_AHCI_SINDX_PIDX_PORT2 0x0100
+#define V_PCH_SATA_AHCI_SINDX_PIDX_PORT3 0x0300
+#define V_PCH_SATA_SIDPBA_SDATA_GEN1 0x10
+#define V_PCH_SATA_SIDPBA_SDATA_GEN2 0x20
+#define V_PCH_SATA_SIDPBA_SDATA_GEN3 0x30
+#define B_PCH_SATA_SIDPBA_SCTL_DET (BIT3|BIT2|BIT1|BIT0)
+#define V_PCH_SATA_SIDPBA_SCTL_DET_COMRST 0x01
+#define V_PCH_SATA_SIDPBA_SCTL_DET_NOINT 0x00
+#define V_PCH_SATA_SIDP_BAR_LENGTH 0x10
+#define N_PCH_SATA_SIDP_BAR_ALIGNMENT 0x04
+
+//
+// AHCI BAR Area related Registers
+//
+#define R_PCH_SATA_AHCI_CAP 0x0
+#define B_PCH_SATA_AHCI_CAP_S64A BIT31
+#define B_PCH_SATA_AHCI_CAP_SCQA BIT30
+#define B_PCH_SATA_AHCI_CAP_SSNTF BIT29
+#define B_PCH_SATA_AHCI_CAP_SIS BIT28 ///< Supports Interlock Switch
+#define B_PCH_SATA_AHCI_CAP_SSS BIT27 ///< Supports Stagger Spin-up
+#define B_PCH_SATA_AHCI_CAP_SALP BIT26
+#define B_PCH_SATA_AHCI_CAP_SAL BIT25
+#define B_PCH_SATA_AHCI_CAP_SCLO BIT24 ///< Supports Command List Override
+#define B_PCH_SATA_AHCI_CAP_ISS_MASK (BIT23 | BIT22 | BIT21 | BIT20)
+#define N_PCH_SATA_AHCI_CAP_ISS 20 ///< Interface Speed Support
+#define V_PCH_SATA_AHCI_CAP_ISS_1_5_G 0x01
+#define V_PCH_SATA_AHCI_CAP_ISS_3_0_G 0x02
+#define V_PCH_SATA_AHCI_CAP_ISS_6_0_G 0x03
+#define B_PCH_SATA_AHCI_CAP_SNZO BIT19
+#define B_PCH_SATA_AHCI_CAP_SAM BIT18
+#define B_PCH_SATA_AHCI_CAP_PMS BIT17 ///< Supports Port Multiplier
+#define B_PCH_SATA_AHCI_CAP_PMD BIT15 ///< PIO Multiple DRQ Block
+#define B_PCH_SATA_AHCI_CAP_SSC BIT14
+#define B_PCH_SATA_AHCI_CAP_PSC BIT13
+#define B_PCH_SATA_AHCI_CAP_NCS 0x1F00
+#define B_PCH_SATA_AHCI_CAP_CCCS BIT7
+#define B_PCH_SATA_AHCI_CAP_EMS BIT6
+#define B_PCH_SATA_AHCI_CAP_SXS BIT5 ///< External SATA is supported
+#define B_PCH_SATA_AHCI_CAP_NPS 0x001F
+
+#define R_PCH_SATA_AHCI_GHC 0x04
+#define B_PCH_SATA_AHCI_GHC_AE BIT31
+#define B_PCH_SATA_AHCI_GHC_MRSM BIT2
+#define B_PCH_SATA_AHCI_GHC_IE BIT1
+#define B_PCH_SATA_AHCI_GHC_HR BIT0
+
+#define R_PCH_SATA_AHCI_IS 0x08
+#define B_PCH_SATA_AHCI_IS_PORT5 BIT5
+#define B_PCH_SATA_AHCI_IS_PORT4 BIT4
+#define B_PCH_SATA_AHCI_IS_PORT3 BIT3
+#define B_PCH_SATA_AHCI_IS_PORT2 BIT2
+#define B_PCH_SATA_AHCI_IS_PORT1 BIT1
+#define B_PCH_SATA_AHCI_IS_PORT0 BIT0
+#define R_PCH_SATA_AHCI_PI 0x0C
+#define B_PCH_H_SATA_PORT_MASK 0x3F
+#define B_PCH_LP_SATA_PORT_MASK 0x0F
+#define B_PCH_SATA_PORT5_IMPLEMENTED BIT5
+#define B_PCH_SATA_PORT4_IMPLEMENTED BIT4
+#define B_PCH_SATA_PORT3_IMPLEMENTED BIT3
+#define B_PCH_SATA_PORT2_IMPLEMENTED BIT2
+#define B_PCH_SATA_PORT1_IMPLEMENTED BIT1
+#define B_PCH_SATA_PORT0_IMPLEMENTED BIT0
+#define R_PCH_SATA_AHCI_VS 0x10
+#define B_PCH_SATA_AHCI_VS_MJR 0xFFFF0000
+#define B_PCH_SATA_AHCI_VS_MNR 0x0000FFFF
+#define R_PCH_SATA_AHCI_EM_LOC 0x1C
+#define B_PCH_SATA_AHCI_EM_LOC_OFST 0xFFFF0000
+#define B_PCH_SATA_AHCI_EM_LOC_SZ 0x0000FFFF
+#define R_PCH_SATA_AHCI_EM_CTRL 0x20
+#define B_PCH_SATA_AHCI_EM_CTRL_ATTR_ALHD BIT26
+#define B_PCH_SATA_AHCI_EM_CTRL_ATTR_XMT BIT25
+#define B_PCH_SATA_AHCI_EM_CTRL_ATTR_SMB BIT24
+#define B_PCH_SATA_AHCI_EM_CTRL_SUPP_SGPIO BIT19
+#define B_PCH_SATA_AHCI_EM_CTRL_SUPP_SES2 BIT18
+#define B_PCH_SATA_AHCI_EM_CTRL_SUPP_SAFTE BIT17
+#define B_PCH_SATA_AHCI_EM_CTRL_SUPP_LED BIT16
+#define B_PCH_SATA_AHCI_EM_CTRL_RST BIT9
+#define B_PCH_SATA_AHCI_EM_CTRL_CTL_TM BIT8
+#define B_PCH_SATA_AHCI_EM_CTRL_STS_MR BIT0
+#define R_PCH_SATA_AHCI_CAP2 0x24
+#define B_PCH_SATA_AHCI_CAP2_DESO BIT5
+#define B_PCH_SATA_AHCI_CAP2_SADM BIT4
+#define B_PCH_SATA_AHCI_CAP2_SDS BIT3
+#define B_PCH_SATA_AHCI_CAP2_APST BIT2 ///< Automatic Partial to Slumber Transitions
+#define R_PCH_SATA_AHCI_VSP 0xA0
+#define B_PCH_SATA_AHCI_VSP_SLPD BIT0
+#define R_PCH_SATA_AHCI_RSTF 0xC8 ///< RST Feature Capabilities
+#define B_PCH_SATA_AHCI_RSTF_OUD (BIT11 | BIT10)
+#define N_PCH_SATA_AHCI_RSTF_OUD 10
+#define B_PCH_SATA_AHCI_RSTF_SEREQ BIT9
+#define B_PCH_SATA_AHCI_RSTF_IROES BIT8
+#define B_PCH_SATA_AHCI_RSTF_LEDL BIT7
+#define B_PCH_SATA_AHCI_RSTF_HDDLK BIT6
+#define B_PCH_SATA_AHCI_RSTF_IRSTOROM BIT5
+#define B_PCH_SATA_AHCI_RSTF_RSTE BIT4
+#define B_PCH_SATA_AHCI_RSTF_R5E BIT3
+#define B_PCH_SATA_AHCI_RSTF_R10E BIT2
+#define B_PCH_SATA_AHCI_RSTF_R1E BIT1
+#define B_PCH_SATA_AHCI_RSTF_R0E BIT0
+#define B_PCH_SATA_AHCI_RSTF_LOWBYTES 0x1FF
+#define R_PCH_SATA_AHCI_P0CLB 0x100
+#define R_PCH_SATA_AHCI_P1CLB 0x180
+#define R_PCH_SATA_AHCI_P2CLB 0x200
+#define R_PCH_SATA_AHCI_P3CLB 0x280
+#define R_PCH_SATA_AHCI_P4CLB 0x300
+#define R_PCH_SATA_AHCI_P5CLB 0x380
+#define R_PCH_SATA_AHCI_P6CLB 0x400
+#define R_PCH_SATA_AHCI_P7CLB 0x480
+#define B_PCH_SATA_AHCI_PXCLB 0xFFFFFC00
+#define R_PCH_SATA_AHCI_P0CLBU 0x104
+#define R_PCH_SATA_AHCI_P1CLBU 0x184
+#define R_PCH_SATA_AHCI_P2CLBU 0x204
+#define R_PCH_SATA_AHCI_P3CLBU 0x284
+#define R_PCH_SATA_AHCI_P4CLBU 0x304
+#define R_PCH_SATA_AHCI_P5CLBU 0x384
+#define R_PCH_SATA_AHCI_P6CLBU 0x404
+#define B_PCH_SATA_AHCI_PXCLBU 0xFFFFFFFF
+#define R_PCH_SATA_AHCI_P0FB 0x108
+#define R_PCH_SATA_AHCI_P1FB 0x188
+#define R_PCH_SATA_AHCI_P2FB 0x208
+#define R_PCH_SATA_AHCI_P3FB 0x288
+#define R_PCH_SATA_AHCI_P4FB 0x308
+#define R_PCH_SATA_AHCI_P5FB 0x388
+#define R_PCH_SATA_AHCI_P6FB 0x408
+#define B_PCH_SATA_AHCI_PXFB 0xFFFFFF00
+#define R_PCH_SATA_AHCI_P0FBU 0x10C
+#define R_PCH_SATA_AHCI_P1FBU 0x18C
+#define R_PCH_SATA_AHCI_P2FBU 0x20C
+#define R_PCH_SATA_AHCI_P3FBU 0x28C
+#define R_PCH_SATA_AHCI_P4FBU 0x30C
+#define R_PCH_SATA_AHCI_P5FBU 0x38C
+#define R_PCH_SATA_AHCI_P6FBU 0x40C
+#define B_PCH_SATA_AHCI_PXFBU 0xFFFFFFFF
+#define R_PCH_SATA_AHCI_P0IS 0x110
+#define R_PCH_SATA_AHCI_P1IS 0x190
+#define R_PCH_SATA_AHCI_P2IS 0x210
+#define R_PCH_SATA_AHCI_P3IS 0x290
+#define R_PCH_SATA_AHCI_P4IS 0x310
+#define R_PCH_SATA_AHCI_P5IS 0x390
+#define R_PCH_SATA_AHCI_P6IS 0x410
+#define B_PCH_SATA_AHCI_PXIS_CPDS BIT31
+#define B_PCH_SATA_AHCI_PXIS_TFES BIT30
+#define B_PCH_SATA_AHCI_PXIS_HBFS BIT29
+#define B_PCH_SATA_AHCI_PXIS_HBDS BIT28
+#define B_PCH_SATA_AHCI_PXIS_IFS BIT27
+#define B_PCH_SATA_AHCI_PXIS_INFS BIT26
+#define B_PCH_SATA_AHCI_PXIS_OFS BIT24
+#define B_PCH_SATA_AHCI_PXIS_IPMS BIT23
+#define B_PCH_SATA_AHCI_PXIS_PRCS BIT22
+#define B_PCH_SATA_AHCI_PXIS_DIS BIT7
+#define B_PCH_SATA_AHCI_PXIS_PCS BIT6
+#define B_PCH_SATA_AHCI_PXIS_DPS BIT5
+#define B_PCH_SATA_AHCI_PXIS_UFS BIT4
+#define B_PCH_SATA_AHCI_PXIS_SDBS BIT3
+#define B_PCH_SATA_AHCI_PXIS_DSS BIT2
+#define B_PCH_SATA_AHCI_PXIS_PSS BIT1
+#define B_PCH_SATA_AHCI_PXIS_DHRS BIT0
+#define R_PCH_SATA_AHCI_P0IE 0x114
+#define R_PCH_SATA_AHCI_P1IE 0x194
+#define R_PCH_SATA_AHCI_P2IE 0x214
+#define R_PCH_SATA_AHCI_P3IE 0x294
+#define R_PCH_SATA_AHCI_P4IE 0x314
+#define R_PCH_SATA_AHCI_P5IE 0x394
+#define R_PCH_SATA_AHCI_P6IE 0x414
+#define B_PCH_SATA_AHCI_PXIE_CPDE BIT31
+#define B_PCH_SATA_AHCI_PXIE_TFEE BIT30
+#define B_PCH_SATA_AHCI_PXIE_HBFE BIT29
+#define B_PCH_SATA_AHCI_PXIE_HBDE BIT28
+#define B_PCH_SATA_AHCI_PXIE_IFE BIT27
+#define B_PCH_SATA_AHCI_PXIE_INFE BIT26
+#define B_PCH_SATA_AHCI_PXIE_OFE BIT24
+#define B_PCH_SATA_AHCI_PXIE_IPME BIT23
+#define B_PCH_SATA_AHCI_PXIE_PRCE BIT22
+#define B_PCH_SATA_AHCI_PXIE_DIE BIT7
+#define B_PCH_SATA_AHCI_PXIE_PCE BIT6
+#define B_PCH_SATA_AHCI_PXIE_DPE BIT5
+#define B_PCH_SATA_AHCI_PXIE_UFIE BIT4
+#define B_PCH_SATA_AHCI_PXIE_SDBE BIT3
+#define B_PCH_SATA_AHCI_PXIE_DSE BIT2
+#define B_PCH_SATA_AHCI_PXIE_PSE BIT1
+#define B_PCH_SATA_AHCI_PXIE_DHRE BIT0
+#define R_PCH_SATA_AHCI_P0CMD 0x118
+#define R_PCH_SATA_AHCI_P1CMD 0x198
+#define R_PCH_SATA_AHCI_P2CMD 0x218
+#define R_PCH_SATA_AHCI_P3CMD 0x298
+#define R_PCH_SATA_AHCI_P4CMD 0x318
+#define R_PCH_SATA_AHCI_P5CMD 0x398
+#define R_PCH_SATA_AHCI_P6CMD 0x418
+#define B_PCH_SATA_AHCI_PxCMD_ICC (BIT31 | BIT30 | BIT29 | BIT28)
+#define B_PCH_SATA_AHCI_PxCMD_MASK (BIT27 | BIT26 | BIT21 | BIT22 | BIT19 | BIT18)
+#define B_PCH_SATA_AHCI_PxCMD_ASP BIT27
+#define B_PCH_SATA_AHCI_PxCMD_ALPE BIT26
+#define B_PCH_SATA_AHCI_PxCMD_DLAE BIT25
+#define B_PCH_SATA_AHCI_PxCMD_ATAPI BIT24
+#define B_PCH_SATA_AHCI_PxCMD_APSTE BIT23
+#define B_PCH_SATA_AHCI_PxCMD_SUD BIT1
+#define R_PCH_SATA_AHCI_P0DEVSLP 0x144
+#define R_PCH_SATA_AHCI_P1DEVSLP 0x1C4
+#define R_PCH_SATA_AHCI_P2DEVSLP 0x244
+#define R_PCH_SATA_AHCI_P3DEVSLP 0x2C4
+#define B_PCH_SATA_AHCI_PxDEVSLP_DSP BIT1
+#define B_PCH_SATA_AHCI_PxDEVSLP_ADSE BIT0
+#define B_PCH_SATA_AHCI_PxDEVSLP_DITO_MASK 0x01FF8000
+#define V_PCH_SATA_AHCI_PxDEVSLP_DITO_625 0x01388000
+#define B_PCH_SATA_AHCI_PxDEVSLP_DM_MASK 0x1E000000
+#define V_PCH_SATA_AHCI_PxDEVSLP_DM_16 0x1E000000
+#define B_PCH_SATA_AHCI_PxCMD_ESP BIT21 ///< Used with an external SATA device
+#define B_PCH_SATA_AHCI_PxCMD_MPSP BIT19 ///< Mechanical Switch Attached to Port
+#define B_PCH_SATA_AHCI_PxCMD_HPCP BIT18 ///< Hotplug capable
+#define B_PCH_SATA_AHCI_PxCMD_CR BIT15
+#define B_PCH_SATA_AHCI_PxCMD_FR BIT14
+#define B_PCH_SATA_AHCI_PxCMD_ISS BIT13
+#define B_PCH_SATA_AHCI_PxCMD_CCS 0x00001F00
+#define B_PCH_SATA_AHCI_PxCMD_FRE BIT4
+#define B_PCH_SATA_AHCI_PxCMD_CLO BIT3
+#define B_PCH_SATA_AHCI_PxCMD_POD BIT2
+#define B_PCH_SATA_AHCI_PxCMD_SUD BIT1
+#define B_PCH_SATA_AHCI_PxCMD_ST BIT0
+#define R_PCH_SATA_AHCI_P0TFD 0x120
+#define R_PCH_SATA_AHCI_P1TFD 0x1A0
+#define R_PCH_SATA_AHCI_P2TFD 0x220
+#define R_PCH_SATA_AHCI_P3TFD 0x2A0
+#define R_PCH_SATA_AHCI_P4TFD 0x320
+#define R_PCH_SATA_AHCI_P5TFD 0x3A0
+#define R_PCH_SATA_AHCI_P6TFD 0x420
+#define B_PCH_SATA_AHCI_PXTFD_ERR 0x0000FF00
+#define B_PCH_SATA_AHCI_PXTFD_STS 0x000000FF
+#define R_PCH_SATA_AHCI_P0SIG 0x124
+#define R_PCH_SATA_AHCI_P1SIG 0x1A4
+#define R_PCH_SATA_AHCI_P2SIG 0x224
+#define R_PCH_SATA_AHCI_P3SIG 0x2A4
+#define R_PCH_SATA_AHCI_P4SIG 0x324
+#define R_PCH_SATA_AHCI_P5SIG 0x3A4
+#define R_PCH_SATA_AHCI_P6SIG 0x424
+#define B_PCH_SATA_AHCI_PXSIG_LBA_HR 0xFF000000
+#define B_PCH_SATA_AHCI_PXSIG_LBA_MR 0x00FF0000
+#define B_PCH_SATA_AHCI_PXSIG_LBA_LR 0x0000FF00
+#define B_PCH_SATA_AHCI_PXSIG_SCR 0x000000FF
+#define R_PCH_SATA_AHCI_P0SSTS 0x128
+#define R_PCH_SATA_AHCI_P1SSTS 0x1A8
+#define R_PCH_SATA_AHCI_P2SSTS 0x228
+#define R_PCH_SATA_AHCI_P3SSTS 0x2A8
+#define R_PCH_SATA_AHCI_P4SSTS 0x328
+#define R_PCH_SATA_AHCI_P5SSTS 0x3A8
+#define R_PCH_SATA_AHCI_P6SSTS 0x428
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_0 0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_1 0x00000100
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_2 0x00000200
+#define B_PCH_SATA_AHCI_PXSSTS_IPM_6 0x00000600
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_0 0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_1 0x00000010
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_2 0x00000020
+#define B_PCH_SATA_AHCI_PXSSTS_SPD_3 0x00000030
+#define B_PCH_SATA_AHCI_PXSSTS_DET_0 0x00000000
+#define B_PCH_SATA_AHCI_PXSSTS_DET_1 0x00000001
+#define B_PCH_SATA_AHCI_PXSSTS_DET_3 0x00000003
+#define B_PCH_SATA_AHCI_PXSSTS_DET_4 0x00000004
+#define R_PCH_SATA_AHCI_P0SCTL 0x12C
+#define R_PCH_SATA_AHCI_P1SCTL 0x1AC
+#define R_PCH_SATA_AHCI_P2SCTL 0x22C
+#define R_PCH_SATA_AHCI_P3SCTL 0x2AC
+#define R_PCH_SATA_AHCI_P4SCTL 0x32C
+#define R_PCH_SATA_AHCI_P5SCTL 0x3AC
+#define R_PCH_SATA_AHCI_P6SCTL 0x42C
+#define B_PCH_SATA_AHCI_PXSCTL_IPM 0x00000F00
+#define V_PCH_SATA_AHCI_PXSCTL_IPM_0 0x00000000
+#define V_PCH_SATA_AHCI_PXSCTL_IPM_1 0x00000100
+#define V_PCH_SATA_AHCI_PXSCTL_IPM_2 0x00000200
+#define V_PCH_SATA_AHCI_PXSCTL_IPM_3 0x00000300
+#define B_PCH_SATA_AHCI_PXSCTL_SPD 0x000000F0
+#define V_PCH_SATA_AHCI_PXSCTL_SPD_0 0x00000000
+#define V_PCH_SATA_AHCI_PXSCTL_SPD_1 0x00000010
+#define V_PCH_SATA_AHCI_PXSCTL_SPD_2 0x00000020
+#define V_PCH_SATA_AHCI_PXSCTL_SPD_3 0x00000030
+#define B_PCH_SATA_AHCI_PXSCTL_DET 0x0000000F
+#define V_PCH_SATA_AHCI_PXSCTL_DET_0 0x00000000
+#define V_PCH_SATA_AHCI_PXSCTL_DET_1 0x00000001
+#define V_PCH_SATA_AHCI_PXSCTL_DET_4 0x00000004
+#define R_PCH_SATA_AHCI_P0SERR 0x130
+#define R_PCH_SATA_AHCI_P1SERR 0x1B0
+#define R_PCH_SATA_AHCI_P2SERR 0x230
+#define R_PCH_SATA_AHCI_P3SERR 0x2B0
+#define R_PCH_SATA_AHCI_P4SERR 0x330
+#define R_PCH_SATA_AHCI_P5SERR 0x3B0
+#define R_PCH_SATA_AHCI_P6SERR 0x430
+#define B_PCH_SATA_AHCI_PXSERR_EXCHG BIT26
+#define B_PCH_SATA_AHCI_PXSERR_UN_FIS_TYPE BIT25
+#define B_PCH_SATA_AHCI_PXSERR_TRSTE_24 BIT24
+#define B_PCH_SATA_AHCI_PXSERR_TRSTE_23 BIT23
+#define B_PCH_SATA_AHCI_PXSERR_HANDSHAKE BIT22
+#define B_PCH_SATA_AHCI_PXSERR_CRC_ERROR BIT21
+#define B_PCH_SATA_AHCI_PXSERR_10B8B_DECERR BIT19
+#define B_PCH_SATA_AHCI_PXSERR_COMM_WAKE BIT18
+#define B_PCH_SATA_AHCI_PXSERR_PHY_ERROR BIT17
+#define B_PCH_SATA_AHCI_PXSERR_PHY_RDY_CHG BIT16
+#define B_PCH_SATA_AHCI_PXSERR_INTRNAL_ERR BIT11
+#define B_PCH_SATA_AHCI_PXSERR_PROTOCOL_ERR BIT10
+#define B_PCH_SATA_AHCI_PXSERR_PCDIE BIT9
+#define B_PCH_SATA_AHCI_PXSERR_TDIE BIT8
+#define B_PCH_SATA_AHCI_PXSERR_RCE BIT1
+#define B_PCH_SATA_AHCI_PXSERR_RDIE BIT0
+#define R_PCH_SATA_AHCI_P0SACT 0x134
+#define R_PCH_SATA_AHCI_P1SACT 0x1B4
+#define R_PCH_SATA_AHCI_P2SACT 0x234
+#define R_PCH_SATA_AHCI_P3SACT 0x2B4
+#define R_PCH_SATA_AHCI_P4SACT 0x334
+#define R_PCH_SATA_AHCI_P5SACT 0x3B4
+#define R_PCH_SATA_AHCI_P6SACT 0x434
+#define B_PCH_SATA_AHCI_PXSACT_DS 0xFFFFFFFF
+#define R_PCH_SATA_AHCI_P0CI 0x138
+#define R_PCH_SATA_AHCI_P1CI 0x1B8
+#define R_PCH_SATA_AHCI_P2CI 0x238
+#define R_PCH_SATA_AHCI_P3CI 0x2B8
+#define R_PCH_SATA_AHCI_P4CI 0x338
+#define R_PCH_SATA_AHCI_P5CI 0x3B8
+#define R_PCH_SATA_AHCI_P6CI 0x438
+#define B_PCH_SATA_AHCI_PXCI 0xFFFFFFFF
+
+//
+// Macros of ICH capabilities for SATA controller which are used by SATA controller driver
+//
+//
+//
+// Define the individual capabilities of each sata controller
+//
+#define LPTH_SATA_MAX_CONTROLLERS 2 ///< max sata controllers number supported
+#define LPTLP_SATA_MAX_CONTROLLERS 1 ///< max sata controllers number supported
+#define PCH_IDE_MAX_CHANNELS 2 ///< max channels number of single sata controller
+#define PCH_IDE_MAX_DEVICES 2 ///< max devices number of single sata channel
+#define LPTH_AHCI_MAX_PORTS 6 ///< max number of sata ports in LPTH
+#define LPTLP_AHCI_MAX_PORTS 4 ///< max number of sata ports in LPTLP
+#define PCH_SATA_DEVICE_ID_INVALID 0xFFFF
+#define PCH_SATA_1_DEVICE_NUMBER PCI_DEVICE_NUMBER_PCH_SATA
+#define PCH_SATA_1_FUNCTION_NUMBER PCI_FUNCTION_NUMBER_PCH_SATA
+#define PCH_H_AHCI_1_MAX_PORTS 6 ///< max number of ports in sata in PCH
+#define PCH_LP_AHCI_1_MAX_PORTS 4 ///< max number of ports in sata1 in PCH
+#define PCH_IDE_1_MAX_CHANNELS 2
+#define PCH_IDE_1_MAX_DEVICES 2
+#define PCH_IDE_1_MAX_PORTS 4
+
+#define PCH_SATA_2_DEVICE_NUMBER PCI_DEVICE_NUMBER_PCH_SATA2
+#define PCH_SATA_2_FUNCTION_NUMBER PCI_FUNCTION_NUMBER_PCH_SATA2
+#define PCH_AHCI_2_MAX_PORTS 2 ///< number of ports in sata2 in PCH
+#define PCH_IDE_2_MAX_CHANNELS 2
+#define PCH_IDE_2_MAX_DEVICES 2
+#define PCH_IDE_2_MAX_PORTS 2
+
+//
+// GPIO SATA0GP is the Sata port 0 reset pin.
+//
+#define PCH_GPIO_SATA_PORT0_RESET 21
+#define PCH_LP_GPIO_SATA_PORT0_RESET (R_PCH_GP_N_CONFIG0 + (34 * 0x08))
+//
+// GPIO SATA1GP is the Sata port 1 reset pin.
+//
+#define PCH_GPIO_SATA_PORT1_RESET 19
+#define PCH_LP_GPIO_SATA_PORT1_RESET (R_PCH_GP_N_CONFIG0 + (35 * 0x08))
+
+//
+// GPIO SATA2GP is the Sata port 2 reset pin.
+//
+#define PCH_GPIO_SATA_PORT2_RESET 36
+#define PCH_LP_GPIO_SATA_PORT2_RESET (R_PCH_GP_N_CONFIG0 + (36 * 0x08))
+
+//
+// GPIO SATA3GP is the Sata port 3 reset pin.
+//
+#define PCH_GPIO_SATA_PORT3_RESET 37
+#define PCH_LP_GPIO_SATA_PORT3_RESET (R_PCH_GP_N_CONFIG0 + (37 * 0x08))
+
+//
+// GPIO SATA4GP is the Sata port 4 reset pin.
+//
+#define PCH_GPIO_SATA_PORT4_RESET 16
+//
+// GPIO SATA5GP is the Sata port 5 reset pin.
+//
+#define PCH_GPIO_SATA_PORT5_RESET 49
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSerialIo.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSerialIo.h
new file mode 100644
index 0000000..c99d758
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSerialIo.h
@@ -0,0 +1,169 @@
+/** @file
+ Register names for PCH Serial IO Controllers
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_CPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_SERIAL_IO_H_
+#define _PCH_REGS_SERIAL_IO_H_
+
+#ifdef SERIAL_IO_FLAG
+
+//
+// Serial IO DMA Controller Registers (D21:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_DMA 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_DMA 0
+#define R_PCH_LP_SERIAL_IO_DMA_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_DMA_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_DMA_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_DMA_DEVICE_ID 0x9C60
+
+//
+// Serial IO I2C0 Controller Registers (D21:F1)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_I2C0 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_I2C0 1
+#define R_PCH_LP_SERIAL_IO_I2C0_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_I2C0_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_I2C0_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_I2C0_DEVICE_ID 0x9C61
+
+//
+// Serial IO I2C0 Controller Registers (D21:F2)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_I2C1 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_I2C1 2
+#define R_PCH_LP_SERIAL_IO_I2C1_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_I2C1_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_I2C1_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_I2C1_DEVICE_ID 0x9C62
+
+//
+// Serial IO SPI0 Controller Registers (D21:F3)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_SPI0 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_SPI0 3
+#define R_PCH_LP_SERIAL_IO_SPI0_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_SPI0_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_SPI0_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_SPI0_DEVICE_ID 0x9C65
+
+//
+// Serial IO SPI1 Controller Registers (D21:F4)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_SPI1 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_SPI1 4
+#define R_PCH_LP_SERIAL_IO_SPI1_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_SPI1_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_SPI1_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_SPI1_DEVICE_ID 0x9C66
+
+//
+// Serial IO UART0 Controller Registers (D21:F5)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_UART0 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_UART0 5
+#define R_PCH_LP_SERIAL_IO_UART0_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_UART0_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_UART0_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_UART0_DEVICE_ID 0x9C63
+
+//
+// Serial IO UART1 Controller Registers (D21:F6)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_UART1 21
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_UART1 6
+#define R_PCH_LP_SERIAL_IO_UART1_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_UART1_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_UART1_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_UART1_DEVICE_ID 0x9C64
+
+//
+// Serial IO SDIO Controller Registers (D23:F0)
+//
+#define PCI_DEVICE_NUMBER_PCH_LP_SERIAL_IO_SDIO 23
+#define PCI_FUNCTION_NUMBER_PCH_LP_SERIAL_IO_SDIO 0
+#define R_PCH_LP_SERIAL_IO_SDIO_VENDOR_ID 0x00
+#define V_PCH_LP_SERIAL_IO_SDIO_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_LP_SERIAL_IO_SDIO_DEVICE_ID 0x02
+#define V_PCH_LP_SERIAL_IO_SDIO_DEVICE_ID 0x9C35
+#define R_PCH_LP_SERIAL_IO_SDIO_PPR_CMD12 0x3C
+#define R_PCH_LP_SERIAL_IO_SDIO_PPR_GEN 0x1008
+#define B_PCH_LP_SERIAL_IO_SDIO_PPR_GEN_LTR_MODE BIT2
+#define R_PCH_LP_SERIAL_IO_SDIO_PPR_SW_LTR 0x1010
+
+
+#define R_PCH_LP_SERIAL_IO_SDIO_SLAVE_DELAY_DDR50_MODE 0x1034
+
+#define V_LP_SERIAL_IO_DEV_MIN_FUN 0
+#define V_LP_SERIAL_IO_DEV_MAX_FUN 6
+
+//
+// Serial IO Controllers General PCI Configuration Registers
+//
+#define R_PCH_LP_SERIAL_IO_VENDOR_ID 0x00
+#define R_PCH_LP_SERIAL_IO_DEVICE_ID 0x02
+#define R_PCH_LP_SERIAL_IO_COMMAND 0x04
+#define B_PCH_LP_SERIAL_IO_COMMAND_BME BIT2
+#define B_PCH_LP_SERIAL_IO_COMMAND_MSE BIT1
+#define R_PCH_LP_SERIAL_IO_BAR0 0x10
+#define B_PCH_LP_SERIAL_IO_BAR0_BAR 0xFFFFF000
+#define R_PCH_LP_SERIAL_IO_BAR1 0x14
+#define B_PCH_LP_SERIAL_IO_BAR1_BAR 0xFFFFF000
+#define V_PCH_LP_SERIAL_IO_BAR_SIZE (4 * 1024)
+#define V_PCH_LP_SERIAL_SDIO_BAR_SIZE (8 * 1024)
+#define N_PCH_LP_SERIAL_IO_BAR_ALIGNMENT 12
+#define R_PCH_LP_SERIAL_IO_PME_CTRL_STS 0x84
+#define B_PCH_LP_SERIAL_IO_PME_CTRL_STS_PWR_ST (BIT1| BIT0)
+
+//
+// Serial IO Controllers Private Registers
+//
+#define R_PCH_LP_SERIAL_IO_PPR_RST 0x804
+#define B_PCH_LP_SERIAL_IO_PPR_RST_APB BIT0
+#define B_PCH_LP_SERIAL_IO_PPR_RST_FUNC BIT1
+#define R_PCH_LP_SERIAL_IO_PPR_GEN 0x808
+#define B_PCH_LP_SERIAL_IO_PPR_GEN_LTR_MODE BIT2
+#define B_PCH_LP_SERIAL_IO_PPR_GEN_IO_VOLTAGE_SEL BIT3
+#define R_PCH_LP_SERIAL_IO_PPR_AUTO_LTR 0x814
+
+#define R_PCH_LP_SERIAL_IO_GPIODF0 0x154
+#define B_PCH_LP_SERIAL_IO_GPIODF0_SPI_IDLE_DET_EN BIT0
+#define B_PCH_LP_SERIAL_IO_GPIODF0_I2C_IDLE_DET_EN BIT1
+#define B_PCH_LP_SERIAL_IO_GPIODF0_UART_IDLE_DET_EN BIT2
+#define B_PCH_LP_SERIAL_IO_GPIODF0_DMA_IDLE_DET_EN BIT3
+#define B_PCH_LP_SERIAL_IO_GPIODF0_SDIO_IDLE_DET_EN BIT4
+
+#endif // SERIAL_IO_FLAG
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSmbus.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSmbus.h
new file mode 100644
index 0000000..a848108
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSmbus.h
@@ -0,0 +1,172 @@
+/** @file
+ Register names for PCH Smbus Device.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_SMBUS_H_
+#define _PCH_REGS_SMBUS_H_
+
+//
+// SMBus Controller Registers (D31:F3)
+//
+#define PCI_DEVICE_NUMBER_PCH_SMBUS 31
+#define PCI_FUNCTION_NUMBER_PCH_SMBUS 3
+#define R_PCH_SMBUS_VENDOR_ID 0x00
+#define V_PCH_SMBUS_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_SMBUS_DEVICE_ID 0x02
+#define V_PCH_LPTH_SMBUS_DEVICE_ID 0x8C22
+#define V_PCH_LPTLP_SMBUS_DEVICE_ID 0x9C22
+#define R_PCH_SMBUS_PCICMD 0x04
+#define B_PCH_SMBUS_PCICMD_INTR_DIS BIT10
+#define B_PCH_SMBUS_PCICMD_FBE BIT9
+#define B_PCH_SMBUS_PCICMD_SERR_EN BIT8
+#define B_PCH_SMBUS_PCICMD_WCC BIT7
+#define B_PCH_SMBUS_PCICMD_PER BIT6
+#define B_PCH_SMBUS_PCICMD_VPS BIT5
+#define B_PCH_SMBUS_PCICMD_PMWE BIT4
+#define B_PCH_SMBUS_PCICMD_SCE BIT3
+#define B_PCH_SMBUS_PCICMD_BME BIT2
+#define B_PCH_SMBUS_PCICMD_MSE BIT1
+#define B_PCH_SMBUS_PCICMD_IOSE BIT0
+#define R_PCH_SMBUS_PCISTS 0x06
+#define B_PCH_SMBUS_PCISTS_DPE BIT15
+#define B_PCH_SMBUS_PCISTS_SSE BIT14
+#define B_PCH_SMBUS_PCISTS_RMA BIT13
+#define B_PCH_SMBUS_PCISTS_RTA BIT12
+#define B_PCH_SMBUS_PCISTS_STA BIT11
+#define B_PCH_SMBUS_PCISTS_DEVT (BIT10 | BIT9)
+#define B_PCH_SMBUS_PCISTS_DPED BIT8
+#define B_PCH_SMBUS_PCISTS_FB2BC BIT7
+#define B_PCH_SMBUS_PCISTS_UDF BIT6
+#define B_PCH_SMBUS_PCISTS_66MHZ_CAP BIT5
+#define B_PCH_SMBUS_PCISTS_CAP_LIST BIT4
+#define B_PCH_SMBUS_PCISTS_INTS BIT3
+#define R_PCH_SMBUS_RID 0x08
+#define B_PCH_SMBUS_RID 0xFF
+#define R_PCH_SMBUS_SCC 0x0A
+#define V_PCH_SMBUS_SCC 0x05
+#define R_PCH_SMBUS_BCC 0x0B
+#define V_PCH_SMBUS_BCC 0x0C
+#define R_PCH_SMBUS_BAR0 0x10
+#define B_PCH_SMBUS_BAR0_BAR 0xFFFFFF00
+#define B_PCH_SMBUS_BAR0_PREF BIT3
+#define B_PCH_SMBUS_BAR0_ADDRNG (BIT2 | BIT1)
+#define B_PCH_SMBUS_BAR0_MSI BIT0
+#define R_PCH_SMBUS_BAR1 0x14
+#define B_PCH_SMBUS_BAR1_BAR 0xFFFFFFFF
+#define R_PCH_SMBUS_BASE 0x20
+#define V_PCH_SMBUS_BASE_SIZE (1 << 5)
+#define B_PCH_SMBUS_BASE_BAR 0x0000FFE0
+#define R_PCH_SMBUS_SVID 0x2C
+#define B_PCH_SMBUS_SVID 0xFFFF
+#define R_PCH_SMBUS_SID 0x2E
+#define B_PCH_SMBUS_SID 0xFFFF
+#define R_PCH_SMBUS_INT_LN 0x3C
+#define B_PCH_SMBUS_INT_LN 0xFF
+#define R_PCH_SMBUS_INT_PN 0x3D
+#define B_PCH_SMBUS_INT_PN 0xFF
+#define R_PCH_SMBUS_HOSTC 0x40
+#define B_PCH_SMBUS_HOSTC_SPDWD BIT4
+#define B_PCH_SMBUS_HOSTC_SSRESET BIT3
+#define B_PCH_SMBUS_HOSTC_I2C_EN BIT2
+#define B_PCH_SMBUS_HOSTC_SMI_EN BIT1
+#define B_PCH_SMBUS_HOSTC_HST_EN BIT0
+
+//
+// SMBus I/O Registers
+//
+#define R_PCH_SMBUS_HSTS 0x00 ///< Host Status Register R/W
+#define B_PCH_SMBUS_HBSY 0x01
+#define B_PCH_SMBUS_INTR 0x02
+#define B_PCH_SMBUS_DERR 0x04
+#define B_PCH_SMBUS_BERR 0x08
+#define B_PCH_SMBUS_FAIL 0x10
+#define B_PCH_SMBUS_SMBALERT_STS 0x20
+#define B_PCH_SMBUS_IUS 0x40
+#define B_PCH_SMBUS_BYTE_DONE_STS 0x80
+#define B_PCH_SMBUS_ERROR (B_PCH_SMBUS_DERR | B_PCH_SMBUS_BERR | B_PCH_SMBUS_FAIL)
+#define B_PCH_SMBUS_HSTS_ALL 0xFF
+#define R_PCH_SMBUS_HCTL 0x02 ///< Host Control Register R/W
+#define B_PCH_SMBUS_INTREN 0x01
+#define B_PCH_SMBUS_KILL 0x02
+#define B_PCH_SMBUS_SMB_CMD 0x1C
+#define V_PCH_SMBUS_SMB_CMD_QUICK 0x00
+#define V_PCH_SMBUS_SMB_CMD_BYTE 0x04
+#define V_PCH_SMBUS_SMB_CMD_BYTE_DATA 0x08
+#define V_PCH_SMBUS_SMB_CMD_WORD_DATA 0x0C
+#define V_PCH_SMBUS_SMB_CMD_PROCESS_CALL 0x10
+#define V_PCH_SMBUS_SMB_CMD_BLOCK 0x14
+#define V_PCH_SMBUS_SMB_CMD_IIC_READ 0x18
+#define V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS 0x1C
+#define B_PCH_SMBUS_LAST_BYTE 0x20
+#define B_PCH_SMBUS_START 0x40
+#define B_PCH_SMBUS_PEC_EN 0x80
+#define R_PCH_SMBUS_HCMD 0x03 ///< Host Command Register R/W
+#define R_PCH_SMBUS_TSA 0x04 ///< Transmit Slave Address Register R/W
+#define B_PCH_SMBUS_RW_SEL 0x01
+#define B_PCH_SMBUS_READ 0x01 // RW
+#define B_PCH_SMBUS_WRITE 0x00 // RW
+#define B_PCH_SMBUS_ADDRESS 0xFE
+#define R_PCH_SMBUS_HD0 0x05 ///< Data 0 Register R/W
+#define R_PCH_SMBUS_HD1 0x06 ///< Data 1 Register R/W
+#define R_PCH_SMBUS_HBD 0x07 ///< Host Block Data Register R/W
+#define R_PCH_SMBUS_PEC 0x08 ///< Packet Error Check Data Register R/W
+#define R_PCH_SMBUS_RSA 0x09 ///< Receive Slave Address Register R/W
+#define B_PCH_SMBUS_SLAVE_ADDR 0x7F
+#define R_PCH_SMBUS_SD 0x0A ///< Receive Slave Data Register R/W
+#define R_PCH_SMBUS_AUXS 0x0C ///< Auxiliary Status Register R/WC
+#define B_PCH_SMBUS_CRCE 0x01
+#define B_PCH_SMBUS_STCO 0x02 ///< SMBus TCO Mode
+#define R_PCH_SMBUS_AUXC 0x0D ///< Auxiliary Control Register R/W
+#define B_PCH_SMBUS_AAC 0x01
+#define B_PCH_SMBUS_E32B 0x02
+#define R_PCH_SMBUS_SMLC 0x0E ///< SMLINK Pin Control Register R/W
+#define B_PCH_SMBUS_SMLINK0_CUR_STS 0x01
+#define B_PCH_SMBUS_SMLINK1_CUR_STS 0x02
+#define B_PCH_SMBUS_SMLINK_CLK_CTL 0x04
+#define R_PCH_SMBUS_SMBC 0x0F ///< SMBus Pin Control Register R/W
+#define B_PCH_SMBUS_SMBCLK_CUR_STS 0x01
+#define B_PCH_SMBUS_SMBDATA_CUR_STS 0x02
+#define B_PCH_SMBUS_SMBCLK_CTL 0x04
+#define R_PCH_SMBUS_SSTS 0x10 ///< Slave Status Register R/WC
+#define B_PCH_SMBUS_HOST_NOTIFY_STS 0x01
+#define R_PCH_SMBUS_SCMD 0x11 ///< Slave Command Register R/W
+#define B_PCH_SMBUS_HOST_NOTIFY_INTREN 0x01
+#define B_PCH_SMBUS_HOST_NOTIFY_WKEN 0x02
+#define B_PCH_SMBUS_SMBALERT_DIS 0x04
+#define R_PCH_SMBUS_NDA 0x14 ///< Notify Device Address Register RO
+#define B_PCH_SMBUS_DEVICE_ADDRESS 0xFE
+#define R_PCH_SMBUS_NDLB 0x16 ///< Notify Data Low Byte Register RO
+#define R_PCH_SMBUS_NDHB 0x17 ///< Notify Data High Byte Register RO
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h
new file mode 100644
index 0000000..b195e33
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsSpi.h
@@ -0,0 +1,380 @@
+/** @file
+ Register names for PCH SPI device.
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_SPI_H_
+#define _PCH_REGS_SPI_H_
+
+//
+// SPI Host Interface Registers
+//
+#define R_PCH_RCRB_SPI_BASE 0x3800 ///< Base address of the SPI host interface registers
+#define R_PCH_SPI_BFPR (R_PCH_RCRB_SPI_BASE + 0x00) ///< BIOS Flash Primary Region Register(32bits), which is RO and contains the same value from FREG1
+#define R_PCH_SPI_HSFS (R_PCH_RCRB_SPI_BASE + 0x04) ///< Hardware Sequencing Flash Status Register(16bits)
+#define B_PCH_SPI_HSFS_FLOCKDN BIT15 ///< Flash Configuration Lock-Down
+#define B_PCH_SPI_HSFS_FDV BIT14 ///< Flash Descriptor Valid, once valid software can use hareware sequencing regs
+#define B_PCH_SPI_HSFS_FDOPSS BIT13 ///< Flash Descriptor Override Pin-Strap Status, 0: The Flash Descriptor Security Override / Intel
+ ///< ME Debug Mode strap is set via external pull-up on HDA_SDO; 1: No override.
+#define B_PCH_SPI_PRR3PRR4_LOCKDN BIT12 ///< PRR3 PRR4 Lock-Down
+#define B_PCH_SPI_HSFS_SCIP BIT5 ///< SPI cyble in progress
+#define B_PCH_SPI_HSFS_BERASE_MASK (BIT4 | BIT3) ///< Block/Sector Erase Size
+#define V_PCH_SPI_HSFS_BERASE_256B 0x00 ///< Block/Sector = 256 Bytes
+#define V_PCH_SPI_HSFS_BERASE_4K 0x01 ///< Block/Sector = 4K Bytes
+#define V_PCH_SPI_HSFS_BERASE_8K 0x10 ///< Block/Sector = 8K Bytes
+#define V_PCH_SPI_HSFS_BERASE_64K 0x11 ///< Block/Sector = 64K Bytes
+#define B_PCH_SPI_HSFS_AEL BIT2 ///< Access Error Log
+#define B_PCH_SPI_HSFS_FCERR BIT1 ///< Flash Cycle Error
+#define B_PCH_SPI_HSFS_FDONE BIT0 ///< Flash Cycle Done
+#define R_PCH_SPI_HSFC (R_PCH_RCRB_SPI_BASE + 0x06) ///< Hardware Sequencing Flash Control Register(16bits)
+#define B_PCH_SPI_HSFC_FSMIE BIT15 ///< Flash SPI SMI# Enable
+#define B_PCH_SPI_HSFC_FDBC_MASK 0x3F00 ///< Flash Data Byte Count ( <= 64), Count = (Value in this field) + 1.
+#define B_PCH_SPI_HSFC_FCYCLE_MASK 0x0006 ///< Flash Cycle.
+#define V_PCH_SPI_HSFC_FCYCLE_READ 0 ///< Flash Cycle Read
+#define V_PCH_SPI_HSFC_FCYCLE_WRITE 2 ///< Flash Cycle Write
+#define V_PCH_SPI_HSFC_FCYCLE_ERASE 3 ///< Flash Cycle Block Erase
+#define B_PCH_SPI_HSFC_FCYCLE_FGO BIT0 ///< Flash Cycle Go.
+#define R_PCH_SPI_FADDR (R_PCH_RCRB_SPI_BASE + 0x08) ///< SPI Flash Address
+#define B_PCH_SPI_FADDR_MASK 0x07FFFFFF ///< SPI Flash Address Mask (0~26bit)
+#define R_PCH_SPI_FDATA00 (R_PCH_RCRB_SPI_BASE + 0x10) ///< SPI Data 00 (32 bits)
+#define R_PCH_SPI_FDATA01 (R_PCH_RCRB_SPI_BASE + 0x14) ///< SPI Data 01
+#define R_PCH_SPI_FDATA02 (R_PCH_RCRB_SPI_BASE + 0x18) ///< SPI Data 02
+#define R_PCH_SPI_FDATA03 (R_PCH_RCRB_SPI_BASE + 0x1C) ///< SPI Data 03
+#define R_PCH_SPI_FDATA04 (R_PCH_RCRB_SPI_BASE + 0x20) ///< SPI Data 04
+#define R_PCH_SPI_FDATA05 (R_PCH_RCRB_SPI_BASE + 0x24) ///< SPI Data 05
+#define R_PCH_SPI_FDATA06 (R_PCH_RCRB_SPI_BASE + 0x28) ///< SPI Data 06
+#define R_PCH_SPI_FDATA07 (R_PCH_RCRB_SPI_BASE + 0x2C) ///< SPI Data 07
+#define R_PCH_SPI_FDATA08 (R_PCH_RCRB_SPI_BASE + 0x30) ///< SPI Data 08
+#define R_PCH_SPI_FDATA09 (R_PCH_RCRB_SPI_BASE + 0x34) ///< SPI Data 09
+#define R_PCH_SPI_FDATA10 (R_PCH_RCRB_SPI_BASE + 0x38) ///< SPI Data 10
+#define R_PCH_SPI_FDATA11 (R_PCH_RCRB_SPI_BASE + 0x3C) ///< SPI Data 11
+#define R_PCH_SPI_FDATA12 (R_PCH_RCRB_SPI_BASE + 0x40) ///< SPI Data 12
+#define R_PCH_SPI_FDATA13 (R_PCH_RCRB_SPI_BASE + 0x44) ///< SPI Data 13
+#define R_PCH_SPI_FDATA14 (R_PCH_RCRB_SPI_BASE + 0x48) ///< SPI Data 14
+#define R_PCH_SPI_FDATA15 (R_PCH_RCRB_SPI_BASE + 0x4C) ///< SPI Data 15
+#define R_PCH_SPI_FRAP (R_PCH_RCRB_SPI_BASE + 0x50) ///< SPI Flash Regions Access Permisions Register
+#define B_PCH_SPI_FRAP_BMWAG_MASK 0xFF000000 ///< Master Write Access Grant MASK
+#define B_PCH_SPI_FRAP_BMWAG_GBE BIT27 ///< Master write access grant for Host CPU/GbE
+#define B_PCH_SPI_FRAP_BMWAG_ME BIT26 ///< Master write access grant for ME
+#define B_PCH_SPI_FRAP_BMWAG_BIOS BIT25 ///< Master write access grant for Host CPU/BIOS
+#define B_PCH_SPI_FRAP_BMRAG_MASK 0x00FF0000 ///< Master Write Access Grant MASK
+#define B_PCH_SPI_FRAP_BMRAG_GBE BIT19 ///< Master write access grant for Host CPU/GbE
+#define B_PCH_SPI_FRAP_BMRAG_ME BIT18 ///< Master write access grant for ME
+#define B_PCH_SPI_FRAP_BMRAG_BIOS BIT17 ///< Master write access grant for Host CPU/BIOS
+#define B_PCH_SPI_FRAP_BRWA_MASK 0x0000FF00 ///< BIOS Regsion Write Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: ...
+#define B_PCH_SPI_FRAP_BRWA_GBE BIT11 ///< Region write access for Region3 GbE
+#define B_PCH_SPI_FRAP_BRWA_ME BIT10 ///< Region write access for Region2 ME
+#define B_PCH_SPI_FRAP_BRWA_BIOS BIT9 ///< Region write access for Region1 BIOS
+#define B_PCH_SPI_FRAP_BRWA_FLASHD BIT8 ///< Region write access for Region0 Flash Descriptor
+#define B_PCH_SPI_FRAP_BRRA_MASK 0x000000FF ///< BIOS Regsion Read Access MASK, Region0~7 - 0: Flash Descriptor; 1: BIOS; 2: ME; 3: GbE; 4: ...
+#define B_PCH_SPI_FRAP_BRRA_GBE BIT3 ///< Region read access for Region3 GbE
+#define B_PCH_SPI_FRAP_BRRA_ME BIT2 ///< Region read access for Region2 ME
+#define B_PCH_SPI_FRAP_BRRA_BIOS BIT1 ///< Region read access for Region1 BIOS
+#define B_PCH_SPI_FRAP_BRRA_FLASHD BIT0 ///< Region read access for Region0 Flash Descriptor
+#define R_PCH_SPI_FREG0_FLASHD (R_PCH_RCRB_SPI_BASE + 0x54) ///< Flash Region 0(Flash Descriptor)(32bits)
+#define B_PCH_SPI_FREG0_LIMIT_MASK 0x7FFF0000 ///< Size, [30:16] here represents limit[26:12]
+#define B_PCH_SPI_FREG0_BASE_MASK 0x00007FFF ///< Base, [14:0] here represents base [26:12]
+#define R_PCH_SPI_FREG1_BIOS (R_PCH_RCRB_SPI_BASE + 0x58) ///< Flash Region 1(BIOS)(32bits)
+#define B_PCH_SPI_FREG1_LIMIT_MASK 0x7FFF0000 ///< Size, [30:16] here represents limit[26:12]
+#define B_PCH_SPI_FREG1_BASE_MASK 0x00007FFF ///< Base, [14:0] here represents base [26:12]
+#define R_PCH_SPI_FREG2_ME (R_PCH_RCRB_SPI_BASE + 0x5C) ///< Flash Region 2(ME)(32bits)
+#define B_PCH_SPI_FREG2_LIMIT_MASK 0x7FFF0000 ///< Size, [30:16] here represents limit[26:12]
+#define B_PCH_SPI_FREG2_BASE_MASK 0x00007FFF ///< Base, [14:0] here represents base [26:12]
+#define R_PCH_SPI_FREG3_GBE (R_PCH_RCRB_SPI_BASE + 0x60) ///< Flash Region 3(GbE)(32bits)
+#define B_PCH_SPI_FREG3_LIMIT_MASK 0x7FFF0000 ///< Size, [30:16] here represents limit[26:12]
+#define B_PCH_SPI_FREG3_BASE_MASK 0x00007FFF ///< Base, [14:0] here represents base [26:12]
+#define R_PCH_SPI_FREG4_PLATFORM_DATA (R_PCH_RCRB_SPI_BASE + 0x64) ///< Flash Region 4(Platform Data)(32bits)
+#define B_PCH_SPI_FREG4_LIMIT_MASK 0x7FFF0000 ///< Size, [30:16] here represents limit[26:12]
+#define B_PCH_SPI_FREG4_BASE_MASK 0x00007FFF ///< Base, [14:0] here represents base [26:12]
+#define R_PCH_SPI_PR0 (R_PCH_RCRB_SPI_BASE + 0x74) ///< Protected Region 0 Register
+#define B_PCH_SPI_PR0_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PR0_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask, [30:16] here represents upper limit of address [26:12]
+#define B_PCH_SPI_PR0_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PR0_PRB_MASK 0x00007FFF ///< Protected Range Base Mask, [14:0] here represents base limit of address [26:12]
+#define R_PCH_SPI_PR1 (R_PCH_RCRB_SPI_BASE + 0x78) ///< Protected Region 1 Register
+#define B_PCH_SPI_PR1_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PR1_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask
+#define B_PCH_SPI_PR1_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PR1_PRB_MASK 0x00007FFF ///< Protected Range Base Mask
+#define R_PCH_SPI_PR2 (R_PCH_RCRB_SPI_BASE + 0x7C) ///< Protected Region 2 Register
+#define B_PCH_SPI_PR2_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PR2_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask
+#define B_PCH_SPI_PR2_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PR2_PRB_MASK 0x00007FFF ///< Protected Range Base Mask
+#define R_PCH_SPI_PR3 (R_PCH_RCRB_SPI_BASE + 0x80) ///< Protected Region 3 Register
+#define B_PCH_SPI_PR3_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PR3_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask
+#define B_PCH_SPI_PR3_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PR3_PRB_MASK 0x00007FFF ///< Protected Range Base Mask
+#define R_PCH_SPI_PR4 (R_PCH_RCRB_SPI_BASE + 0x84) ///< Protected Region 4 Register
+#define B_PCH_SPI_PR4_WPE BIT31 ///< Write Protection Enable
+#define B_PCH_SPI_PR4_PRL_MASK 0x7FFF0000 ///< Protected Range Limit Mask
+#define B_PCH_SPI_PR4_RPE BIT15 ///< Read Protection Enable
+#define B_PCH_SPI_PR4_PRB_MASK 0x00007FFF ///< Protected Range Base Mask
+#define R_PCH_SPI_SSFS (R_PCH_RCRB_SPI_BASE + 0x90) ///< Software Sequencing Flash Status Register(8bits)
+#define B_PCH_SPI_SSFS_FRS BIT7 ///< Fast Read Supported
+#define B_PCH_SPI_SSFS_DOFRS BIT6 ///< Dual Output Fast Read Supported
+#define B_PCH_SPI_SSFS_AEL BIT4 ///< Access Error Log
+#define B_PCH_SPI_SSFS_FCERR BIT3 ///< Flash Cycle Error
+#define B_PCH_SPI_SSFS_CDS BIT2 ///< Cycle Done Status
+#define B_PCH_SPI_SSFS_SCIP BIT0 ///< SPI Cycle in Progress
+#define R_PCH_SPI_SSFC (R_PCH_RCRB_SPI_BASE + 0x91) ///< Software Sequencing Flash Control(24bits)
+#define B_PCH_SPI_SSFC_SCF_MASK (BIT18 | BIT17 | BIT16) ///< SPI Cycle Frequency
+#define V_PCH_SPI_SSFC_SCF_20MHZ 0 ///< SPI Cycle Frequency = 20MHz
+#define V_PCH_SPI_SSFC_SCF_33MHZ 1 ///< SPI Cycle Frequency = 33MHz
+#define V_PCH_SPI_SSFC_SCF_50MHZ 4 ///< SPI Cycle Frequency = 50MHz
+#define B_PCH_SPI_SSFC_SME BIT15 ///< SPI SMI# Enable
+#define B_PCH_SPI_SSFC_DS BIT14 ///< SPI Data Cycle
+#define B_PCH_SPI_SSFC_DBC_MASK 0x3F00 ///< SPI Data Byte Count (value here + 1 = count)
+#define B_PCH_SPI_SSFC_COP 0x0070 ///< Cycle Opcode Pointer
+#define B_PCH_SPI_SSFC_SPOP BIT3 ///< Sequence Prefix Opcode Pointer
+#define B_PCH_SPI_SSFC_ACS BIT2 ///< Atomic Cycle Sequence
+#define B_PCH_SPI_SSFC_SCGO BIT1 ///< SPI Cycle Go
+#define R_PCH_SPI_PREOP (R_PCH_RCRB_SPI_BASE + 0x94) ///< Prefix Opcode Configuration Register(16 bits)
+#define B_PCH_SPI_PREOP1_MASK 0xFF00 ///< Prefix Opcode 1 Mask
+#define B_PCH_SPI_PREOP0_MASK 0x00FF ///< Prefix Opcode 0 Mask
+#define R_PCH_SPI_OPTYPE (R_PCH_RCRB_SPI_BASE + 0x96) ///< Opcode Type Configuration
+#define B_PCH_SPI_OPTYPE7_MASK (BIT15 | BIT14) ///< Opcode Type 7 Mask
+#define B_PCH_SPI_OPTYPE6_MASK (BIT13 | BIT12) ///< Opcode Type 6 Mask
+#define B_PCH_SPI_OPTYPE5_MASK (BIT11 | BIT10) ///< Opcode Type 5 Mask
+#define B_PCH_SPI_OPTYPE4_MASK (BIT9 | BIT8) ///< Opcode Type 4 Mask
+#define B_PCH_SPI_OPTYPE3_MASK (BIT7 | BIT6) ///< Opcode Type 3 Mask
+#define B_PCH_SPI_OPTYPE2_MASK (BIT5 | BIT4) ///< Opcode Type 2 Mask
+#define B_PCH_SPI_OPTYPE1_MASK (BIT3 | BIT2) ///< Opcode Type 1 Mask
+#define B_PCH_SPI_OPTYPE0_MASK (BIT1 | BIT0) ///< Opcode Type 0 Mask
+#define V_PCH_SPI_OPTYPE_RDNOADDR 0x00 ///< Read cycle type without address
+#define V_PCH_SPI_OPTYPE_WRNOADDR 0x01 ///< Write cycle type without address
+#define V_PCH_SPI_OPTYPE_RDADDR 0x02 ///< Address required; Read cycle type
+#define V_PCH_SPI_OPTYPE_WRADDR 0x03 ///< Address required; Write cycle type
+#define R_PCH_SPI_OPMENU (R_PCH_RCRB_SPI_BASE + 0x98) ///< Opcode Menu Configuration (64bits)
+#define R_PCH_SPI_FDOC (R_PCH_RCRB_SPI_BASE + 0xB0) ///< Flash Descriptor Observability Control Register(32 bits)
+#define B_PCH_SPI_FDOC_FDSS_MASK (BIT14 | BIT13 | BIT12) ///< Flash Descritor Section Select
+#define V_PCH_SPI_FDOC_FDSS_FSDM 0x0000 ///< Flash Signature and Descriptor Map
+#define V_PCH_SPI_FDOC_FDSS_COMP 0x1000 ///< Component
+#define V_PCH_SPI_FDOC_FDSS_REGN 0x2000 ///< Region
+#define V_PCH_SPI_FDOC_FDSS_MSTR 0x3000 ///< Master
+#define V_PCH_SPI_FDOC_FDSS_PCHS 0x4000 ///< PCH soft straps
+#define V_PCH_SPI_FDOC_FDSS_SFDP 0x5000 ///< SFDP Parameter Table
+#define B_PCH_SPI_FDOC_FDSI_MASK 0x0FFC ///< Flash Descriptor Section Index
+#define R_PCH_SPI_FDOD (R_PCH_RCRB_SPI_BASE + 0xB4) ///< Flash Descriptor Observability Data Register(32 bits)
+#define R_PCH_SPI_AFC (R_PCH_RCRB_SPI_BASE + 0xC0) ///< Additional Flash Control Register
+#define B_PCH_SPI_AFC_INF_DCGE (BIT2 | BIT1) ///< Flash Controller Interface Dynamic Clock Gating Enable
+#define B_PCH_SPI_AFC_CORE_DCGE BIT0 ///< Flash Core Dynamic Clock Gating Enable
+#define R_PCH_SPI_VSCC0 (R_PCH_RCRB_SPI_BASE + 0xC4) ///< Vendor Specific Component Capabilities Register(32 bits)
+#define B_PCH_SPI_VSCC0_CPPTV BIT31 ///< Component Property Parameter Table Valid
+#define B_PCH_SPI_VSCC0_VCL BIT23 ///< Vendor Component Lock
+#define B_PCH_SPI_VSCC0_EO_MASK 0x0000FF00 ///< Erase Opcode
+#define B_PCH_SPI_VSCC0_WEWS BIT4 ///< Write Enable on Write Status
+#define B_PCH_SPI_VSCC0_WSR BIT3 ///< Write Status Required
+#define B_PCH_SPI_VSCC0_WG_64B BIT2 ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define B_PCH_SPI_VSCC0_BSES_MASK (BIT1 | BIT0) ///< Block/Sector Erase Size
+#define V_PCH_SPI_VSCC0_BSES_256B 0x0 ///< Block/Sector Erase Size = 256 Bytes
+#define V_PCH_SPI_VSCC0_BSES_4K 0x1 ///< Block/Sector Erase Size = 4K Bytes
+#define V_PCH_SPI_VSCC0_BSES_8K 0x2 ///< Block/Sector Erase Szie = 8K Bytes
+#define V_PCH_SPI_VSCC0_BSES_64K 0x3 ///< Block/Sector Erase Size = 64K Bytes
+#define R_PCH_SPI_VSCC1 (R_PCH_RCRB_SPI_BASE + 0xC8) ///< Vendor Specific Component Capabilities Register(32 bits)
+#define B_PCH_SPI_VSCC1_CPPTV BIT31 ///< Component Property Parameter Table Valid
+#define B_PCH_SPI_VSCC1_EO_MASK 0x0000FF00 ///< Erase Opcode
+#define B_PCH_SPI_VSCC1_WEWS BIT4 ///< Write Enable on Write Status
+#define B_PCH_SPI_VSCC1_WSR BIT3 ///< Write Status Required
+#define B_PCH_SPI_VSCC1_WG_64B BIT2 ///< Write Granularity, 0: 1 Byte; 1: 64 Bytes
+#define B_PCH_SPI_VSCC1_BSES_MASK (BIT1 | BIT0) ///< Block/Sector Erase Size
+#define V_PCH_SPI_VSCC1_BSES_256B 0x0 ///< Block/Sector Erase Size = 256 Bytes
+#define V_PCH_SPI_VSCC1_BSES_4K 0x1 ///< Block/Sector Erase Size = 4K Bytes
+#define V_PCH_SPI_VSCC1_BSES_8K 0x2 ///< Block/Sector Erase Size = 8K Bytes
+#define V_PCH_SPI_VSCC1_BSES_64K 0x3 ///< Block/Sector Erase Size = 64K Bytes
+#define R_PCH_SPI_PINTX (R_PCH_RCRB_SPI_BASE + 0xCC) ///< Parameter Table Index
+#define N_PCH_SPI_PINTX_SPT 14
+#define V_PCH_SPI_PINTX_SPT_CPT0 0x0 ///< Component 0 Property Parameter Table
+#define V_PCH_SPI_PINTX_SPT_CPT1 0x1 ///< Component 1 Property Parameter Table
+#define N_PCH_SPI_PINTX_HORD 12
+#define V_PCH_SPI_PINTX_HORD_SFDP 0x0 ///< SFDP Header
+#define V_PCH_SPI_PINTX_HORD_PT 0x1 ///< Parameter Table Header
+#define V_PCH_SPI_PINTX_HORD_DATA 0x2 ///< Data
+#define R_PCH_SPI_PTDATA (R_PCH_RCRB_SPI_BASE + 0xD0) ///< Parameter Table Data
+#define R_PCH_SPI_SRDL (R_PCH_RCRB_SPI_BASE + 0xF0) ///< Soft Reset Data Lock
+#define B_PCH_SPI_SRDL_SSL BIT0 ///< Set_Stap Lock
+#define R_PCH_SPI_SRDC (R_PCH_RCRB_SPI_BASE + 0xF4) ///< Soft Reset Data Control
+#define B_PCH_SPI_SRDC_SRDS BIT0 ///< Soft Reset Data Select
+#define R_PCH_SPI_SRD (R_PCH_RCRB_SPI_BASE + 0xF8) ///< Soft Reset Data
+//
+// @todo Follow up with EDS owner if it should be 3FFF or FFFF.
+//
+#define B_PCH_SPI_SRD_SSD 0x0000FFFF ///< Set_Stap Data
+//
+// Flash Descriptor Base Address Region (FDBAR) from Flash Region 0
+//
+#define R_PCH_SPI_FDBAR_FLVALSIG 0x00 ///< Flash Valid Signature
+#define V_PCH_SPI_FDBAR_FLVALSIG 0x0FF0A55A
+#define R_PCH_SPI_FDBAR_FLASH_MAP0 0x04
+#define B_PCH_SPI_FDBAR_FCBA 0x000000FF ///< Flash Component Base Address
+#define B_PCH_SPI_FDBAR_NC 0x00000300 ///< Number Of Components
+#define N_PCH_SPI_FDBAR_NC 0x08 ///< Number Of Components
+#define V_PCH_SPI_FDBAR_NC_1 0x00000000
+#define V_PCH_SPI_FDBAR_NC_2 0x00000100
+#define B_PCH_SPI_FDBAR_FRBA 0x00FF0000 ///< Flash Region Base Address
+#define B_PCH_SPI_FDBAR_NR 0x07000000 ///< Number Of Regions
+#define R_PCH_SPI_FDBAR_FLASH_MAP1 0x08
+#define B_PCH_SPI_FDBAR_FMBA 0x000000FF ///< Flash Master Base Address
+#define B_PCH_SPI_FDBAR_NM 0x00000700 ///< Number Of Masters
+#define B_PCH_SPI_FDBAR_FPCHSBA 0x00FF0000 ///< Flash PCH Strap Base Address
+#define B_PCH_SPI_FDBAR_PCHSL 0xFF000000 ///< PCH Strap Length
+#define R_PCH_SPI_FDBAR_FLASH_MAP2 0x0C
+#define B_PCH_SPI_FDBAR_FPROSBA 0x000000FF ///< Flash Processor Strap Base Address
+#define B_PCH_SPI_FDBAR_PROSL 0x0000FF00 ///< PROC Strap Length
+//
+// Flash Component Base Address (FCBA) from Flash Region 0
+//
+#define R_PCH_SPI_FCBA_FLCOMP 0x00 ///< Flash Components Register
+#define B_PCH_SPI_FLCOMP_RIDS_FREQ (BIT29 | BIT28 | BIT27) ///< Read ID and Read Status Clock Frequency
+#define B_PCH_SPI_FLCOMP_WE_FREQ (BIT26 | BIT25 | BIT24) ///< Write and Erase Clock Frequency
+#define B_PCH_SPI_FLCOMP_FRCF_FREQ (BIT23 | BIT22 | BIT21) ///< Fast Read Clock Frequency
+#define B_PCH_SPI_FLCOMP_FR_SUP BIT20 ///< Fast Read Support.
+#define B_PCH_SPI_FLCOMP_RC_FREQ (BIT19 | BIT18 | BIT17) ///< Read Clock Frequency.
+#define V_PCH_SPI_FLCOMP_FREQ_20MHZ 0x00
+#define V_PCH_SPI_FLCOMP_FREQ_33MHZ 0x01
+#define V_PCH_SPI_FLCOMP_FREQ_50MHZ 0x04
+#define B_PCH_SPI_FLCOMP_COMP2_MASK 0xF0 ///< Flash Component 2 Size MASK
+#define V_PCH_SPI_FLCOMP_COMP2_512KB 0x00
+#define V_PCH_SPI_FLCOMP_COMP2_1MB 0x10
+#define V_PCH_SPI_FLCOMP_COMP2_2MB 0x20
+#define V_PCH_SPI_FLCOMP_COMP2_4MB 0x30
+#define V_PCH_SPI_FLCOMP_COMP2_8MB 0x40
+#define V_PCH_SPI_FLCOMP_COMP2_16MB 0x50
+#define V_PCH_SPI_FLCOMP_COMP2_32MB 0x60
+#define V_PCH_SPI_FLCOMP_COMP2_64MB 0x70
+#define B_PCH_SPI_FLCOMP_COMP1_MASK 0x0F ///< Flash Component 1 Size MASK
+#define V_PCH_SPI_FLCOMP_COMP1_512KB 0x00
+#define V_PCH_SPI_FLCOMP_COMP1_1MB 0x01
+#define V_PCH_SPI_FLCOMP_COMP1_2MB 0x02
+#define V_PCH_SPI_FLCOMP_COMP1_4MB 0x03
+#define V_PCH_SPI_FLCOMP_COMP1_8MB 0x04
+#define V_PCH_SPI_FLCOMP_COMP1_16MB 0x05
+#define V_PCH_SPI_FLCOMP_COMP1_32MB 0x06
+#define V_PCH_SPI_FLCOMP_COMP1_64MB 0x07
+#define V_PCH_SPI_FLCOMP_COMP_512KB 0x80000
+//
+// Descriptor Upper Map Section from Flash Region 0
+//
+#define R_PCH_SPI_FLASH_UMAP1 0xEFC ///< Flash Upper Map 1
+#define B_PCH_SPI_FLASH_UMAP1_VTBA 0x000000FF ///< VSCC Table Base Address
+#define B_PCH_SPI_FLASH_UMAP1_VTL 0x0000FF00 ///< VSCC Table Length
+
+#define R_PCH_SPI_VTBA_JID0 0x00 ///< JEDEC-ID 0 Register
+#define S_PCH_SPI_VTBA_JID0 0x04
+#define B_PCH_SPI_VTBA_JID0_VID 0x000000FF
+#define B_PCH_SPI_VTBA_JID0_DID0 0x0000FF00
+#define B_PCH_SPI_VTBA_JID0_DID1 0x00FF0000
+#define N_PCH_SPI_VTBA_JID0_DID0 0x08
+#define N_PCH_SPI_VTBA_JID0_DID1 0x10
+#define R_PCH_SPI_VTBA_VSCC0 0x04
+#define S_PCH_SPI_VTBA_VSCC0 0x04
+#define R_PCH_SPI_STRP0 0x0 ///< PCH soft strap 0
+#define B_PCH_SPI_STRP0_BBBS (BIT31 |BIT30 | BIT29) ///< BIOS Boot-Block size
+#define B_PCH_SPI_STRP0_BBBS_64KB 0x00
+#define B_PCH_SPI_STRP0_BBBS_128KB BIT29
+#define B_PCH_SPI_STRP0_BBBS_256KB BIT30
+#define B_PCH_SPI_STRP0_BBBS_512KB (BIT30 | BIT29)
+#define B_PCH_SPI_STRP0_BBBS_1MB BIT31
+#define B_PCH_SPI_STRP0_DMI_REQID_DIS BIT24 ///< DMI RequesterID Check Disable
+#define B_PCH_SPI_STRP0_CFG_STRP1 BIT21 ///< Chipset configuration Softstrap 1
+#define B_PCH_SPI_STRP0_LAN_GP12_SEL BIT20 ///< LAN PHY Power Control GPIO12 Select
+#define B_PCH_SPI_STRP0_SML0FRQ (BIT15 | BIT14) ///< SMLink0 Frequency
+#define B_PCH_SPI_STRP0_SMB0FRQ (BIT13 | BIT12) ///< Intel ME SMBus Frequency
+#define B_PCH_SPI_STRP0_SML1FRQ (BIT11 | BIT10) ///< SMLink1 Frequency
+#define B_PCH_SPI_STRP0_SML1_EN BIT9 ///< SMLink1 Enable
+#define B_PCH_SPI_STRP0_SML0_EN BIT8 ///< SMLink0 Enable
+#define B_PCH_SPI_STRP0_SMB_EN BIT7 ///< Intel ME SMBus Select
+#define B_PCH_SPI_STRP0_CFG_STRP2 BIT1 ///< Chipset configuration Softstrap 2
+#define R_PCH_SPI_STRP1 0x04 ///< PCH soft strap 1
+#define B_PCH_SPI_STRP1_CFG_STRP3 0x0F ///< Chipset configuration Softstrap 3
+#define R_PCH_SPI_STRP2 0x08 ///< PCH soft strap 2
+#define B_PCH_SPI_STRP2_MESMA 0xFE000000 ///< ME SMBus Address
+#define B_PCH_SPI_STRP2_MESMI2CEN BIT24 ///< ME SMBus Address Enable
+#define B_PCH_SPI_STRP2_MESMASDA 0xFE00 ///< ME SMBus Alert Sending Device Address
+#define B_PCH_SPI_STRP2_MESMASDEN BIT8 ///< ME SMBus Alert Sending Device Address Enable
+#define R_PCH_SPI_STRP3 0x0C ///< PCH soft strap 3
+#define R_PCH_SPI_STRP4 0x10 ///< PCH soft strap 4
+#define B_PCH_SPI_STRP4_GBEPHYSMA 0xFE0000 ///< GbE PHY SMBus Address
+#define B_PCH_SPI_STRP4_GBEMACSMA 0xFE00 ///< GbE MAC SMBus Address
+#define B_PCH_SPI_STRP4_GBEMACSMAEN BIT8 ///< Gbe MAC SMBus Address Enable
+#define B_PCH_SPI_STRP4_PHYCON (BIT1 | BIT0) ///< Intel PHY Connectivity
+#define B_PCH_SPI_STRP4_NO_PHYCON 0x00
+#define B_PCH_SPI_STRP4_PHY_ON 0x02
+#define R_PCH_SPI_STRP5 0x14 ///< PCH soft strap 5
+#define R_PCH_SPI_STRP6 0x18 ///< PCH soft strap 6
+#define R_PCH_SPI_STRP7 0x1C ///< PCH soft strap 7
+#define B_PCH_SPI_STRP7_MESMASVID 0xFFFFFFFF ///< ME SMBus Subsystem Vendor and Device ID
+#define R_PCH_SPI_STRP8 0x20 ///< PCH soft strap 8
+#define R_PCH_SPI_STRP9 0x24 ///< PCH soft strap 9
+#define B_PCH_SPI_STRP9_HOT_SML1_SEL BIT22 ///< PCHHOT# or SML1AlERT# Select (0:SML1ALERT#; 1:PCHHOT#)
+#define B_PCH_SPI_STRP9_PCIE_SBDE_EN BIT14 ///< Subtractive Decode over PCI Express Enabling
+#define N_PCH_SPI_STRP9_PCIE_SBDE_EN 14
+#define B_PCH_SPI_STRP9_GBE_PCIE_EN BIT11 ///< GbE over PCI Express Enabling
+#define B_PCH_SPI_STRP9_GBE_PCIE_PSC (BIT8 | BIT9 | BIT10) ///< GbE PCI E Port Select
+#define N_PCH_SPI_STRP9_GBE_PCIE_PSC 8
+#define B_PCH_SPI_STRP9_DMILR BIT6 ///< DMI Lane Reversal
+#define B_PCH_SPI_STRP9_PCIELR2 BIT5 ///< PCIe Lane Reversal 2
+#define B_PCH_SPI_STRP9_PCIELR1 BIT4 ///< PCIe Lane Reversal 1
+#define B_PCH_SPI_STRP9_PCIEPCS2 BIT3 | BIT2 ///< PCI Express Port Configuration Strap 2
+#define B_PCH_SPI_STRP9_PCIEPCS1 BIT1 | BIT0 ///< PCI Express Port Configuration Strap 1
+#define V_PCH_SPI_STRP9_PCIEPCS_1x4 0x03 ///< 1x4 Port 1/5 (x4), Ports 2-4/6-8 (disabled)
+#define V_PCH_SPI_STRP9_PCIEPCS_2x2 0x02 ///< 2x2 Port 1/5 (x2), Port 3/7 (x2), Ports 2,4/6,8 (disabled)
+#define V_PCH_SPI_STRP9_PCIEPCS_1x2 0x01 ///< 1x2, 2x1 Port 1/5 (x2), Port 2/6 (disabled), Ports 3,4/7,8 (x1)
+#define V_PCH_SPI_STRP9_PCIEPCS_4x1 0x00 ///< 4x1 Ports 1-4/5-8 (x1)
+#define R_PCH_SPI_STRP10 0x28 ///< PCH soft strap 10
+#define B_PCH_SPI_STRP10_MER_CL1 BIT21 ///< ME Reset Capture on CL_RST1
+#define B_PCH_SPI_STRP10_ICC_SEL 0x1C0000 ///< Integrated Clocking Configuration Select
+#define B_PCH_SPI_STRP10_CFG_STRP7 BIT16 ///< Chipset Configuration Softstrap 7
+#define B_PCH_SPI_STRP10_MMADDR 0xFE00 ///< ME Memory-attached Debug Display Device Address
+#define B_PCH_SPI_STRP10_MMDDE BIT8 ///< ME Memory-attached Debug Display Device Enable
+#define B_PCH_SPI_STRP10_VE_EN BIT3 ///< 0 - VE disabled; 1 - VE enabled
+#define B_PCH_SPI_STRP10_CFG_STRP5 BIT2 ///< Chipset Configuration Softstrap 5
+#define B_PCH_SPI_STRP10_ME_BFlash BIT1 ///< ME from Boot Flash
+#define R_PCH_SPI_STRP11 0x2C ///< PCH soft strap 11
+#define B_PCH_SPI_STRP11_SML1I2CA 0xFE000000 ///< SMLink1 I2C Target Address
+#define B_PCH_SPI_STRP11_SML1I2CAEN BIT24 ///< SMLink1 I2C Target Address Enable
+#define B_PCH_SPI_STRP11_SML1GPA 0xE ///< SMLink1 GP Address
+#define B_PCH_SPI_STRP11_SML1GPAEN BIT0 ///< SMLink1 GP Address Enable
+#define R_PCH_SPI_STRP12 0x30
+#define R_PCH_SPI_STRP13 0x34
+#define R_PCH_SPI_STRP14 0x38
+#define R_PCH_SPI_STRP15 0x3C
+#define R_PCH_SPI_STRP15_SML1_THRMSEL BIT14 ///< SMLink1 Thermal Reporting Select
+#define B_PCH_SPI_STRP15_T209MIN (BIT9 | BIT8) ///< T209 min Timing
+#define B_PCH_SPI_STRP15_IWL_EN BIT6 ///< Intel integrated wired LAN Enable
+#define B_PCH_SPI_STRP15_CFG_STRP6 (BIT4 | BIT3) ///< Chipset Configuration Softstrap 6
+#define R_PCH_SPI_STRP17 0x44 ///< PCH Soft strap 17
+#define B_PCH_SPI_STRP17_CLK_MODE BIT0 ///< Integrated Clock mode select
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsThermal.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsThermal.h
new file mode 100644
index 0000000..b94d1ed
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsThermal.h
@@ -0,0 +1,100 @@
+/** @file
+ Register names for PCH Thermal Device
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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
+**/
+#ifndef _PCH_REGS_THERMAL_H_
+#define _PCH_REGS_THERMAL_H_
+
+//
+// Thermal Device Registers (D31:F6)
+//
+#define PCI_DEVICE_NUMBER_PCH_THERMAL 31
+#define PCI_FUNCTION_NUMBER_PCH_THERMAL 6
+#define R_PCH_THERMAL_VENDOR_ID 0x00
+#define V_PCH_THERMAL_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_THERMAL_DEVICE_ID 0x02
+#define V_PCH_LPTH_THERMAL_DEVICE_ID 0x8C24
+#define V_PCH_LPTLP_THERMAL_DEVICE_ID 0x9C24
+#define R_PCH_THERMAL_COMMAND 0x04
+#define B_PCH_THERMAL_COMMAND_MSE BIT1
+#define B_PCH_THERMAL_COMMAND_BME BIT2
+#define R_PCH_THERMAL_TBAR 0x10
+#define V_PCH_THERMAL_TBAR_SIZE (4 * 1024)
+#define N_PCH_THREMAL_TBAR_ALIGNMENT 12
+#define B_PCH_THERMAL_TBAR_MASK 0xFFFFF000
+#define R_PCH_THERMAL_TBARH 0x14
+#define R_PCH_THERMAL_SVID 0x2C
+#define R_PCH_THERMAL_INTLN 0x3C
+#define R_PCH_THERMAL_TBARB 0x40
+#define V_PCH_THERMAL_TBARB_SIZE (4 * 1024)
+#define N_PCH_THREMAL_TBARB_ALIGNMENT 12
+#define B_PCH_THERMAL_SPTYPEN BIT0
+#define R_PCH_THERMAL_TBARBH 0x44
+#define B_PCH_THERMAL_TBARB_MASK 0xFFFFF000
+
+#define R_PCH_TBARB_TSC 0x04
+#define B_PCH_TBARB_TSC_PLD BIT7
+#define B_PCH_TBARB_TSC_CPDE BIT0
+#define R_PCH_TBARB_TSS 0x06
+#define R_PCH_TBARB_TSEL 0x08
+#define B_PCH_TBARB_TSEL_PLD BIT7
+#define B_PCH_TBARB_TSEL_ETS BIT0
+#define R_PCH_TBARB_TSREL 0x0A
+#define R_PCH_TBARB_TSMIC 0x0C
+#define B_PCH_TBARB_TSMIC_PLD BIT7
+#define B_PCH_TBARB_TSMIC_SMIE BIT0
+#define R_PCH_TBARB_CTT 0x10
+#define V_PCH_TBARB_CTT_LPTH 0x154
+#define V_PCH_TBARB_CTT_LPTLP 0x14A
+#define R_PCH_TBARB_TAHV 0x14
+#define R_PCH_TBARB_TALV 0x18
+#define R_PCH_TBARB_TSPM 0x1C
+#define B_PCH_TBARB_TSPM_LTT (BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0)
+#define V_PCH_TBARB_TSPM_LTT 0x0C8
+#define B_PCH_TBARB_TSPM_MAXTSST (BIT11 | BIT10 | BIT9)
+#define V_PCH_TBARB_TSPM_MAXTSST (0x4 << 9)
+#define B_PCH_TBARB_TSPM_MINTSST BIT12
+#define B_PCH_TBARB_TSPM_DTSSIC0 BIT13
+#define B_PCH_TBARB_TSPM_DTSSS0EN BIT14
+#define B_PCH_TBARB_TSPM_TSPMLOCK BIT15
+#define R_PCH_TBARB_TL 0x40
+#define B_PCH_TBARB_TL_LOCK BIT31
+#define R_PCH_TBARB_PHL 0x60
+#define B_PCH_TBARB_PHLE BIT15
+#define R_PCH_TBARB_PHLC 0x62
+#define R_PCH_TBARB_TAS 0x80
+#define R_PCH_TBARB_TSPIEN 0x82
+#define R_PCH_TBARB_TSGPEN 0x84
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h
new file mode 100644
index 0000000..12eaa9d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchRegs/PchRegsUsb.h
@@ -0,0 +1,563 @@
+/** @file
+ Register names for PCH USB devices
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+ - In general, PCH registers are denoted by "_PCH_" in register names
+ - Registers / bits that are different between PCH generations are denoted by
+ "_PCH_<generation_name>_" in register/bit names. e.g., "_PCH_LPT_"
+ - Registers / bits that are different between SKUs are denoted by "_<SKU_name>"
+ at the end of the register/bit names
+ - Registers / bits of new devices introduced in a PCH generation will be just named
+ as "_PCH_" without <generation_name> inserted.
+
+@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_REGS_USB_H_
+#define _PCH_REGS_USB_H_
+
+//
+// USB Definitions
+//
+#define LPTH_USB_MAX_PHYSICAL_PORTS 14 ///< Max Physical Connector EHCI + XHCI, not counting virtual ports like USB-R.
+#define LPTH_EHCI_MAX_CONTROLLERS 2 ///< Max EHCI Controllers
+#define LPTH_EHCI_MAX_PORTS 14 ///< Counting ports behind RMHs 8 from EHCI-1 and 6 from EHCI-2, not counting EHCI USB-R virtual ports.
+#define LPTH_XHCI_MAX_USB2_PORTS 15 ///< 14 High Speed lanes + Including one port reserved for USBr
+#define LPTH_XHCI_MAX_USB3_PORTS 6 ///< 6 Super Speed lanes
+#define LPTLP_USB_MAX_PHYSICAL_PORTS 8 ///< Max Physical Connector EHCI + XHCI, not counting virtual ports like USB-R.
+#define LPTLP_EHCI_MAX_PORTS 8 ///< Counting ports behind RMHs 8 from EHCI-1 and 6 from EHCI-2, not counting EHCI USB-R virtual ports.
+#define LPTLP_EHCI_MAX_CONTROLLERS 1 ///< Max EHCI Controllers
+#define LPTLP_XHCI_MAX_USB2_PORTS 9 ///< 8 High Speed lanes + Including one port reserved for USBr
+#define LPTLP_XHCI_MAX_USB3_PORTS 4 ///< 4 Super Speed lanes
+
+#define R_PCH_USB_VENDOR_ID 0x00
+#define V_PCH_USB_VENDOR_ID V_PCH_INTEL_VENDOR_ID
+#define R_PCH_USB_DEVICE_ID 0x02
+#define V_PCH_LPTH_USB_DEVICE_ID_EHCI_1 0x8C26 ///< LPT EHCI#1
+#define V_PCH_LPTH_USB_DEVICE_ID_EHCI_2 0x8C2D ///< LPT EHCI#2
+#define V_PCH_LPTH_USB_DEVICE_ID_XHCI_1 0x8C31 ///< LPT XHCI#1
+#define V_PCH_LPTLP_USB_DEVICE_ID_EHCI_1 0x9C26 ///< LPTLP EHCI#1
+#define V_PCH_LPTLP_USB_DEVICE_ID_XHCI_1 0x9C31 ///< LPTLP XHCI#1
+
+//
+// USB2 (EHCI) related definitions
+//
+typedef enum {
+ PchEhci1 = 0,
+ PchEhci2,
+ PchEhciControllerMax
+} PCH_USB20_CONTROLLER_TYPE;
+
+#define PCI_DEVICE_NUMBER_PCH_USB 29
+#define PCI_FUNCTION_NUMBER_PCH_EHCI 0
+
+#define PCI_DEVICE_NUMBER_PCH_USB_EXT 26
+#define PCI_FUNCTION_NUMBER_PCH_EHCI2 0
+
+//
+// EHCI PCI Config Space registers
+//
+#define R_PCH_EHCI_COMMAND_REGISTER 0x04
+#define B_PCH_EHCI_COMMAND_INTR_DIS BIT10
+#define B_PCH_EHCI_COMMAND_FBE BIT9
+#define B_PCH_EHCI_COMMAND_SERR_EN BIT8
+#define B_PCH_EHCI_COMMAND_WCC BIT7
+#define B_PCH_EHCI_COMMAND_PER BIT6
+#define B_PCH_EHCI_COMMAND_VPS BIT5
+#define B_PCH_EHCI_COMMAND_PMWE BIT4
+#define B_PCH_EHCI_COMMAND_SCE BIT3
+#define B_PCH_EHCI_COMMAND_BME BIT2
+#define B_PCH_EHCI_COMMAND_MSE BIT1
+#define B_PCH_EHCI_COMMAND_IOSE BIT0
+
+#define R_PCH_EHCI_PCISTS 0x06
+#define B_PCH_EHCI_PCISTS_DPE BIT15
+#define B_PCH_EHCI_PCISTS_SSE BIT14
+#define B_PCH_EHCI_PCISTS_RMA BIT13
+#define B_PCH_EHCI_PCISTS_RTA BIT12
+#define B_PCH_EHCI_PCISTS_STA BIT11
+#define B_PCH_EHCI_PCISTS_DEV_STS (BIT10 | BIT9)
+#define B_PCH_EHCI_PCISTS_DPED BIT8
+#define B_PCH_EHCI_PCISTS_FB2BC BIT7
+#define B_PCH_EHCI_PCISTS_UDF BIT6
+#define B_PCH_EHCI_PCISTS_66MHZ_CAP BIT5
+#define B_PCH_EHCI_PCISTS_CAP_LST BIT4
+#define B_PCH_EHCI_PCISTS_INTR_STS BIT3
+
+#define R_PCH_EHCI_RID 0x08
+#define B_PCH_EHCI_RID 0xFF
+#define R_PCH_EHCI_PI 0x09
+#define B_PCH_EHCI_PI 0xFF
+#define R_PCH_EHCI_SCC 0x0A
+#define B_PCH_EHCI_SCC 0xFF
+#define R_PCH_EHCI_BCC 0x0B
+#define B_PCH_EHCI_BCC 0xFF
+#define R_PCH_EHCI_MLT 0x0D
+#define B_PCH_EHCI_MLT 0xFF
+#define R_PCH_EHCI_HEADTYPE 0x0E
+#define B_PCH_EHCI_HEADTYPE 0xFF
+#define R_PCH_EHCI_MEM_BASE 0x10
+#define V_PCH_EHCI_MEM_LENGTH 0x400
+#define N_PCH_EHCI_MEM_ALIGN 10
+#define R_PCH_EHCI_SVID 0x2C
+#define B_PCH_EHCI_SVID 0xFFFF
+#define R_PCH_EHCI_SID 0x2E
+#define B_PCH_EHCI_SID 0xFFFF
+#define R_PCH_EHCI_CAP_PTR 0x34
+#define B_PCH_EHCI_CAP_PTR 0xFF
+#define R_PCH_EHCI_INT_LN 0x3C
+#define B_PCH_EHCI_INT_LN 0xFF
+#define R_PCH_EHCI_INT_PN 0x3D
+#define B_PCH_EHCI_INT_PN 0xFF
+#define R_PCH_EHCI_IHFCLK 0x44
+#define B_PCH_EHCI_IHFCLK 0xFFFFFFFF
+#define R_PCH_EHCI_IHFCLKC 0x48
+#define B_PCH_EHCI_IHFCLKC 0xFFFFFFFF
+#define R_PCH_EHCI_PWR_CAPID 0x50
+#define B_PCH_EHCI_PWR_CAPID 0xFF
+#define R_PCH_EHCI_NXT_PTR1 0x51
+#define B_PCH_EHCI_NXT_PTR1 0xFF
+#define R_PCH_EHCI_PWR_CAP 0x52
+#define B_PCH_EHCI_PWR_CAP_PME_SUP 0xF800
+#define B_PCH_EHCI_PWR_CAP_D2_SUP BIT10
+#define B_PCH_EHCI_PWR_CAP_D1_SUP BIT9
+#define B_PCH_EHCI_PWR_CAP_AUX_CUR (BIT8 | BIT7 | BIT6)
+#define B_PCH_EHCI_PWR_CAP_DSI BIT5
+#define B_PCH_EHCI_PWR_CAP_PME_CLK BIT3
+#define B_PCH_EHCI_PWR_CAP_VER (BIT2 | BIT1 | BIT0)
+#define R_PCH_EHCI_PWR_CNTL_STS 0x54
+#define B_PCH_EHCI_PWR_CNTL_STS_PME_STS BIT15
+#define B_PCH_EHCI_PWR_CNTL_STS_DATASCL (BIT14 | BIT13)
+#define B_PCH_EHCI_PWR_CNTL_STS_DATASEL (BIT12 | BIT11 | BIT10 | BIT9)
+#define B_PCH_EHCI_PWR_CNTL_STS_PME_EN BIT8
+#define B_PCH_EHCI_PWR_CNTL_STS_NO_SOFT_RESET BIT3
+#define B_PCH_EHCI_PWR_CNTL_STS_PWR_STS (BIT1 | BIT0)
+#define V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3 (BIT1 | BIT0)
+#define R_PCH_EHCI_DBG_CAPID 0x58
+#define B_PCH_EHCI_DBG_CAPID 0xFF
+#define R_PCH_EHCI_NXT_PTR2 0x59
+#define B_PCH_EHCI_NXT_PTR2 0xFF
+#define R_PCH_EHCI_DBG_BASE 0x5A
+#define B_PCH_EHCI_DBG_BASE_BAR_NUM 0xE000
+#define B_PCH_EHCI_DBG_BASE_PORT_OFFSET 0x1FFF
+#define R_PCH_EHCI_USB_RELNUM 0x60
+#define B_PCH_EHCI_USB_RELNUM 0xFF
+#define R_PCH_EHCI_FL_ADJ 0x61
+#define B_PCH_EHCI_FL_ADJ 0x3F
+#define R_PCH_EHCI_PWAKE_CAP 0x62
+#define B_PCH_EHCI_PWAKE_CAP_D29_MASK 0x01FE
+#define B_PCH_EHCI_PWAKE_CAP_D26_MASK 0x007E
+#define B_PCH_EHCI_PWAKE_CAP_PWK_IMP BIT0
+#define R_PCH_EHCI_PDO 0x64
+#define B_PCH_EHCI_PDO_DIS_PORT0 BIT0
+#define B_PCH_EHCI_PDO_D29_MASK 0xFF
+#define B_PCH_EHCI_PDO_D26_MASK 0x3F
+#define R_PCH_EHCI_RMHDEVR 0x66
+#define B_PCH_EHCI_RMHDEVR_D29_MASK 0x01FE
+#define B_PCH_EHCI_RMHDEVR_D26_MASK 0x007E
+#define R_PCH_EHCI_LEGEXT_CAP 0x68
+#define B_PCH_EHCI_LEGEXT_CAP_HCOS BIT24
+#define B_PCH_EHCI_LEGEXT_CAP_HCBIOS BIT16
+#define B_PCH_EHCI_LEGEXT_CAP_NEXT 0x0000FF00
+#define B_PCH_EHCI_LEGEXT_CAP_CAPID 0x000000FF
+#define R_PCH_EHCI_LEGEXT_CS 0x6C
+#define B_PCH_EHCI_LEGEXT_CS_SMIBAR BIT31
+#define B_PCH_EHCI_LEGEXT_CS_SMIPCI BIT30
+#define B_PCH_EHCI_LEGEXT_CS_SMIOS BIT29
+#define B_PCH_EHCI_LEGEXT_CS_SMIAA BIT21
+#define B_PCH_EHCI_LEGEXT_CS_SMIHSE BIT20
+#define B_PCH_EHCI_LEGEXT_CS_SMIFLR BIT19
+#define B_PCH_EHCI_LEGEXT_CS_SMIPCD BIT18
+#define B_PCH_EHCI_LEGEXT_CS_SMIERR BIT17
+#define B_PCH_EHCI_LEGEXT_CS_SMICOMP BIT16
+#define B_PCH_EHCI_LEGEXT_CS_SMIBAR_EN BIT15
+#define B_PCH_EHCI_LEGEXT_CS_SMIPCI_EN BIT14
+#define B_PCH_EHCI_LEGEXT_CS_SMIOS_EN BIT13
+#define B_PCH_EHCI_LEGEXT_CS_SMIAA_EN BIT5
+#define B_PCH_EHCI_LEGEXT_CS_SMIHSE_EN BIT4
+#define B_PCH_EHCI_LEGEXT_CS_SMIFLR_EN BIT3
+#define B_PCH_EHCI_LEGEXT_CS_SMIPCD_EN BIT2
+#define B_PCH_EHCI_LEGEXT_CS_SMIERR_EN BIT1
+#define B_PCH_EHCI_LEGEXT_CS_SMICOMP_EN BIT0
+#define R_PCH_EHCI_SPCSMI 0x70
+#define B_PCH_EHCI_SPCSMI_D29 0x3FC00000
+#define B_PCH_EHCI_SPCSMI_D26 0x0FC00000
+#define B_PCH_EHCI_SPCSMI_PMCSR BIT21
+#define B_PCH_EHCI_SPCSMI_ASYNC BIT20
+#define B_PCH_EHCI_SPCSMI_PERIODIC BIT19
+#define B_PCH_EHCI_SPCSMI_CF BIT18
+#define B_PCH_EHCI_SPCSMI_HCHALT BIT17
+#define B_PCH_EHCI_SPCSMI_HCRESET BIT16
+#define B_PCH_EHCI_SPCSMI_PO_EN 0x00003FC0
+#define B_PCH_EHCI_SPCSMI_PMCSR_EN BIT5
+#define B_PCH_EHCI_SPCSMI_ASYNC_EN BIT4
+#define B_PCH_EHCI_SPCSMI_PERIODIC_EN BIT3
+#define B_PCH_EHCI_SPCSMI_CF_EN BIT2
+#define B_PCH_EHCI_SPCSMI_HCHALT_EN BIT1
+#define B_PCH_EHCI_SPCSMI_HCRESET_EN BIT0
+#define R_PCH_EHCI_OCMAP 0x74
+#define R_PCH_EHCI_RMHWKCTL 0x7E
+#define R_PCH_EHCI_ACCESS_CNTL 0x80
+#define B_PCH_EHCI_ACCESS_CNTL_ENABLE BIT0
+#define V_PCH_EHCI_ACCESS_CNTL_ENABLE 0x01
+#define R_PCH_EHCI_FLR_CID 0x98
+#define B_PCH_EHCI_FLR_CID 0xFF
+#define V_PCH_EHCI_FLR_CID_13 0x13
+#define V_PCH_EHCI_FLR_CID_09 0x09
+#define R_PCH_EHCI_FLR_NEXT 0x99
+#define B_PCH_EHCI_FLR_NEXT 0xFF
+#define R_PCH_EHCI_FLR_CLV 0x9A
+#define B_PCH_EHCI_FLR_CLV_CAP_SSEL0 BIT9
+#define B_PCH_EHCI_FLR_CLV_TXP_SSEL0 BIT8
+#define B_PCH_EHCI_FLR_CLV_VSCID_SSEL1 0xF000
+#define B_PCH_EHCI_FLR_CLV_CAPVER_SSEL1 0x0F00
+#define B_PCH_EHCI_FLR_CLV_LNG 0x00FF
+#define R_PCH_EHCI_FLR_CTRL 0x9C
+#define B_PCH_EHCI_FLR_CTRL_INITFLR BIT0
+#define R_PCH_EHCI_FLR_STS 0x9D
+#define B_PCH_EHCI_FLR_STS_TXP BIT0
+
+//
+// EHCI MMIO registers
+//
+#define R_PCH_EHCI_HCSPARAMS 0x04
+#define N_PCH_EHCI_HCSPARAMS_DP_N 20
+#define N_PCH_EHCI_HCSPARAMS_N_CC 12
+#define N_PCH_EHCI_HCSPARAMS_N_PCC 8
+#define N_PCH_EHCI_HCSPARAMS_N_PORTS 0
+#define R_PCH_EHCI_USB2CMD 0x20
+#define B_PCH_EHCI_USB2CMD_ASE BIT5
+#define B_PCH_EHCI_USB2CMD_PSE BIT4
+#define B_PCH_EHCI_USB2CMD_HCRESET BIT1
+#define B_PCH_EHCI_USB2CMD_RS BIT0
+#define R_PCH_EHCI_USB2STS 0x24
+#define B_PCH_EHCI_USB2STS_HCHALTED BIT12
+#define R_PCH_EHCI_CONFIGFLAG 0x60
+#define R_PCH_EHCI_PORTSC0 0x64
+#define R_PCH_EHCI_PORTSC0_SUSPEND BIT7
+#define R_PCH_EHCI_PORTSC0_PORT_EN_DIS BIT2
+#define B_PCH_EHCI_PORTSC0_CHANGE_ENABLE_MASK (0x2A | R_PCH_EHCI_PORTSC0_PORT_EN_DIS) ///< Mask all change bits and port enabled
+#define B_PCH_EHCI_PORTSC0_RESET BIT8
+
+//
+// USB3 (XHCI) related definitions
+//
+#define PCI_DEVICE_NUMBER_PCH_XHCI 20
+#define PCI_FUNCTION_NUMBER_PCH_XHCI 0
+
+//
+// XHCI PCI Config Space registers
+//
+#define R_PCH_XHCI_COMMAND_REGISTER 0x04
+#define B_PCH_XHCI_COMMAND_BME BIT2
+#define B_PCH_XHCI_COMMAND_MSE BIT1
+#define R_PCH_XHCI_MEM_BASE 0x10
+#define V_PCH_XHCI_MEM_LENGTH 0x3000
+#define N_PCH_XHCI_MEM_ALIGN 16
+#define R_PCH_XHCI_SVID 0x2C
+#define B_PCH_XHCI_SVID 0xFFFF
+#define R_PCH_XHCI_SID 0x2E
+#define B_PCH_XHCI_SID 0xFFFF
+
+#define R_PCH_XHCI_XHCC1 0x40
+#define B_PCH_XHCI_XHCC1_ACCTRL BIT31
+#define B_PCH_XHCI_XHCC1_RMTASERR BIT24
+#define B_PCH_XHCI_XHCC1_URD BIT23
+#define B_PCH_XHCI_XHCC1_URRE BIT22
+#define B_PCH_XHCI_XHCC1_IIL1E (BIT21 | BIT20 | BIT19)
+#define V_PCH_XHCI_XHCC1_IIL1E_DIS 0
+#define V_PCH_XHCI_XHCC1_IIL1E_32 (BIT19)
+#define V_PCH_XHCI_XHCC1_IIL1E_64 (BIT20)
+#define V_PCH_XHCI_XHCC1_IIL1E_128 (BIT20 | BIT19)
+#define V_PCH_XHCI_XHCC1_IIL1E_256 (BIT21)
+#define V_PCH_XHCI_XHCC1_IIL1E_512 (BIT21 | BIT19)
+#define V_PCH_XHCI_XHCC1_IIL1E_1024 (BIT21 | BIT20)
+#define V_PCH_XHCI_XHCC1_IIL1E_131072 (BIT21 | BIT20 | BIT19)
+#define B_PCH_XHCI_XHCC1_XHCIL1E BIT18
+#define B_PCH_XHCI_XHCC1_D3IL1E BIT17
+#define B_PCH_XHCI_XHCC1_UNPPA (BIT16 | BIT15 | BIT14 | BIT13 | BIT12)
+#define B_PCH_XHCI_XHCC1_SWAXHCI BIT11
+#define B_PCH_XHCI_XHCC1_L23HRAWC (BIT10 | BIT9 | BIT8)
+#define B_PCH_XHCI_XHCC1_UTAGCP (BIT7 | BIT6)
+#define B_PCH_XHCI_XHCC1_UDAGCNP (BIT5 | BIT4)
+#define B_PCH_XHCI_XHCC1_UDAGCCP (BIT3 | BIT2)
+#define B_PCH_XHCI_XHCC1_UDAGC (BIT1 | BIT0)
+
+#define R_PCH_XHCI_XHCC2 0x44
+#define B_PCH_XHCI_XHCC2_OCCFDONE BIT31
+#define B_PCH_XHCI_XHCC2_XHCUPRDROE BIT11
+#define B_PCH_XHCI_XHCC2_IOSFSRAD BIT10
+#define B_PCH_XHCI_XHCC2_SWACXIHB (BIT9 | BIT8)
+#define B_PCH_XHCI_XHCC2_SWADMIL1IHB (BIT7 | BIT6)
+#define B_PCH_XHCI_XHCC2_L1FP2CGWC (BIT5 | BIT4 | BIT3)
+#define B_PCH_XHCI_XHCC2_RDREQSZCTRL (BIT2 | BIT1 | BIT0)
+
+#define R_PCH_XHCI_XHCLKGTEN 0x50
+#define B_PCH_XHCI_XHCLKGTEN_SSLSE BIT26
+#define B_PCH_XHCI_XHCLKGTEN_USB2PLLSE BIT25
+#define B_PCH_XHCI_XHCLKGTEN_IOSFSTCGE BIT24
+#define B_PCH_XHCI_XHCLKGTEN_HSTCGE (BIT23 | BIT22 | BIT21 | BIT20)
+#define B_PCH_XHCI_XHCLKGTEN_SSTCGE (BIT19 | BIT18 | BIT17 | BIT16)
+#define B_PCH_XHCI_XHCLKGTEN_XHCIGEU3S BIT15
+#define B_PCH_XHCI_XHCLKGTEN_XHCFTCLKSE BIT14
+#define B_PCH_XHCI_XHCLKGTEN_XHCBBTCGIPISO BIT13
+#define B_PCH_XHCI_XHCLKGTEN_XHCHSTCGU2NRWE BIT12
+#define B_PCH_XHCI_XHCLKGTEN_XHCUSB2PLLSDLE (BIT11 | BIT10)
+#define B_PCH_XHCI_XHCLKGTEN_HSPLLSUE (BIT9 | BIT8)
+#define B_PCH_XHCI_XHCLKGTEN_SSPLLSUE (BIT7 | BIT6 | BIT5)
+#define B_PCH_XHCI_XHCLKGTEN_XHCBLCGE BIT4
+#define B_PCH_XHCI_XHCLKGTEN_HSLTCGE BIT3
+#define B_PCH_XHCI_XHCLKGTEN_SSLTCGE BIT2
+#define B_PCH_XHCI_XHCLKGTEN_IOSFBTCGE BIT1
+#define B_PCH_XHCI_XHCLKGTEN_IOSFGBLCGE BIT0
+
+#define R_PCH_XHCI_USB_RELNUM 0x60
+#define B_PCH_XHCI_USB_RELNUM 0xFF
+#define R_PCH_XHCI_FL_ADJ 0x61
+#define B_PCH_XHCI_FL_ADJ 0x3F
+#define R_PCH_XHCI_PWR_CAPID 0x70
+#define B_PCH_XHCI_PWR_CAPID 0xFF
+#define R_PCH_XHCI_NXT_PTR1 0x71
+#define B_PCH_XHCI_NXT_PTR1 0xFF
+#define R_PCH_XHCI_PWR_CAP 0x72
+#define B_PCH_XHCI_PWR_CAP_PME_SUP 0xF800
+#define B_PCH_XHCI_PWR_CAP_D2_SUP BIT10
+#define B_PCH_XHCI_PWR_CAP_D1_SUP BIT9
+#define B_PCH_XHCI_PWR_CAP_AUX_CUR (BIT8 | BIT7 | BIT6)
+#define B_PCH_XHCI_PWR_CAP_DSI BIT5
+#define B_PCH_XHCI_PWR_CAP_PME_CLK BIT3
+#define B_PCH_XHCI_PWR_CAP_VER (BIT2 | BIT1 | BIT0)
+#define R_PCH_XHCI_PWR_CNTL_STS 0x74
+#define B_PCH_XHCI_PWR_CNTL_STS_PME_STS BIT15
+#define B_PCH_XHCI_PWR_CNTL_STS_DATASCL (BIT14 | BIT13)
+#define B_PCH_XHCI_PWR_CNTL_STS_DATASEL (BIT12 | BIT11 | BIT10 | BIT9)
+#define B_PCH_XHCI_PWR_CNTL_STS_PME_EN BIT8
+#define B_PCH_XHCI_PWR_CNTL_STS_PWR_STS (BIT1 | BIT0)
+#define V_PCH_XHCI_PWR_CNTL_STS_PWR_STS_D3 (BIT1 | BIT0)
+
+#define R_PCH_XHCI_U2OCM1 0xC0
+#define B_PCH_XHCI_U2OCM1_OC4_MAPPING 0xFF000000
+#define B_PCH_XHCI_U2OCM1_OC3_MAPPING 0x00FF0000
+#define B_PCH_XHCI_U2OCM1_OC2_MAPPING 0x0000FF00
+#define B_PCH_XHCI_U2OCM1_OC1_MAPPING 0x000000FF
+
+#define R_PCH_XHCI_U2OCM2 0xC4
+#define B_PCH_XHCI_U2OCM2_OC8_MAPPING 0x3F000000
+#define B_PCH_XHCI_U2OCM2_OC7_MAPPING 0x003F0000
+#define B_PCH_XHCI_U2OCM2_OC6_MAPPING 0x00003F00
+#define B_PCH_XHCI_U2OCM2_OC5_MAPPING 0x0000003F
+
+#define R_PCH_XHCI_U3OCM1 0xC8
+#define B_PCH_XHCI_U3OCM1_OC4_MAPPING 0x3F000000
+#define B_PCH_XHCI_U3OCM1_OC3_MAPPING 0x003F0000
+#define B_PCH_XHCI_U3OCM1_OC2_MAPPING 0x00003F00
+#define B_PCH_XHCI_U3OCM1_OC1_MAPPING 0x0000003F
+
+#define R_PCH_XHCI_U3OCM2 0xCC
+#define B_PCH_XHCI_U3OCM2_OC8_MAPPING 0x3F000000
+#define B_PCH_XHCI_U3OCM2_OC7_MAPPING 0x003F0000
+#define B_PCH_XHCI_U3OCM2_OC6_MAPPING 0x00003F00
+#define B_PCH_XHCI_U3OCM2_OC5_MAPPING 0x0000003F
+
+#define R_PCH_XHCI_USB2PR 0xD0
+#define B_PCH_XHCI_USB2PR_USB2HCSEL 0x7FFF
+#define R_PCH_XHCI_USB2PRM 0xD4
+#define B_PCH_XHCI_USB2PR_USB2HCSELM 0x7FFF
+
+#define R_PCH_XHCI_USB3PR 0xD8
+#define B_PCH_XHCI_USB3PR_USB3SSEN 0x3F
+#define R_PCH_XHCI_USB3PRM 0xDC
+#define B_PCH_XHCI_USB3PR_USB3SSENM 0x3F
+
+#define R_PCH_XHCI_FUS 0xE0
+#define B_PCH_XHCI_FUS_USBR (BIT5)
+#define V_PCH_XHCI_FUS_USBR_EN 0
+#define V_PCH_XHCI_FUS_USBR_DIS (BIT5)
+
+#define B_PCH_XHCI_FUS_SSPRTCNT (BIT4 | BIT3)
+#define V_PCH_XHCI_FUS_SSPRTCNT_00B 0
+#define V_PCH_XHCI_FUS_SSPRTCNT_01B (BIT3)
+#define V_PCH_XHCI_FUS_SSPRTCNT_10B (BIT4)
+#define V_PCH_XHCI_FUS_SSPRTCNT_11B (BIT4 | BIT3)
+
+#define B_PCH_XHCI_FUS_HSPRTCNT (BIT2 | BIT1)
+#define V_PCH_XHCI_FUS_HSPRTCNT_00B 0
+#define V_PCH_XHCI_FUS_HSPRTCNT_01B (BIT1)
+#define V_PCH_XHCI_FUS_HSPRTCNT_10B (BIT2)
+#define V_PCH_XHCI_FUS_HSPRTCNT_11B (BIT2 | BIT1)
+
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_00B_CNT 6
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_01B_CNT 4
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_10B_CNT 2
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_11B_CNT 0
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_00B_MASK 0x3F
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_01B_MASK 0x0F
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_10B_MASK 0x03
+#define V_PCH_H_XHCI_FUS_SSPRTCNT_11B_MASK 0x00
+
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_00B_CNT 14
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_01B_CNT 12
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_10B_CNT 10
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_11B_CNT 8
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_00B_MASK 0x3FFF
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_01B_MASK 0x3FFF
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_10B_MASK 0x0FFF
+#define V_PCH_H_XHCI_FUS_HSPRTCNT_11B_MASK 0x00FF
+
+#define V_PCH_LP_XHCI_FIXED_SSPRTCNT 4
+#define V_PCH_LP_XHCI_FIXED_SSPRTCNT_MASK 0x0F
+
+#define V_PCH_LP_XHCI_FIXED_HSPRTCNT 8
+#define V_PCH_LP_XHCI_FIXED_HSPRTCNT_MASK 0x00FF
+
+#define R_PCH_XHCI_USB2PDO 0xE4
+#define B_PCH_XHCI_USB2PDO_MASK 0x7FFF
+#define B_PCH_XHCI_USB2PDO_DIS_PORT0 BIT0
+
+#define R_PCH_XHCI_USB3PDO 0xE8
+#define B_PCH_XHCI_USB3PDO_MASK 0x3F
+#define B_PCH_XHCI_USB3PDO_DIS_PORT0 BIT0
+
+//
+// xHCI MMIO registers
+//
+
+//
+// 0x00 - 0x1F - Capability Registers
+//
+#define R_PCH_XHCI_CAPLENGTH 0x00
+#define R_PCH_XHCI_HCIVERSION 0x02
+#define R_PCH_XHCI_HCSPARAMS1 0x04
+#define R_PCH_XHCI_HCSPARAMS2 0x08
+#define R_PCH_XHCI_HCSPARAMS3 0x0C
+#define B_PCH_XHCI_HCSPARAMS3_U2DEL 0xFFFF0000
+#define B_PCH_XHCI_HCSPARAMS3_U1DEL 0x0000FFFF
+#define R_PCH_XHCI_HCCPARAMS 0x10
+#define B_PCH_XHCI_HCCPARAMS_LHRC BIT5
+#define B_PCH_XHCI_HCCPARAMS_MAXPSASIZE 0xF000
+#define R_PCH_XHCI_DBOFF 0x14
+#define R_PCH_XHCI_RTSOFF 0x18
+
+//
+// 0x80 - 0xBF - Operational Registers
+//
+#define R_PCH_XHCI_USBCMD 0x80
+#define B_PCH_XHCI_USBCMD_RS BIT0 ///< Run/Stop
+#define B_PCH_XHCI_USBCMD_RST BIT1 ///< HCRST
+#define R_PCH_XHCI_USBSTS 0x84
+
+//
+// 0x480 - 0x5CF - Port Status and Control Registers
+//
+#define R_PCH_XHCI_PORTSC01USB2 0x480
+#define R_PCH_XHCI_PORTSC02USB2 0x490
+#define R_PCH_XHCI_PORTSC03USB2 0x4A0
+#define R_PCH_XHCI_PORTSC04USB2 0x4B0
+#define R_PCH_XHCI_PORTSC05USB2 0x4C0
+#define R_PCH_XHCI_PORTSC06USB2 0x4D0
+#define R_PCH_XHCI_PORTSC07USB2 0x4E0
+#define R_PCH_XHCI_PORTSC08USB2 0x4F0
+#define R_PCH_XHCI_PORTSC09USB2 0x500
+#define R_PCH_H_XHCI_PORTSC10USB2 0x510
+#define R_PCH_H_XHCI_PORTSC11USB2 0x520
+#define R_PCH_H_XHCI_PORTSC12USB2 0x530
+#define R_PCH_H_XHCI_PORTSC13USB2 0x540
+#define R_PCH_H_XHCI_PORTSC14USB2 0x550
+#define R_PCH_H_XHCI_PORTSC15USB2 0x560
+
+#define B_PCH_XHCI_PORTSCXUSB2_WPR BIT31 ///< Warm Port Reset
+#define B_PCH_XHCI_PORTSCXUSB2_CEC BIT23 ///< Port Config Error Change
+#define B_PCH_XHCI_PORTSCXUSB2_PLC BIT22 ///< Port Link State Change
+#define B_PCH_XHCI_PORTSCXUSB2_PRC BIT21 ///< Port Reset Change
+#define B_PCH_XHCI_PORTSCXUSB2_OCC BIT20 ///< Over-current Change
+#define B_PCH_XHCI_PORTSCXUSB2_WRC BIT19 ///< Warm Port Reset Change
+#define B_PCH_XHCI_PORTSCXUSB2_PEC BIT18 ///< Port Enabled Disabled Change
+#define B_PCH_XHCI_PORTSCXUSB2_CSC BIT17 ///< Connect Status Change
+#define B_PCH_XHCI_PORTSCXUSB2_LWS BIT16 ///< Port Link State Write Strobe
+#define B_PCH_XHCI_USB2_U3_EXIT (BIT5 | BIT6 | BIT7 | BIT8)
+#define B_PCH_XHCI_USB2_U0_MASK (BIT5 | BIT6 | BIT7 | BIT8)
+#define B_PCH_XHCI_PORTSCXUSB2_PP BIT9
+#define B_PCH_XHCI_PORTSCXUSB2_PR BIT4 ///< Port Reset
+#define B_PCH_XHCI_PORTSCXUSB2_PED BIT1 ///< Port Enable/Disabled
+#define B_PCH_XHCI_PORTSCXUSB2_CCS BIT0 ///< Current Connect Status
+#define B_PCH_XHCI_PORT_CHANGE_ENABLE_MASK (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 | B_PCH_XHCI_PORTSCXUSB2_PED)
+
+#define R_PCH_H_XHCI_PORTSC1USB3 0x570
+#define R_PCH_H_XHCI_PORTSC2USB3 0x580
+#define R_PCH_H_XHCI_PORTSC3USB3 0x590
+#define R_PCH_H_XHCI_PORTSC4USB3 0x5A0
+#define R_PCH_H_XHCI_PORTSC5USB3 0x5B0
+#define R_PCH_H_XHCI_PORTSC6USB3 0x5C0
+
+#define R_PCH_LP_XHCI_PORTSC1USB3 0x510
+#define R_PCH_LP_XHCI_PORTSC2USB3 0x520
+#define R_PCH_LP_XHCI_PORTSC3USB3 0x530
+#define R_PCH_LP_XHCI_PORTSC4USB3 0x540
+
+#define B_PCH_XHCI_PORTSCXUSB3_WPR BIT31 ///< Warm Port Reset
+#define B_PCH_XHCI_PORTSCXUSB3_CEC BIT23 ///< Port Config Error Change
+#define B_PCH_XHCI_PORTSCXUSB3_PLC BIT22 ///< Port Link State Change
+#define B_PCH_XHCI_PORTSCXUSB3_PRC BIT21 ///< Port Reset Change
+#define B_PCH_XHCI_PORTSCXUSB3_OCC BIT20 ///< Over-current Change
+#define B_PCH_XHCI_PORTSCXUSB3_WRC BIT19 ///< Warm Port Reset Change
+#define B_PCH_XHCI_PORTSCXUSB3_PEC BIT18 ///< Port Enabled Disabled Change
+#define B_PCH_XHCI_PORTSCXUSB3_CSC BIT17 ///< Connect Status Change
+#define B_PCH_XHCI_PORTSCXUSB3_LWS BIT16 ///< Port Link State Write Strobe //AMI_OVERRITE
+#define B_PCH_XHCI_PORTSCXUSB3_PLS (BIT8 | BIT7 | BIT6 | BIT5) ///< Port Link State
+#define V_PCH_XHCI_PORTSCXUSB3_PLS_POLLING 0x000000E0 ///< Link is in the Polling State
+#define V_PCH_XHCI_PORTSCXUSB3_PLS_RXDETECT 0x000000A0 ///< Link is in the RxDetect State
+#define B_PCH_XHCI_PORTSCXUSB3_PP BIT9 ///< Port Power //AMI_OVERRITE
+#define B_PCH_XHCI_PORTSCXUSB3_PR BIT4 ///< Port Reset
+#define B_PCH_XHCI_PORTSCXUSB3_PED BIT1 ///< Port Enable/Disabled
+#define B_PCH_XHCI_PORTSCXUSB3_CHANGE_ENABLE_MASK (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 | B_PCH_XHCI_PORTSCXUSB3_PED)
+//
+// 0x2000 - 0x21FF - Runtime Registers
+// 0x3000 - 0x307F - Doorbell Registers
+//
+
+//
+// 0x8000 - 0x833F - Extended Capabilities Registers
+//
+#define R_PCH_XHCI_MMIO_ECR_8058 0x8058
+#define B_PCH_XHCI_MMIO_ECR_8058_BIT8 BIT8 ///< Set 0
+
+#define R_PCH_XHCI_MMIO_ECR_8090 0x8090
+#define B_PCH_XHCI_MMIO_ECR_8090_BIT14 BIT14 ///< Set 1
+#define B_PCH_XHCI_MMIO_ECR_8090_BIT8 BIT8 ///< Set 1
+
+#define R_PCH_XHCI_MMIO_ECR_8094 0x8094
+#define B_PCH_XHCI_MMIO_ECR_8094_BIT23 BIT23 ///< Set 1
+
+#define R_PCH_XHCI_MMIO_ECR_80E0 0x80E0
+#define B_PCH_XHCI_MMIO_ECR_80E0_BIT9 BIT9 ///< Set 1
+#define B_PCH_XHCI_MMIO_ECR_80E0_BIT6 BIT6 ///< Set 1
+
+#define R_PCH_XHCI_MMIO_ECR_80EC 0x80EC
+#define B_PCH_XHCI_MMIO_ECR_80EC_BIT_14_12 0x7000 ///< Set 6
+#define B_PCH_XHCI_MMIO_ECR_80EC_BIT_11_9 0x0E00 ///< Set 6
+
+#define R_PCH_XHCI_MMIO_ECR_8110 0x8110
+#define B_PCH_XHCI_MMIO_ECR_8110_BIT2 BIT2 ///< Set 0
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Include/PchUsbConfig.h b/ReferenceCode/Chipset/LynxPoint/Include/PchUsbConfig.h
new file mode 100644
index 0000000..61fc690
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Include/PchUsbConfig.h
@@ -0,0 +1,178 @@
+/** @file
+ General USB Configurate data structure and register definitions.
+
+@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_CONFIG_H_
+#define _PCH_USB_CONFIG_H_
+
+///
+/// ---------------------------- USB Config -----------------------------
+///
+///
+/// Overcurrent pins, the values match the setting of PCH EDS, please refer to PCH EDS for more details
+///
+typedef enum {
+ PchUsbOverCurrentPin0 = 0,
+ PchUsbOverCurrentPin1,
+ PchUsbOverCurrentPin2,
+ PchUsbOverCurrentPin3,
+ PchUsbOverCurrentPin4,
+ PchUsbOverCurrentPin5,
+ PchUsbOverCurrentPin6,
+ PchUsbOverCurrentPin7,
+ PchUsbOverCurrentPinSkip,
+ PchUsbOverCurrentPinMax
+} PCH_USB_OVERCURRENT_PIN;
+
+//
+// The location of the USB connectors. This information is use to decide eye diagram tuning value for Usb 2.0 motherboard trace.
+//
+typedef enum {
+ PchUsbPortLocationBackPanel = 0,
+ PchUsbPortLocationFrontPanel,
+ PchUsbPortLocationDock,
+ PchUsbPortLocationMiniPciE,
+ PchUsbPortLocationFlex,
+ PchUsbPortLocationInternalTopology,
+ PchUsbPortLocationSkip,
+ PchUsbPortLocationMax
+} PCH_USB_PORT_LOCATION;
+
+typedef struct {
+ UINT8 Enable : 1; ///< 0: Disable; 1: Enable. This would take effect while UsbPerPortCtl is enabled
+ UINT8 Rsvdbits : 7;
+ UINT8 Location; // The location of the USB connectors. Please use the enum PCH_USB_PORT_LOCATION.
+ UINT16 Usb20PortLength; // The length of Usb Port to configure the USB transmitter, bits [16:4] represents length of Usb Port in inches using octal format and [3:0] is for the decimal Point.
+ UINT8 Usb20EyeDiagramTuningParam1; // Set IOBP registers 0xE5004000 + (PortNumber * 0x100)[10:08] = {0,1,2,3,4,5,6,7}
+ UINT8 Usb20EyeDiagramTuningParam2; // Set IOBP registers 0xE5004000 + (PortNumber * 0x100)[13:11] = {0,1,2,3,4,5,6,7}
+} PCH_USB_PORT_SETTINGS;
+
+typedef struct {
+ UINT8 Enable : 1; ///< 0: Disable; 1: Enable. This would take effect while UsbPerPortCtl is enabled
+ UINT8 Rsvdbits : 7; ///< Reserved fields for future expansion w/o protocol change;
+} PCH_USB30_PORT_SETTINGS;
+
+typedef struct {
+ UINT8 Enable : 1; ///< 0: Disable; 1: Enable
+ UINT8 Rsvdbits : 7;
+} PCH_USB20_CONTROLLER_SETTINGS;
+
+#define PCH_XHCI_MODE_OFF 0
+#define PCH_XHCI_MODE_ON 1
+#define PCH_XHCI_MODE_AUTO 2
+#define PCH_XHCI_MODE_SMARTAUTO 3
+
+#define PCH_XHCI_STREAMS_OFF 0
+#define PCH_XHCI_STREAMS_ON 1
+
+#define EHCI_PRECONDITION(Device, EhciMmioBase) \
+ EhciPrecondition(Device, EhciMmioBase)
+#define XHCI_PRECONDITION(BusNumber, Device, Function, XhciMmioBase, USB2Ptr, HsPortCount, USB3Ptr, SsPortCount) \
+ XhciPrecondition(BusNumber, Device, Function, XhciMmioBase, USB2Ptr, HsPortCount, USB3Ptr, SsPortCount)
+
+typedef struct {
+ UINT8 Mode : 2; ///< 0: Disable; 1: Enable, 2: Auto, 3: Smart Auto
+ UINT8 PreBootSupport : 1; ///< 0: No xHCI driver available; 1: xHCI driver available
+ UINT8 XhciStreams : 1; ///< OBSOLETE from Revision 2 !!! DO NOT USE !!!
+ UINT8 ManualMode : 1; ///< 0: Disable; 1: Enable Manual Mode
+ UINT8 XhciIdleL1 : 1; ///< 0: Disable; 1: Enable
+ UINT8 Btcg : 1; ///<.0:.Disable; 1: Enable trunk clock gating
+ UINT8 Rsvdbits : 1;
+ UINT8 ManualModeUsb20PerPinRoute[LPTH_USB_MAX_PHYSICAL_PORTS]; ///< 0: EHCI; 1 :XHCI;
+ UINT8 ManualModeUsb30PerPinEnable[LPTH_XHCI_MAX_USB3_PORTS]; ///< 0: Disable; 1:Enable;
+} PCH_USB30_CONTROLLER_SETTINGS;
+
+///
+/// This member describes the expected configuration of the PCH USB controllers,
+/// Platform modules may need to refer Setup options, schematic, BIOS specification
+/// to update this field.
+/// The Usb20OverCurrentPins and Usb30OverCurrentPins field must be updated by refer
+/// the schematic.
+///
+typedef struct {
+ ///
+ /// This member describes whether the USB per-port controlling feature of PCH is
+ /// enabled by platform modules. If enabled, the USB Port N of PCH can be
+ /// enabled/disabled by setting PortSettings[N] to enabled/disabled.
+ ///
+ UINT8 UsbPerPortCtl : 1; ///< 0: Disable; 1: Enable Per-port enable control
+ ///
+ /// This member describes whether or not EHCI 1 USBR should be enabled.
+ ///
+ UINT8 Ehci1Usbr : 1; ///< 0: Disable; 1: Enable EHCI 1 USBR
+ ///
+ /// This member describes whether or not EHCI 2 USBR should be enabled.
+ ///
+ UINT8 Ehci2Usbr : 1; ///< 0: Disable; 1: Enable EHCI 2 USBR
+ UINT8 RsvdBits : 5;
+ ///
+ /// These members describe whether the USB2 Port N of PCH is enabled by platform modules.
+ /// They would take effect while UsbPerPortCtl is enabled. Panel and Dock are used to
+ /// describe the layout of USB port. Panel is only available for Desktop LPT.
+ /// Dock is only available for Mobile LPT.
+ ///
+ PCH_USB_PORT_SETTINGS PortSettings[LPTH_USB_MAX_PHYSICAL_PORTS];
+ ///
+ /// These members describe whether the USB 2.0 controller N of PCH is enabled by
+ /// platform modules.
+ ///
+ PCH_USB20_CONTROLLER_SETTINGS Usb20Settings[PchEhciControllerMax];
+ ///
+ /// These members describe some settings which are related to the USB 3.0 controller.
+ /// While ManualMode is set to 1, ManualModeUsb20PerPinRoute[] and ManualModeUsb30PerPinEnable[]
+ /// need to be programmed properly per the platform design.
+ /// While ManualModeUsb20PerPinRoute[] is set to 1, it means routes USB2 pins to the
+ /// XHCI controller. ManualModeUsb30PerPinEnable[] is used to control whether Super Speed
+ /// capability is enabled for a given USB3 port.
+ ///
+ PCH_USB30_CONTROLLER_SETTINGS Usb30Settings;
+ ///
+ /// These members describe the specific over current pin number of USB 2.0 Port N.
+ /// It is SW's responsibility to ensure that a given port's bit map is set only for
+ /// one OC pin Description. USB2 and USB3 on the same combo Port must use the same
+ /// OC pin.
+ ///
+ PCH_USB_OVERCURRENT_PIN Usb20OverCurrentPins[LPTH_USB_MAX_PHYSICAL_PORTS];
+ ///
+ /// These members describe the specific over current pin number of USB 3.0 Port N.
+ /// It is SW's responsibility to ensure that a given port's bit map is set only for
+ /// one OC pin Description. USB2 and USB3 on the same combo Port must use the same
+ /// OC pin.
+ ///
+ PCH_USB_OVERCURRENT_PIN Usb30OverCurrentPins[LPTH_XHCI_MAX_USB3_PORTS];
+ ///
+ /// This feature intends to reduce the necessary initialization time for USB HC
+ /// and devices on root ports. It is assembled by PCHInit drivers in PEI and DXE phase.
+ /// In PEI phase, the feature resets all USB HCs on PCH bus, including Intel EHCI
+ /// and XHCI. After reset USB HC, continue the system initialization without waiting
+ /// for the USB XHC reset ready. After running to DXE phase, the feature resets
+ /// those USB devices installed on each USB HC root port in parallel, including RMH
+ /// on EHCI root port 0 and any non USB3 speed devices on XHCI root port if XHCI is
+ /// enabled. For USB3 protocol root port, USB3 speed devices will be advanced to
+ /// enable state if link training succeeds after XHC reset.
+ ///
+ BOOLEAN UsbPrecondition;
+ ///
+ /// These members describe whether the USB3 Port N of PCH is enabled by platform modules.
+ /// They would take effect while UsbPerPortCtl is enabled.
+ ///
+ PCH_USB30_PORT_SETTINGS Port30Settings[LPTH_XHCI_MAX_USB3_PORTS];
+} PCH_USB_CONFIG;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c
new file mode 100644
index 0000000..74cb450
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.c
@@ -0,0 +1,884 @@
+/** @file
+ Main implementation source file for the Io Trap SMM driver
+
+@copyright
+ Copyright (c) 2006 - 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 "IoTrap.h"
+
+//
+// Module global variables
+//
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_HANDLE mDriverImageHandle;
+EFI_SMM_ICHN_DISPATCH_PROTOCOL *mIchnDispatch;
+EFI_SMM_ICHN_DISPATCH_CONTEXT mIchnContext;
+EFI_HANDLE mIchnHandle;
+UINT32 mPchRootComplexBar;
+
+IO_TRAP_INSTANCE mIoTrapData;
+IO_TRAP_RECORD *mIoTrapRecord;
+
+static CONST UINT16 mLengthTable[7] = { 4, 8, 16, 32, 64, 128, 256 };
+
+/**
+ Register a new IO Trap SMI dispatch function with a parent SMM driver.
+ The caller will provide information about the IO trap characteristics via
+ the context. This includes base address, length, read vs. r/w, etc.
+ This function will autoallocate IO base address from a common pool if the base address is 0,
+ and the RegisterContext Address field will be updated.
+ The service will not perform GCD allocation if the base address is non-zero.
+ In this case, the caller is responsible for the existence and allocation of the
+ specific IO range.
+ This function looks for the suitable handler and Register a new IchnIoTrap handler
+ if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+ SMI.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for
+ this SMI source.
+ @param[in, out] RegisterContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling
+ the register function to indicate to the register
+ function the IO trap SMI source for which the dispatch
+ function should be invoked. This may not be NULL.
+ @param[out] DispatchHandle Handle of dispatch function, for when interfacing
+ with the parent SMM driver, will be the address of linked
+ list link in the call back record. This may not be NULL.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+ @retval EFI_DEVICE_ERROR The driver was unable to enable the SMI source.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+ @retval EFI_INVALID_PARAMETER Address requested is already in use.
+**/
+static
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK DispatchFunction,
+ IN OUT EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT *RegisterContext,
+ OUT EFI_HANDLE *DispatchHandle
+ )
+{
+ EFI_STATUS Status;
+ static CONST UINT16 IoTrapHandlerList[IO_TRAP_HANDLER_NUM] = { IchnIoTrap0, IchnIoTrap1, IchnIoTrap2, IchnIoTrap3 };
+ EFI_PHYSICAL_ADDRESS NextBaseAddress;
+ UINT32 NextUsedLength;
+ UINT8 NextTrapHandlerNum;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+ UINT32 IoTrapRegLowDword;
+ UINT32 IoTrapRegHighDword;
+ UINT8 LengthIndex;
+
+ //
+ // Return error if the type is invalid
+ //
+ if (RegisterContext->Type >= IoTrapTypeMaximum) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch Type %0X is invalid! \n", RegisterContext->Type));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Return error if the Length is invalid
+ //
+ if (RegisterContext->Length < 1 || RegisterContext->Length > 0x100) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch Length %0X is invalid! \n", RegisterContext->Length));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Return error if the address is invalid
+ //
+ if (RegisterContext->Address % 4 != 0) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch address %0X is invalid! \n", RegisterContext->Address));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Loop through the first IO Trap handler, looking for the suitable handler
+ //
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ //
+ // Check if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ //
+ // Search available IO address and allocate it if the IO address is 0
+ //
+ BaseAddress = RegisterContext->Address;
+ if (BaseAddress == 0) {
+ //
+ // Allocate 256 byte range from GCD for common pool usage
+ //
+ Status = gDS->AllocateIoSpace (
+ EfiGcdAllocateAnySearchBottomUp,
+ EfiGcdIoTypeIo,
+ 8,
+ 0x100,
+ &BaseAddress,
+ mDriverImageHandle,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Can't find any available IO address! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ RegisterContext->Address = (UINT16) BaseAddress;
+ UsedLength = 0x100;
+ mIoTrapData.TrapUsedLength[TrapHandlerNum] = RegisterContext->Length;
+ } else {
+ //
+ // PCH only support dword * power of 2 alignment
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (RegisterContext->Length == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Return error if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ DEBUG ((EFI_D_ERROR, "The PCH only support dword * power of 2 alignment! \n"));
+ DEBUG ((EFI_D_ERROR, "The Dispatch Length %0X is 0 or invalid! \n", RegisterContext->Length));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UsedLength = RegisterContext->Length;
+ }
+
+ //
+ // Register a new IchnIoTrap handler
+ //
+ mIchnContext.Type = IoTrapHandlerList[TrapHandlerNum];
+ mIchnHandle = NULL;
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ IoTrapCallback,
+ &mIchnContext,
+ &mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ mIoTrapData.IchnIoTrapHandle[TrapHandlerNum] = mIchnHandle;
+ //
+ // Fill in the Length, address and Enable the IO Trap SMI
+ //
+ IoTrapRegLowDword = (UINT32) (((UsedLength - 1) & ~(BIT1 + BIT0)) << 16) |
+ (UINT16) BaseAddress |
+ B_PCH_RCRB_IO_TRAP_TRSE;
+
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+
+ IoTrapRegHighDword = 0x000000F0 | (UINT32) (RegisterContext->Type << N_PCH_RCRB_IO_TRAP_RWIO);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ //
+ // Set MergeDisable flag of the registered IoTrap
+ //
+ mIoTrapData.MergeDisable[TrapHandlerNum] = RegisterContext->MergeDisable;
+ } else {
+ //
+ // Check next handler if MergeDisable is TRUE or the registered IoTrap if MergeDisable is TRUE
+ //
+ if ((RegisterContext->MergeDisable == TRUE) || (mIoTrapData.MergeDisable[TrapHandlerNum] == TRUE)) {
+ continue;
+ }
+ //
+ // The IO Trap handler is used, calculate the Length
+ //
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+ //
+ // Assign an addfress from common pool if the caller's address is 0
+ //
+ if (RegisterContext->Address == 0) {
+ //
+ // Check next handler if it's fully used
+ //
+ if (mIoTrapData.TrapUsedLength[TrapHandlerNum] >= 0x100) {
+ continue;
+ }
+ //
+ // Check next handler if it's not for a common pool
+ //
+ if (UsedLength < 0x100) {
+ continue;
+ }
+ //
+ // Check next handler if the size is too big
+ //
+ if (RegisterContext->Length >= (UINT16) 0x100 - mIoTrapData.TrapUsedLength[TrapHandlerNum]) {
+ continue;
+ }
+ //
+ // For common pool, we don't need to change the BaseAddress and UsedLength
+ //
+ RegisterContext->Address = (UINT16) (BaseAddress + mIoTrapData.TrapUsedLength[TrapHandlerNum]);
+ mIoTrapData.TrapUsedLength[TrapHandlerNum] += RegisterContext->Length;
+ } else {
+ //
+ // Check next handler if the address is smaller than the IO trap handler's start address
+ //
+ if (RegisterContext->Address < (UINT16) BaseAddress) {
+ continue;
+ }
+ //
+ // Check next handler if the max address is bigger than IO trap handler's range
+ //
+ if ((RegisterContext->Address + RegisterContext->Length) > (UINT16) (BaseAddress + 256)) {
+ continue;
+ }
+ //
+ // If this handler is used for common pool, assert if the caller's address is within the range
+ //
+ if (mIoTrapData.TrapUsedLength[TrapHandlerNum] != 0) {
+ DEBUG ((EFI_D_ERROR, "The Dispatch address %0x is used for common pool! \n", RegisterContext->Address));
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Calculate the Length which is maximum use address - start address
+ //
+ UsedLength = RegisterContext->Address + RegisterContext->Length - (UINT16) BaseAddress;
+ //
+ // Check the alignment is dword * power of 2 or not
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (UsedLength == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Check next handler if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ continue;
+ }
+ //
+ // Merge the overlap range: remove next Io Trap handler if next Io Trap handler's range is within this handler's range
+ //
+ for (NextTrapHandlerNum = TrapHandlerNum + 1; NextTrapHandlerNum != TrapHandlerNum; NextTrapHandlerNum++) {
+ //
+ // Check if NextTrapHandlerNum overflow
+ //
+ if (NextTrapHandlerNum >= IO_TRAP_HANDLER_NUM) {
+ NextTrapHandlerNum = 0;
+ }
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8);
+ //
+ // Check next handler if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ continue;
+ }
+ //
+ // Check if next Io Trap handler's range is within this handler's range
+ //
+ NextUsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ NextBaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+ if ((BaseAddress > NextBaseAddress) || ((BaseAddress + UsedLength) < (NextBaseAddress + NextUsedLength))) {
+ continue;
+ }
+ //
+ // Unregister the IO Trap handler
+ //
+ mIchnHandle = mIoTrapData.IchnIoTrapHandle[NextTrapHandlerNum];
+ mIchnContext.Type = IoTrapHandlerList[NextTrapHandlerNum];
+ Status = mIchnDispatch->UnRegister (
+ mIchnDispatch,
+ mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Clear the Io Trap handler register
+ //
+ IoTrapRegLowDword = 0;
+ IoTrapRegHighDword = 0;
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + NextTrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ }
+ //
+ // Update the Length
+ //
+ IoTrapRegLowDword = (UINT32) (((UsedLength - 1) & ~(BIT1 + BIT0)) << 16) |
+ (UINT16) BaseAddress |
+ B_PCH_RCRB_IO_TRAP_TRSE;
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8,
+ (UINT32) (IoTrapRegLowDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ }
+ //
+ // Only set RWM bit when we need both read and write cycles.
+ //
+ IoTrapRegHighDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4);
+ if ((IoTrapRegHighDword & B_PCH_RCRB_IO_TRAP_RWM) == 0 &&
+ (UINT32) ((IoTrapRegHighDword & B_PCH_RCRB_IO_TRAP_RWIO) >> N_PCH_RCRB_IO_TRAP_RWIO) !=
+ (UINT32) RegisterContext->Type) {
+ IoTrapRegHighDword = ((IoTrapRegHighDword | B_PCH_RCRB_IO_TRAP_RWM) & ~B_PCH_RCRB_IO_TRAP_RWIO);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+ }
+ }
+ break;
+ }
+
+ if (TrapHandlerNum >= IO_TRAP_HANDLER_NUM) {
+ DEBUG ((EFI_D_ERROR, "All IO Trap handler is used, no available IO Trap handler! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Create database record and add to database
+ //
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (IO_TRAP_RECORD),
+ (VOID **) &mIoTrapRecord
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for mIoTrapRecord! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Gather information about the registration request
+ //
+ mIoTrapRecord->Signature = IO_TRAP_RECORD_SIGNATURE;
+ mIoTrapRecord->Context = *RegisterContext;
+ mIoTrapRecord->Callback = DispatchFunction;
+
+ InsertTailList (&mIoTrapData.CallbackDataBase, &mIoTrapRecord->Link);
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *DispatchHandle = (EFI_HANDLE) (&mIoTrapRecord->Link);
+
+ DEBUG ((EFI_D_INFO, "RegisterContext->Address:%x! \n", RegisterContext->Address));
+ DEBUG ((EFI_D_INFO, "RegisterContext->Length:%x! \n", RegisterContext->Length));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ )
+{
+ EFI_STATUS Status;
+ IO_TRAP_RECORD *RecordToDelete;
+ UINT32 IoTrapRegLowDword;
+ UINT32 IoTrapRegHighDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+ UINT8 LengthIndex;
+
+ if (*DispatchHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RecordToDelete = IO_TRAP_RECORD_FROM_LINK (*DispatchHandle);
+
+ //
+ // Take the entry out of the linked list
+ //
+ if (RecordToDelete->Link.ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Loop through the first IO Trap handler, looking for the suitable handler
+ //
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // Get information from Io Trap handler register
+ //
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ //
+ // Check next Io Trap handler if the IO Trap handler is not used
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD) == 0) {
+ continue;
+ }
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // Check if it's the maximum address of the Io Trap handler
+ //
+ if (BaseAddress + UsedLength == RecordToDelete->Context.Address + RecordToDelete->Context.Length) {
+
+ if (BaseAddress == RecordToDelete->Context.Address) {
+ //
+ // Disable the IO Trap handler if it's the only child of the Trap handler
+ //
+ mIchnHandle = mIoTrapData.IchnIoTrapHandle[TrapHandlerNum];
+ mIchnContext.Type = IchnIoTrap0 + TrapHandlerNum;
+ Status = mIchnDispatch->UnRegister (
+ mIchnDispatch,
+ mIchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Clear the Io Trap handler register
+ //
+ IoTrapRegLowDword = 0;
+ IoTrapRegHighDword = 0;
+ MmioWrite32 (
+ mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4,
+ (UINT32) (IoTrapRegHighDword)
+ );
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8 + 4),
+ 1,
+ &IoTrapRegHighDword
+ );
+
+ } else {
+ //
+ // Calculate the new IO Trap handler Length
+ //
+ UsedLength = UsedLength - RecordToDelete->Context.Length;
+ //
+ // Check the alignment is dword * power of 2 or not
+ //
+ for (LengthIndex = 0; LengthIndex < sizeof (mLengthTable) / sizeof (UINT16); LengthIndex++) {
+ if (UsedLength == mLengthTable[LengthIndex]) {
+ break;
+ }
+ }
+ //
+ // Do not decrease the length if the alignment is not dword * power of 2
+ //
+ if (LengthIndex >= sizeof (mLengthTable) / sizeof (UINT16)) {
+ break;
+ }
+ //
+ // Decrease the length to prevent the IO trap SMI
+ //
+ IoTrapRegLowDword = (UINT32) ((((UsedLength - 1) &~(BIT1 + BIT0)) << 16) | BaseAddress | B_PCH_RCRB_IO_TRAP_TRSE);
+ }
+
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINT64) (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8),
+ 1,
+ &IoTrapRegLowDword
+ );
+ break;
+ }
+ }
+
+ RemoveEntryList (&RecordToDelete->Link);
+ Status = mSmst->SmmFreePool (RecordToDelete);
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This I/O Trap SMI handler invokes the ACPI reference code to handle the SMI.
+ It currently assumes it owns all of the IO trap SMI.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+IoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ IO_TRAP_RECORD *RecordInDb;
+ LIST_ENTRY *LinkInDb;
+ EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT CurrentIoTrapData;
+ UINT16 BaseAddress;
+ UINT16 StartAddress;
+ UINT16 EndAddress;
+
+ if (!IsListEmpty (&mIoTrapData.CallbackDataBase)) {
+ BaseAddress = MmioRead16 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_TIOA;
+ StartAddress = (UINT16) ((MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_AHBE) >> 16);
+ //
+ // StartAddress and EndAddress will be equal if it's byte access
+ //
+ EndAddress = (UINT16) (HighBitSet32 ((UINT32) (StartAddress))) + BaseAddress;
+ StartAddress = (UINT16) (LowBitSet32 ((UINT32) (StartAddress))) + BaseAddress;
+
+ CurrentIoTrapData.Type = (BOOLEAN) ((MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRCR) & B_PCH_RCRB_TRCR_RWI) != 0);
+ CurrentIoTrapData.WriteData = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_TRWDR);
+
+ LinkInDb = GetFirstNode (&mIoTrapData.CallbackDataBase);
+
+ while (!IsNull (&mIoTrapData.CallbackDataBase, LinkInDb)) {
+ RecordInDb = IO_TRAP_RECORD_FROM_LINK (LinkInDb);
+ if ((RecordInDb->Context.Address <= StartAddress) &&
+ (RecordInDb->Context.Address + RecordInDb->Context.Length > EndAddress)) {
+ if (RecordInDb->Context.Type == ReadWriteTrap || RecordInDb->Context.Type == CurrentIoTrapData.Type) {
+ //
+ // Pass the IO trap context information
+ //
+ CurrentIoTrapData.Address = StartAddress;
+ CurrentIoTrapData.Context = RecordInDb->Context.Context;
+ RecordInDb->Callback (&RecordInDb->Link, &CurrentIoTrapData);
+ break;
+ }
+ } else {
+ LinkInDb = GetNextNode (&mIoTrapData.CallbackDataBase, &RecordInDb->Link);
+ if (IsNull (&mIoTrapData.CallbackDataBase, LinkInDb)) {
+ //
+ // An IO access was trapped that does not have a handler registered.
+ // Since this is an invalid state, we will loop here.
+ // It may be appropriate to remove this loop in production systems to avoid potential user issues.
+ // But, this indicates an error condition.
+ //
+ DEBUG_CODE (
+ EFI_DEADLOOP ();
+ );
+ }
+ }
+ }
+ }
+}
+
+/**
+ Pause IoTrap callback function.
+
+ This function disables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+IoTrapControlPause (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL *This,
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ IO_TRAP_RECORD *IoTrapRecord;
+ UINT32 IoTrapRegLowDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+
+ if (DispatchHandle == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+ if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+ (IoTrapRecord->Context.MergeDisable != TRUE) ||
+ (IoTrapRecord->Context.Address == 0) ||
+ (IoTrapRecord->Context.Length == 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // This IoTrap register should be merge disabled.
+ //
+ if (mIoTrapData.MergeDisable[TrapHandlerNum] != TRUE) {
+ continue;
+ }
+
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // The address and length of record matches the IoTrap register's.
+ //
+ if ((BaseAddress == IoTrapRecord->Context.Address) &&
+ (UsedLength == IoTrapRecord->Context.Length )) {
+ //
+ // Check if status matched.
+ // If this is already Paused, return warning status.
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_TRSE) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Clear IoTrap register SMI enable bit
+ //
+ IoTrapRegLowDword &= (~B_PCH_RCRB_IO_TRAP_TRSE);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Resume IoTrap callback function.
+
+ This function enables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+IoTrapControlResume (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL *This,
+ IN EFI_HANDLE DispatchHandle
+ )
+{
+ IO_TRAP_RECORD *IoTrapRecord;
+ UINT32 IoTrapRegLowDword;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 UsedLength;
+ UINT8 TrapHandlerNum;
+
+ if (DispatchHandle == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IoTrapRecord = IO_TRAP_RECORD_FROM_LINK (DispatchHandle);
+
+ if ((IoTrapRecord->Signature != IO_TRAP_RECORD_SIGNATURE) ||
+ (IoTrapRecord->Context.MergeDisable != TRUE) ||
+ (IoTrapRecord->Context.Address == 0) ||
+ (IoTrapRecord->Context.Length == 0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (TrapHandlerNum = 0; TrapHandlerNum < IO_TRAP_HANDLER_NUM; TrapHandlerNum++) {
+ //
+ // This IoTrap register should be merge disabled.
+ //
+ if (mIoTrapData.MergeDisable[TrapHandlerNum] != TRUE) {
+ continue;
+ }
+
+ IoTrapRegLowDword = MmioRead32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8);
+
+ UsedLength = ((IoTrapRegLowDword >> 16) & 0xFC) + 4;
+ BaseAddress = IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_IOAD;
+
+ //
+ // The address and length of record matches the IoTrap register's.
+ //
+ if ((BaseAddress == IoTrapRecord->Context.Address) &&
+ (UsedLength == IoTrapRecord->Context.Length )) {
+ //
+ // Check if status matched.
+ // If this is already Resume, return warning status.
+ //
+ if ((IoTrapRegLowDword & B_PCH_RCRB_IO_TRAP_TRSE) != 0) {
+ return EFI_ACCESS_DENIED;
+ }
+ //
+ // Set IoTrap register SMI enable bit
+ //
+ IoTrapRegLowDword |= (B_PCH_RCRB_IO_TRAP_TRSE);
+ MmioWrite32 (mPchRootComplexBar + R_PCH_RCRB_IO_TRAP_0 + TrapHandlerNum * 8, (UINT32) (IoTrapRegLowDword));
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ IO Trap SMM driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Initialize the EFI SMM driver library
+ //
+ mDriverImageHandle = ImageHandle;
+
+ //
+ // Find the SMM base protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize global variables.
+ //
+ mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+
+ //
+ // Add other initialization code
+ //
+ //
+ // PCH RCBA must be initialized prior to run this driver.
+ //
+ mPchRootComplexBar = PCH_RCRB_BASE;
+ ASSERT (mPchRootComplexBar != 0);
+
+ //
+ // Locate the ICHn Dispatch protocol
+ //
+ Status = gBS->LocateProtocol (&gEfiSmmIchnDispatchProtocolGuid, NULL, (VOID **) &mIchnDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Locate the S3 resume scripting protocol
+ //
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+
+ //
+ // Initialize the IO trap protocol we produce
+ //
+ mIoTrapData.Signature = IO_TRAP_INSTANCE_SIGNATURE;
+ mIoTrapData.EfiSmmIoTrapDispatchProtocol.Register = IoTrapRegister;
+ mIoTrapData.EfiSmmIoTrapDispatchProtocol.UnRegister = IoTrapUnRegister;
+
+ //
+ // Initialize the Io trap control protocol.
+ //
+ mIoTrapData.PchSmmIoTrapControlProtocol.Pause = IoTrapControlPause;
+ mIoTrapData.PchSmmIoTrapControlProtocol.Resume = IoTrapControlResume;
+
+ //
+ // Install protocol interface
+ //
+ mIoTrapData.Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mIoTrapData.Handle,
+ &gEfiSmmIoTrapDispatchProtocolGuid,
+ &mIoTrapData.EfiSmmIoTrapDispatchProtocol,
+ &gPchSmmIoTrapControlGuid,
+ &mIoTrapData.PchSmmIoTrapControlProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize IO TRAP Callback DataBase
+ //
+ InitializeListHead (&mIoTrapData.CallbackDataBase);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif
new file mode 100644
index 0000000..c76e3da
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "IoTrap"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\IoTrap\Smm"
+ RefName = "IoTrap"
+[files]
+"IoTrap.sdl"
+"IoTrap.mak"
+"IoTrap.c"
+"IoTrap.h"
+"IoTrapDepex.dxs"
+"IoTrap.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h
new file mode 100644
index 0000000..d449fea
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.h
@@ -0,0 +1,221 @@
+/** @file
+ Defines and prototypes for the IoTrap SMM driver
+
+@copyright
+ Copyright (c) 2006 - 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 _IO_TRAP_H_
+#define _IO_TRAP_H_
+
+//
+// Include files
+//
+//
+// 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
+//
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (LoadedImage)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIchnDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (BootScriptSave)
+
+//
+// Driver Produced Protocol
+//
+#include EFI_PROTOCOL_PRODUCER (SmmIoTrapDispatch)
+#include EFI_PROTOCOL_PRODUCER (PchSmmIoTrapControl)
+#include "PchAccess.h"
+#endif
+
+#define IO_TRAP_HANDLER_NUM 4
+
+//
+// Driver private data
+//
+#define IO_TRAP_INSTANCE_SIGNATURE EFI_SIGNATURE_32 ('I', 'O', 'T', 'P')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL EfiSmmIoTrapDispatchProtocol;
+ EFI_HANDLE IchnIoTrapHandle[IO_TRAP_HANDLER_NUM];
+ LIST_ENTRY CallbackDataBase;
+ UINT32 TrapUsedLength[IO_TRAP_HANDLER_NUM];
+ BOOLEAN MergeDisable[IO_TRAP_HANDLER_NUM]; ///< Determine if IoTrap can be merged with other IoTrap
+ PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PchSmmIoTrapControlProtocol; ///< Protocol for runtime control the IoTrap state
+} IO_TRAP_INSTANCE;
+
+#define IO_TRAP_INSTANCE_FROM_THIS(a) CR (a, IO_TRAP_INSTANCE, EfiSmmIoTrapDispatchProtocol, IO_TRAP_INSTANCE_SIGNATURE)
+
+///
+/// "IOTRAP" RECORD
+/// Linked list data structures
+///
+#define IO_TRAP_RECORD_SIGNATURE EFI_SIGNATURE_32 ('I', 'T', 'R', 'C')
+
+typedef struct _IO_TRAP_RECORD {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT Context;
+ EFI_SMM_IO_TRAP_DISPATCH_CALLBACK Callback;
+} IO_TRAP_RECORD;
+
+#define IO_TRAP_RECORD_FROM_LINK(_record) CR (_record, IO_TRAP_RECORD, Link, IO_TRAP_RECORD_SIGNATURE)
+
+//
+// Prototypes
+//
+/**
+ IO Trap SMM driver entry point function.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS Driver initialization completed successfully
+**/
+EFI_STATUS
+EFIAPI
+InstallIoTrap (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Register a new IO Trap SMI dispatch function with a parent SMM driver.
+ The caller will provide information about the IO trap characteristics via
+ the context. This includes base address, length, read vs. r/w, etc.
+ This function will autoallocate IO base address from a common pool if the base address is 0,
+ and the RegisterContext Address field will be updated.
+ The service will not perform GCD allocation if the base address is non-zero.
+ In this case, the caller is responsible for the existence and allocation of the
+ specific IO range.
+ This function looks for the suitable handler and Register a new IchnIoTrap handler
+ if the IO Trap handler is not used. It also enable the IO Trap Range to generate
+ SMI.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for
+ this SMI source.
+ @param[in, out] RegisterContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling
+ the register function to indicate to the register
+ function the IO trap SMI source for which the dispatch
+ function should be invoked. This may not be NULL.
+ @param[out] DispatchHandle Handle of dispatch function, for when interfacing
+ with the parent SMM driver, will be the address of linked
+ list link in the call back record. This may not be NULL.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+ @retval EFI_DEVICE_ERROR The driver was unable to enable the SMI source.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available
+ @retval EFI_INVALID_PARAMETER Address requested is already in use.
+**/
+static
+EFI_STATUS
+EFIAPI
+IoTrapRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK DispatchFunction,
+ IN OUT EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT *RegisterContext,
+ OUT EFI_HANDLE *DispatchHandle
+ );
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+EFIAPI
+IoTrapUnRegister (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ );
+
+/**
+ This I/O Trap SMI handler invokes the ACPI reference code to handle the SMI.
+ It currently assumes it owns all of the IO trap SMI.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+IoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ );
+
+/**
+ Pause IoTrap callback function.
+
+ This function disables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady PAUSED.
+**/
+EFI_STATUS
+IoTrapControlPause (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+/**
+ Resume IoTrap callback function.
+
+ This function enables the SMI enable of IoTrap according to the DispatchHandle,
+ which is returned by IoTrap callback registration. It only supports the DispatchHandle
+ with MergeDisable TRUE and address not zero.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady RESUMED.
+**/
+EFI_STATUS
+IoTrapControlResume (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf
new file mode 100644
index 0000000..7da9522
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.inf
@@ -0,0 +1,92 @@
+## @file
+# Component description file for the IoTrap BS_DRIVER
+#
+#@copyright
+# Copyright (c) 2006 - 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 = IoTrap
+FILE_GUID = 2374EDDF-F203-4fc0-A20E-61BAD73089D6
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ IoTrap.c
+ IoTrap.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[libraries.common]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ EfiScriptLib
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/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
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = IoTrapDepex.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallIoTrap
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak
new file mode 100644
index 0000000..950c31e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.mak
@@ -0,0 +1,118 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IoTrap/IoTrap.mak 4 12/18/12 5:19a Scottyang $
+#
+# $Revision: 4 $
+#
+# $Date: 12/18/12 5:19a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IoTrap/IoTrap.mak $
+#
+# 4 12/18/12 5:19a 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 9/26/12 2:27a Victortu
+#
+# 2 2/24/12 2:10a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:44a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# Create IoTrap Driver
+#---------------------------------------------------------------------------
+EDK : IoTrap
+IoTrap : $(BUILD_DIR)\IoTrap.mak IoTrapBin
+
+$(BUILD_DIR)\IoTrap.mak : $(IoTrap_DIR)\$(@B).cif $(IoTrap_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IoTrap_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IoTrap_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(EDK_SOURCE)\Foundation\Efi\Include\
+
+IoTrap_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallIoTrap"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+
+
+IoTrap_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueBasePciExpressLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EFISCRIPTLIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+IoTrapBin: $(IoTrap_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\IoTrap.mak all \
+ "MY_INCLUDES=$(IoTrap_INCLUDES)" \
+ "MY_DEFINES=$(IoTrap_DEFINES)" \
+ GUID=2374EDDF-F203-4fc0-A20E-61BAD73089D6\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(IoTrap_DIR)\IoTrapDepex.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/IoTrap/Smm/IoTrap.sdl b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.sdl
new file mode 100644
index 0000000..9eee5f4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrap.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/IoTrap/IoTrap.sdl 1 2/08/12 8:44a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:44a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IoTrap/IoTrap.sdl $
+#
+# 1 2/08/12 8:44a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IoTrap_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IoTrap support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "IoTrap_DIR"
+End
+
+MODULE
+ File = "IoTrap.mak"
+ Help = "Includes IoTrap to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IoTrap.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/IoTrap/Smm/IoTrapDepex.dxs b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs
new file mode 100644
index 0000000..0c0b283
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/IoTrap/Smm/IoTrapDepex.dxs
@@ -0,0 +1,43 @@
+/** @file
+ Dispatch dependency expression file for the IoTrap driver.
+
+@copyright
+ Copyright (c) 2006 - 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 (SmmIchnDispatch)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
diff --git a/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif
new file mode 100644
index 0000000..b6fd327
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "IntelLegacyInterrupt"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\LegacyInterrupt\Dxe"
+ RefName = "IntelLegacyInterrupt"
+[files]
+"IntelLegacyInterrupt.sdl"
+"IntelLegacyInterrupt.mak"
+"LegacyInterrupt.c"
+"LegacyInterrupt.h"
+"LegacyInterrupt.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak
new file mode 100644
index 0000000..c304a3b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.mak
@@ -0,0 +1,91 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IntelLegacyInterrupt/IntelLegacyInterrupt.mak 2 2/24/12 2:11a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:11a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelLegacyInterrupt/IntelLegacyInterrupt.mak $
+#
+# 2 2/24/12 2:11a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:45a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create IntelLegacyInterrupt Driver
+#---------------------------------------------------------------------------
+EDK : IntelLegacyInterrupt
+IntelLegacyInterrupt : $(BUILD_DIR)\IntelLegacyInterrupt.mak IntelLegacyInterruptBin
+
+
+$(BUILD_DIR)\IntelLegacyInterrupt.mak : $(IntelLegacyInterrupt_DIR)\$(@B).cif $(IntelLegacyInterrupt_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IntelLegacyInterrupt_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IntelLegacyInterrupt_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+IntelLegacyInterrupt_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=LegacyInterruptInstall"\
+ /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__ \
+
+IntelLegacyInterrupt_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+IntelLegacyInterruptBin: $(IntelLegacyInterrupt_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\IntelLegacyInterrupt.mak all \
+ "MY_INCLUDES=$(IntelLegacyInterrupt_INCLUDES)"\
+ "MY_DEFINES=$(IntelLegacyInterrupt_DEFINES)"\
+ GUID=C1C418F9-591D-461c-82A2-B9CD96DFEA86\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ 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/LegacyInterrupt/Dxe/IntelLegacyInterrupt.sdl b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.sdl
new file mode 100644
index 0000000..194a4cc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/IntelLegacyInterrupt.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/IntelLegacyInterrupt/IntelLegacyInterrupt.sdl 1 2/08/12 8:45a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:45a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelLegacyInterrupt/IntelLegacyInterrupt.sdl $
+#
+# 1 2/08/12 8:45a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IntelLegacyInterrupt_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable IntelLegacyInterrupt support in Project"
+End
+
+PATH
+ Name = "IntelLegacyInterrupt_DIR"
+ Help = "IntelLegacyInterrupt file source directory"
+End
+
+MODULE
+ File = "IntelLegacyInterrupt.mak"
+ Help = "Includes IntelLegacyInterrupt.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IntelLegacyInterrupt.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/LegacyInterrupt/Dxe/LegacyInterrupt.c b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.c
new file mode 100644
index 0000000..213f91b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.c
@@ -0,0 +1,204 @@
+/** @file
+ This code supports a the private implementation
+ of the Legacy Interrupt protocol
+
+@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 "LegacyInterrupt.h"
+
+///
+/// Handle for the Legacy Interrupt Protocol instance produced by this driver
+///
+EFI_HANDLE mLegacyInterruptHandle = NULL;
+
+///
+/// The Legacy Interrupt Protocol instance produced by this driver
+///
+EFI_LEGACY_INTERRUPT_PROTOCOL mLegacyInterrupt = {
+ GetNumberPirqs,
+ GetLocation,
+ ReadPirq,
+ WritePirq
+};
+
+///
+/// Module Global:
+/// Since this driver will only ever produce one instance of the Private Data
+/// protocol you are not required to dynamically allocate the PrivateData.
+///
+UINT8 PirqReg[MAX_PIRQ_NUMBER] = { PIRQA, PIRQB, PIRQC, PIRQD, PIRQE, PIRQF, PIRQG, PIRQH };
+
+/**
+ Return the number of PIRQs supported by this chipset.
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[out] NumberPirqs The pointer which point to the max IRQ number supported by this PCH.
+
+ @retval EFI_SUCCESS Legacy BIOS protocol installed
+**/
+EFI_STATUS
+EFIAPI
+GetNumberPirqs (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *NumberPirqs
+ )
+{
+ *NumberPirqs = MAX_PIRQ_NUMBER;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return PCI location of this device. $PIR table requires this info.
+
+ @param[in] This Protocol instance pointer.
+ @param[out] Bus PCI Bus
+ @param[out] Device PCI Device
+ @param[out] Function PCI Function
+
+ @retval EFI_SUCCESS Bus/Device/Function returned
+**/
+EFI_STATUS
+EFIAPI
+GetLocation (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *Bus,
+ OUT UINT8 *Device,
+ OUT UINT8 *Function
+ )
+{
+ *Bus = DEFAULT_PCI_BUS_NUMBER_PCH;
+ *Device = PCI_DEVICE_NUMBER_PCH_LPC;
+ *Function = PCI_FUNCTION_NUMBER_PCH_LPC;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Builds the PCIE configuration address for the register specified by PirqNumber
+
+ @param[in] PirqNumber The PIRQ number to build the PCIE configuration address for
+
+ @retval UINTN The PCIE Configuration address for interrupt controller in PCH
+**/
+UINTN
+GetAddress (
+ UINT8 PirqNumber
+ )
+{
+ return MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ PirqReg[PirqNumber]
+ );
+}
+
+/**
+ Read the given PIRQ register
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[out] PirqData Value read
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+**/
+EFI_STATUS
+EFIAPI
+ReadPirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ OUT UINT8 *PirqData
+ )
+{
+ if (PirqNumber >= MAX_PIRQ_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PirqData = MmioRead8 (GetAddress (PirqNumber));
+ *PirqData = (UINT8) (*PirqData & 0x7f);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Read the given PIRQ register
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[in] PirqData Value read
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+**/
+EFI_STATUS
+EFIAPI
+WritePirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ IN UINT8 PirqData
+ )
+{
+ if (PirqNumber >= MAX_PIRQ_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MmioWrite8 (GetAddress (PirqNumber), PirqData);
+ return EFI_SUCCESS;
+}
+
+/**
+ Install Driver to produce Legacy Interrupt protocol.
+
+ @param[in] ImageHandle Handle for this drivers loaded image protocol.
+ @param[in] SystemTable EFI system table.
+
+ @retval EFI_SUCCESS Legacy Interrupt protocol installed
+ @retval Other No protocol installed, unload driver.
+**/
+EFI_STATUS
+LegacyInterruptInstall (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "LegacyInterruptInstall() Start\n"));
+
+ ///
+ /// Make sure the Legacy Interrupt Protocol is not already installed in the system
+ ///
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiLegacyInterruptProtocolGuid);
+
+ ///
+ /// Make a new handle and install the protocol
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mLegacyInterruptHandle,
+ &gEfiLegacyInterruptProtocolGuid,
+ &mLegacyInterrupt,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "LegacyInterruptInstall() End\n"));
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.h b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.h
new file mode 100644
index 0000000..0c9440f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.h
@@ -0,0 +1,119 @@
+/** @file
+ This code supports a the private implementation
+ of the Legacy Interrupt protocol
+
+@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
+**/
+#ifndef LEGACY_INTERRUPT_H_
+#define LEGACY_INTERRUPT_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 EFI_PROTOCOL_PRODUCER (LegacyInterrupt)
+#include "PchAccess.h"
+#endif
+
+#define PIRQN 0x00 ///< PIRQ Null
+#define PIRQA 0x60
+#define PIRQB 0x61
+#define PIRQC 0x62
+#define PIRQD 0x63
+#define PIRQE 0x68
+#define PIRQF 0x69
+#define PIRQG 0x6A
+#define PIRQH 0x6B
+
+#define MAX_PIRQ_NUMBER 8
+
+/**
+ Return the number of PIRQs supported by this chipset.
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[out] NumberPirqs The pointer which point to the max IRQ number supported by this PCH.
+
+ @retval EFI_SUCCESS Legacy BIOS protocol installed
+**/
+EFI_STATUS
+EFIAPI
+GetNumberPirqs (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *NumberPirqs
+ );
+
+/**
+ Return PCI location of this device. $PIR table requires this info.
+
+ @param[in] This Protocol instance pointer.
+ @param[out] Bus PCI Bus
+ @param[out] Device PCI Device
+ @param[out] Function PCI Function
+
+ @retval EFI_SUCCESS Bus/Device/Function returned
+**/
+EFI_STATUS
+EFIAPI
+GetLocation (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ OUT UINT8 *Bus,
+ OUT UINT8 *Device,
+ OUT UINT8 *Function
+ );
+
+/**
+ Read the given PIRQ register
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[out] PirqData Value read
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+**/
+EFI_STATUS
+EFIAPI
+ReadPirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ OUT UINT8 *PirqData
+ );
+
+/**
+ Read the given PIRQ register
+
+ @param[in] This Pointer to LegacyInterrupt Protocol
+ @param[in] PirqNumber The Pirq register 0 = A, 1 = B etc
+ @param[in] PirqData Value read
+
+ @retval EFI_SUCCESS Decoding change affected.
+ @retval EFI_INVALID_PARAMETER Invalid PIRQ number
+**/
+EFI_STATUS
+EFIAPI
+WritePirq (
+ IN EFI_LEGACY_INTERRUPT_PROTOCOL *This,
+ IN UINT8 PirqNumber,
+ IN UINT8 PirqData
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.inf b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.inf
new file mode 100644
index 0000000..29c9cbc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LegacyInterrupt/Dxe/LegacyInterrupt.inf
@@ -0,0 +1,73 @@
+## @file
+# Component description file for LegacyBios module.
+#
+#@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 = LegacyInterrupt
+FILE_GUID = C1C418F9-591D-461c-82A2-B9CD96DFEA86
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ LegacyInterrupt.c
+ LegacyInterrupt.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ EdkIIGlueBasePciLibPciExpress
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=LegacyInterruptInstall
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c
new file mode 100644
index 0000000..b9aab0a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.c
@@ -0,0 +1,2148 @@
+/** @file
+ PCI Library using PC Express access.
+
+@copyright
+ Copyright (c) 2005 - 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 "DxeRuntimePciLibPciExpress.h"
+
+/**
+ Assert the validity of a PCI address. A valid PCI address should contain 1's
+ only in the low 28 bits.
+
+ @param A The address to validate.
+**/
+#define ASSERT_INVALID_PCI_ADDRESS(A) ASSERT (((A) &~0xfffffff) == 0)
+
+/**
+ PCI Express base address
+**/
+STATIC UINTN mPciExpressBaseAddress;
+
+/**
+ Registered memory scope.
+**/
+typedef struct _REGISTERED_ADDRESS_MAP {
+ UINTN PciAddress;
+ UINTN Length;
+ UINTN RuntimeAddress;
+} REGISTERED_ADDRESS_MAP;
+
+#define PCI_LIB_ADDRESS_MAP_MAX_ITEM 64
+
+STATIC REGISTERED_ADDRESS_MAP mPciLibAddressMap[PCI_LIB_ADDRESS_MAP_MAX_ITEM];
+
+STATIC UINTN mPciLibAddressMapIndex = 0;
+
+/**
+ Virtual address notify event
+**/
+STATIC EFI_EVENT mVirtualNofityEvent;
+
+/**
+ Get the base address of PCI Express memory space.
+
+ @param[in] None
+
+ @retval VOID Return The base address of PCI Express.
+**/
+VOID *
+EFIAPI
+GetPciExpressBaseAddress (
+ VOID
+ )
+{
+ return (VOID *) (mPciExpressBaseAddress);
+}
+
+/**
+ Generate Pci Express address.
+ If Address > 0x0FFFFFFF or can't get the match Pci address, then ASSERT().
+
+ @param[in] Address Pci address.
+
+ @retval UINTN Pci Express address.
+**/
+static
+UINTN
+EFIAPI
+PreparePciExpressAddress (
+ IN UINTN Address
+ )
+{
+ UINTN Index;
+
+ ASSERT_INVALID_PCI_ADDRESS (Address);
+
+ if (EfiAtRuntime () == FALSE) {
+ return mPciExpressBaseAddress + Address;
+ }
+
+ for (Index = 0; Index < PCI_LIB_ADDRESS_MAP_MAX_ITEM; Index++) {
+ if ((Address >= mPciLibAddressMap[Index].PciAddress) &&
+ (Address < mPciLibAddressMap[Index].PciAddress + mPciLibAddressMap[Index].Length)
+ ) {
+ return mPciLibAddressMap[Index].RuntimeAddress + (Address - mPciLibAddressMap[Index].PciAddress);
+ }
+ }
+
+ ASSERT (FALSE);
+ EFI_DEADLOOP ();
+ return 0;
+}
+
+/**
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT8 return The read value from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressRead8 (
+ IN UINTN Address
+ )
+{
+ return MmioRead8 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write
+
+ @retval UINT8 The value to write to the MMIO register.
+**/
+UINT8
+EFIAPI
+PciExpressWrite8 (
+ IN UINTN Address,
+ IN UINT8 Value
+ )
+{
+ return MmioWrite8 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return MmioOr8 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return MmioAnd8 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return MmioAndThenOr8 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+
+ @retval UINT8 The value of the bit field read from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return MmioBitFieldWrite8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return MmioBitFieldOr8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return MmioBitFieldAnd8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciExpressBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return MmioBitFieldAndThenOr8 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT16 The read value from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressRead16 (
+ IN UINTN Address
+ )
+{
+ return MmioRead16 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write.
+
+ @retval UINT16 The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressWrite16 (
+ IN UINTN Address,
+ IN UINT16 Value
+ )
+{
+ return MmioWrite16 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return MmioOr16 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return MmioAnd16 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return MmioAndThenOr16 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+
+ @retval UINT16 The value of the bit field read from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return MmioBitFieldWrite16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return MmioBitFieldOr16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return MmioBitFieldAnd16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 16-bit boundary, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciExpressBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return MmioBitFieldAndThenOr16 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT32 The read value from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressRead32 (
+ IN UINTN Address
+ )
+{
+ return MmioRead32 (PreparePciExpressAddress (Address));
+}
+
+/**
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Value The value to write.
+
+ @retval UINT32 The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressWrite32 (
+ IN UINTN Address,
+ IN UINT32 Value
+ )
+{
+ return MmioWrite32 (PreparePciExpressAddress (Address), Value);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return MmioOr32 (PreparePciExpressAddress (Address), OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return MmioAnd32 (PreparePciExpressAddress (Address), AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return MmioAndThenOr32 (
+ PreparePciExpressAddress (Address),
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+
+ @retval UNT32 The value of the bit field read from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return MmioBitFieldRead32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit
+ );
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return MmioBitFieldWrite32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ Value
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return MmioBitFieldOr32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ OrData
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return MmioBitFieldAnd32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData
+ );
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If Address is not aligned on a 32-bit boundary, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciExpressBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return MmioBitFieldAndThenOr32 (
+ PreparePciExpressAddress (Address),
+ StartBit,
+ EndBit,
+ AndData,
+ OrData
+ );
+}
+
+/**
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer receiving the data read.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciExpressReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+ if (Size == 0) {
+ return Size;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & 1) != 0) {
+ //
+ // Read a byte if StartAddress is byte aligned
+ //
+ *(volatile UINT8 *) Buffer = PciExpressRead8 (StartAddress);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
+ //
+ // Read a word if StartAddress is word aligned
+ //
+ *(volatile UINT16 *) Buffer = PciExpressRead16 (StartAddress);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Read as many double words as possible
+ //
+ *(volatile UINT32 *) Buffer = PciExpressRead32 (StartAddress);
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Read the last remaining word if exist
+ //
+ *(volatile UINT16 *) Buffer = PciExpressRead16 (StartAddress);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Read the last remaining byte if exist
+ //
+ *(volatile UINT8 *) Buffer = PciExpressRead8 (StartAddress);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer containing the data to write.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciExpressWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ UINTN ReturnValue;
+
+ ASSERT (((StartAddress & 0xFFF) + Size) <= 0x1000);
+
+ if (Size == 0) {
+ return 0;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ //
+ // Save Size for return
+ //
+ ReturnValue = Size;
+
+ if ((StartAddress & 1) != 0) {
+ //
+ // Write a byte if StartAddress is byte aligned
+ //
+ PciExpressWrite8 (StartAddress, *(UINT8 *) Buffer);
+ StartAddress += sizeof (UINT8);
+ Size -= sizeof (UINT8);
+ Buffer = (UINT8 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16) && (StartAddress & 2) != 0) {
+ //
+ // Write a word if StartAddress is word aligned
+ //
+ PciExpressWrite16 (StartAddress, *(UINT16 *) Buffer);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ while (Size >= sizeof (UINT32)) {
+ //
+ // Write as many double words as possible
+ //
+ PciExpressWrite32 (StartAddress, *(UINT32 *) Buffer);
+ StartAddress += sizeof (UINT32);
+ Size -= sizeof (UINT32);
+ Buffer = (UINT32 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT16)) {
+ //
+ // Write the last remaining word if exist
+ //
+ PciExpressWrite16 (StartAddress, *(UINT16 *) Buffer);
+ StartAddress += sizeof (UINT16);
+ Size -= sizeof (UINT16);
+ Buffer = (UINT16 *) Buffer + 1;
+ }
+
+ if (Size >= sizeof (UINT8)) {
+ //
+ // Write the last remaining byte if exist
+ //
+ PciExpressWrite8 (StartAddress, *(UINT8 *) Buffer);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Reads and returns the 8-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT8 The read value from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciRead8 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead8 (Address);
+}
+
+/**
+ Writes the 8-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT8 The value written to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciWrite8 (
+ IN UINTN Address,
+ IN UINT8 Data
+ )
+{
+ return PciExpressWrite8 (Address, Data);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciOr8 (
+ IN UINTN Address,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressOr8 (Address, OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciAnd8 (
+ IN UINTN Address,
+ IN UINT8 AndData
+ )
+{
+ return PciExpressAnd8 (Address, AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciAndThenOr8 (
+ IN UINTN Address,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressAndThenOr8 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in an 8-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+
+ @retval UINT8 The value of the bit field read from the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldRead8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead8 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 8-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldWrite8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 Value
+ )
+{
+ return PciExpressBitFieldWrite8 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 8-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressBitFieldOr8 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 8-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldAnd8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData
+ )
+{
+ return PciExpressBitFieldAnd8 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 8-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 8-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 7, then ASSERT().
+ If EndBit is greater than 7, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..7.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..7.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT8 The value written back to the PCI configuration register.
+**/
+UINT8
+EFIAPI
+PciBitFieldAndThenOr8 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT8 AndData,
+ IN UINT8 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr8 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads and returns the 16-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT16 The read value from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciRead16 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead16 (Address);
+}
+
+/**
+ Writes the 16-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT16 The value written to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciWrite16 (
+ IN UINTN Address,
+ IN UINT16 Data
+ )
+{
+ return PciExpressWrite16 (Address, Data);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciOr16 (
+ IN UINTN Address,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressOr16 (Address, OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciAnd16 (
+ IN UINTN Address,
+ IN UINT16 AndData
+ )
+{
+ return PciExpressAnd16 (Address, AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciAndThenOr16 (
+ IN UINTN Address,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressAndThenOr16 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in a 16-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+
+ @retval UINT16 The value of the bit field read from the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldRead16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead16 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 16-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldWrite16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 Value
+ )
+{
+ return PciExpressBitFieldWrite16 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 16-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressBitFieldOr16 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 16-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldAnd16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData
+ )
+{
+ return PciExpressBitFieldAnd16 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 16-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 16-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 15, then ASSERT().
+ If EndBit is greater than 15, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..15.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..15.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT16 The value written back to the PCI configuration register.
+**/
+UINT16
+EFIAPI
+PciBitFieldAndThenOr16 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT16 AndData,
+ IN UINT16 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr16 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads and returns the 32-bit PCI configuration register specified by Address.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+
+ @retval UINT32 The read value from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciRead32 (
+ IN UINTN Address
+ )
+{
+ return PciExpressRead32 (Address);
+}
+
+/**
+ Writes the 32-bit PCI configuration register specified by Address with the
+ value specified by Value. Value is returned. This function must guarantee
+ that all PCI read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Data The value to write.
+
+ @retval UINT32 The value written to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciWrite32 (
+ IN UINTN Address,
+ IN UINT32 Data
+ )
+{
+ return PciExpressWrite32 (Address, Data);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciOr32 (
+ IN UINTN Address,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressOr32 (Address, OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciAnd32 (
+ IN UINTN Address,
+ IN UINT32 AndData
+ )
+{
+ return PciExpressAnd32 (Address, AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData,
+ performs a bitwise inclusive OR between the result of the AND operation and
+ the value specified by OrData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized.
+ If Address > 0x0FFFFFFF, then ASSERT().
+
+ @param[in] Address Address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciAndThenOr32 (
+ IN UINTN Address,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressAndThenOr32 (Address, AndData, OrData);
+}
+
+/**
+ Reads the bit field in a 32-bit PCI configuration register. The bit field is
+ specified by the StartBit and the EndBit. The value of the bit field is
+ returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to read.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+
+ @retval UINT32 The value of the bit field read from the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldRead32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit
+ )
+{
+ return PciExpressBitFieldRead32 (Address, StartBit, EndBit);
+}
+
+/**
+ Writes Value to the bit field of the PCI configuration register. The bit
+ field is specified by the StartBit and the EndBit. All other bits in the
+ destination PCI configuration register are preserved. The new value of the
+ 32-bit register is returned.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] Value New value of the bit field.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldWrite32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 Value
+ )
+{
+ return PciExpressBitFieldWrite32 (Address, StartBit, EndBit, Value);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise inclusive OR between the read result and the value specified by
+ OrData, and writes the result to the 32-bit PCI configuration register
+ specified by Address. The value written to the PCI configuration register is
+ returned. This function must guarantee that all PCI read and write operations
+ are serialized. Extra left bits in OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] OrData The value to OR with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressBitFieldOr32 (Address, StartBit, EndBit, OrData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND between the read result and the value specified by AndData, and
+ writes the result to the 32-bit PCI configuration register specified by
+ Address. The value written to the PCI configuration register is returned.
+ This function must guarantee that all PCI read and write operations are
+ serialized. Extra left bits in AndData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldAnd32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData
+ )
+{
+ return PciExpressBitFieldAnd32 (Address, StartBit, EndBit, AndData);
+}
+
+/**
+ Reads the 32-bit PCI configuration register specified by Address, performs a
+ bitwise AND followed by a bitwise inclusive OR between the read result and
+ the value specified by AndData, and writes the result to the 32-bit PCI
+ configuration register specified by Address. The value written to the PCI
+ configuration register is returned. This function must guarantee that all PCI
+ read and write operations are serialized. Extra left bits in both AndData and
+ OrData are stripped.
+ If Address > 0x0FFFFFFF, then ASSERT().
+ If StartBit is greater than 31, then ASSERT().
+ If EndBit is greater than 31, then ASSERT().
+ If EndBit is less than StartBit, then ASSERT().
+
+ @param[in] Address PCI configuration register to write.
+ @param[in] StartBit The original of the least significant bit in the bit field. Range 0..31.
+ @param[in] EndBit The original of the most significant bit in the bit field. Range 0..31.
+ @param[in] AndData The value to AND with the PCI configuration register.
+ @param[in] OrData The value to OR with the result of the AND operation.
+
+ @retval UINT32 The value written back to the PCI configuration register.
+**/
+UINT32
+EFIAPI
+PciBitFieldAndThenOr32 (
+ IN UINTN Address,
+ IN UINTN StartBit,
+ IN UINTN EndBit,
+ IN UINT32 AndData,
+ IN UINT32 OrData
+ )
+{
+ return PciExpressBitFieldAndThenOr32 (Address, StartBit, EndBit, AndData, OrData);
+}
+
+/**
+ Reads the range of PCI configuration registers specified by StartAddress and
+ Size into the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be read. Size is
+ returned. When possible 32-bit PCI configuration read cycles are used to read
+ from StartAdress to StartAddress + Size. Due to alignment restrictions, 8-bit
+ and 16-bit PCI configuration read cycles may be used at the beginning and the
+ end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer receiving the data read.
+
+ @retval UINTN Size in bytes of the transfer.
+**/
+UINTN
+EFIAPI
+PciReadBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ OUT VOID *Buffer
+ )
+{
+ return PciExpressReadBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Writes the range of PCI configuration registers specified by StartAddress and
+ Size from the buffer specified by Buffer. This function only allows the PCI
+ configuration registers from a single PCI function to be written. Size is
+ returned. When possible 32-bit PCI configuration write cycles are used to
+ write from StartAdress to StartAddress + Size. Due to alignment restrictions,
+ 8-bit and 16-bit PCI configuration write cycles may be used at the beginning
+ and the end of the range.
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If ((StartAddress & 0xFFF) + Size) > 0x1000, then ASSERT().
+ If Size > 0 and Buffer is NULL, then ASSERT().
+
+ @param[in] StartAddress Starting address that encodes the PCI Bus, Device, Function and Register.
+ @param[in] Size Size in bytes of the transfer.
+ @param[in] Buffer Pointer to a buffer containing the data to write.
+
+ @retval UINTN The value written back to the PCI configuration register.
+**/
+UINTN
+EFIAPI
+PciWriteBuffer (
+ IN UINTN StartAddress,
+ IN UINTN Size,
+ IN VOID *Buffer
+ )
+{
+ return PciExpressWriteBuffer (StartAddress, Size, Buffer);
+}
+
+/**
+ Register memory space
+ If StartAddress > 0x0FFFFFFF, then ASSERT().
+ If SmPciLibAddressMapIndex) > PCI_LIB_ADDRESS_MAP_MAX_ITEM, then ASSERT().
+
+ @param[in] Address Starting address of the memory space
+ @param[in] Length Length of the memory space
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibRegisterMemory (
+ IN UINTN Address,
+ IN UINTN Length
+ )
+{
+ UINTN Index;
+
+ ASSERT_INVALID_PCI_ADDRESS (Address);
+ ASSERT (mPciLibAddressMapIndex < PCI_LIB_ADDRESS_MAP_MAX_ITEM);
+
+ //
+ // If already registered
+ //
+ for (Index = 0; Index < mPciLibAddressMapIndex; Index++) {
+ if (mPciLibAddressMap[Index].PciAddress == Address) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ mPciLibAddressMap[mPciLibAddressMapIndex].PciAddress = Address;
+ mPciLibAddressMap[mPciLibAddressMapIndex].Length = Length;
+ mPciLibAddressMap[mPciLibAddressMapIndex].RuntimeAddress = mPciExpressBaseAddress + Address;
+ mPciLibAddressMapIndex++;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Virtual address nofity.
+ The event handler changes PCIE base address to an virtual address.
+ Starting address of registered memory scope is converted as well.
+
+ @param[in] Event The event that be siganlled when virtual address changed
+ @param[in] Context The pointer of the ESAL procedure instance
+
+ @retval None
+**/
+VOID
+EFIAPI
+VirtualAddressNotifyEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < PCI_LIB_ADDRESS_MAP_MAX_ITEM; Index++) {
+ if (mPciLibAddressMap[Index].PciAddress != 0) {
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mPciLibAddressMap[Index].RuntimeAddress));
+ }
+ }
+
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &mPciExpressBaseAddress);
+}
+
+/**
+ Constructor for Pci library. Register VirtualAddressNotifyEvent() notify function
+ It will ASSERT() if that operation fails
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+PciLibConstructor (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ mPciExpressBaseAddress = (UINTN) PcdGet64 (PcdPciExpressBaseAddress);
+
+ Status = gBS->CreateEvent (
+ EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+ EFI_TPL_NOTIFY,
+ VirtualAddressNotifyEvent,
+ NULL,
+ &mVirtualNofityEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ZeroMem (mPciLibAddressMap, sizeof (mPciLibAddressMap));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif
new file mode 100644
index 0000000..179a995
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "DxeRuntimePciLibPciExpress"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\DxeRuntimePciLibPciExpress"
+ RefName = "DxeRuntimePciLibPciExpress"
+[files]
+"DxeRuntimePciLibPciExpress.sdl"
+"DxeRuntimePciLibPciExpress.mak"
+"DxeRuntimePciLibPciExpress.c"
+"DxeRuntimePciLibPciExpress.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf
new file mode 100644
index 0000000..20fec36
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.inf
@@ -0,0 +1,78 @@
+## @file
+# Component description file for the DxeRuntimePciLibPciExpress
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchDxeRuntimePciLibPciExpress
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ DxeRuntimePciLibPciExpress.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+
+[libraries.common]
+ EdkIIGlueEdkDxeRuntimeDriverLib
+
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common]
+ LIB_STD_FLAGS = $(LIB_STD_FLAGS) /IGNORE:4006 /IGNORE:4221
+
+[nmake.ia32]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_IA32
+
+[nmake.x64]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_X64
+
+[nmake.ipf]
+ C_FLAGS = $(C_FLAGS) -DMDE_CPU_IPF
+
+[nmake.ebc]
+ EBC_C_STD_FLAGS = $(EBC_C_STD_FLAGS) -DEDKII_GLUE_LIBRARY_IMPLEMENTATION
+ EBC_LIB_STD_FLAGS = $(EBC_LIB_STD_FLAGS) /IGNORE:4006 /IGNORE:4221
+ EBC_C_STD_FLAGS = $(EBC_C_STD_FLAGS) -DMDE_CPU_EBC
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak
new file mode 100644
index 0000000..2a0bb30
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.mak $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:DxeRuntimePciLibPciExpress
+EDK : DxeRuntimePciLibPciExpress
+
+DxeRuntimePciLibPciExpress : $(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak DxeRuntimePciLibPciExpressBin
+
+$(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak : $(DxeRuntimePciLibPciExpress_DIR)\$(@B).cif $(DxeRuntimePciLibPciExpress_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(DxeRuntimePciLibPciExpress_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(DxeRuntimePciLibPciExpressLib_LIB) : DxeRuntimePciLibPciExpress
+
+DxeRuntimePciLibPciExpress_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+DxeRuntimePciLibPciExpress_DEFINES = \
+$(CFLAGS) \
+$(DxeCpuBuildDefine) \
+
+DxeRuntimePciLibPciExpressBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) \
+ /f $(BUILD_DIR)\DxeRuntimePciLibPciExpress.mak all \
+ "MY_INCLUDES=$(DxeRuntimePciLibPciExpress_INCLUDES)" \
+ "CFLAGS=$(DxeRuntimePciLibPciExpress_DEFINES)"\
+ TYPE=LIBRARY LIBRARIES= \
+ LIBRARY_NAME=$(DxeRuntimePciLibPciExpressLib_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/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl
new file mode 100644
index 0000000..5c09ab6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl
@@ -0,0 +1,72 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/DxeRuntimePciLibPciExpress/DxeRuntimePciLibPciExpress.sdl $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "DxeRuntimePciLibPciExpress_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable DxeRuntimePciLibPciExpress support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "DxeRuntimePciLibPciExpress_DIR"
+End
+
+MODULE
+ File = "DxeRuntimePciLibPciExpress.mak"
+ Help = "Includes DxeRuntimePciLibPciExpress.mak to Project"
+End
+
+ELINK
+ Name = "DxeRuntimePciLibPciExpressLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\DxeRuntimePciLibPciExpress_Lib.lib"
+ Parent = "DxeRuntimePciLibPciExpressLib_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/Library/PchLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif
new file mode 100644
index 0000000..2f066b4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\"
+ RefName = "PchLib"
+[files]
+"PchLib.sdl"
+[parts]
+"DxeRuntimePciLibPciExpress"
+"PchPciExpressHelpersLib"
+"PchPlatformLib"
+"PchSmbusLib"
+"RcFviDxeLib"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl
new file mode 100644
index 0000000..b73418a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchLib.sdl
@@ -0,0 +1,55 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchLib.sdl 1 2/08/12 8:46a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:46a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchLib.sdl $
+#
+# 1 2/08/12 8:46a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchLibrary_SUPPORT"
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchLibrary support in Project"
+End
+
+PATH
+ Name = "PchLibrary_DIR"
+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/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif
new file mode 100644
index 0000000..bffca56
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PchPciExpressHelpersLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPciExpressHelpersLib"
+ RefName = "PchPciExpressHelpersLib"
+[files]
+"PchPciExpressHelpersLib.sdl"
+"PchPciExpressHelpersLib.mak"
+"PchPciExpressHelpersLibrary.c"
+"PchPciExpressHelpersLibrary.h"
+"PchPciExpressHelpersLib.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf
new file mode 100644
index 0000000..aa731f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.inf
@@ -0,0 +1,66 @@
+## @file
+# Component description file for the PchPciExpressHelpersLib
+#
+#@copyright
+# Copyright (c) 2008 - 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 = PchPciExpressHelpersLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ PchPciExpressHelpersLibrary.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ PchPlatformLib
+
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common] \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak
new file mode 100644
index 0000000..e8ce73e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak
@@ -0,0 +1,88 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak 2 10/16/12 4:57a Scottyang $
+#
+# $Revision: 2 $
+#
+# $Date: 10/16/12 4:57a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.mak $
+#
+# 2 10/16/12 4:57a Scottyang
+# [TAG] EIP84720
+# [Category] Improvement
+# [Description] Support Hot-Plug in Shark Bay
+# [Files] PchRootPort.c, PchPcie.asl, PchPciExpressHelpersLib.mak,
+# PchPciExpressHlpersLibrary.c, SB.sdl
+#
+# 1 2/08/12 8:47a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchPciExpressHelpersLib
+
+PchPciExpressHelpersLib : PchPciExpressHelpersDxeLib PchPciExpressHelpersPeiLib
+
+$(PchPciExpressHelpersDxeLib_LIB) : PchPciExpressHelpersDxeLib
+$(PchPciExpressHelpersPeiLib_LIB) : PchPciExpressHelpersPeiLib
+
+PchPciExpressHelpersDxeLib : $(BUILD_DIR)\PchPciExpressHelpersLib.mak PchPciExpressHelpersLibDxeBin
+PchPciExpressHelpersPeiLib : $(BUILD_DIR)\PchPciExpressHelpersLib.mak PchPciExpressHelpersLibPeiBin
+
+$(BUILD_DIR)\PchPciExpressHelpersLib.mak : $(PchPciExpressHelpersLib_DIR)\$(@B).cif $(PchPciExpressHelpersLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchPciExpressHelpersLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchPciExpressHelpersLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchPciExpressHelpersLib_DEFINES=\
+ $(CFLAGS)\
+
+PchPciExpressHelpersLibDxeBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPciExpressHelpersLib.mak all \
+ "MY_INCLUDES=$(PchPciExpressHelpersLib_INCLUDES)" \
+ TYPE=LIBRARY LIBRARIES= \
+ LIBRARY_NAME=$(PchPciExpressHelpersDxeLib_LIB)
+
+PchPciExpressHelpersLibPeiBin:
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+!ENDIF
+ /f $(BUILD_DIR)\PchPciExpressHelpersLib.mak all \
+ "MY_INCLUDES=$(PchPciExpressHelpersLib_INCLUDES)" \
+ "MY_DEFINES=$(PchPciExpressHelpersLib_DEFINES)" \
+ LIBRARIES= \
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(PchPciExpressHelpersPeiLib_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/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl
new file mode 100644
index 0000000..1bb4ebc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl
@@ -0,0 +1,83 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl 1 2/08/12 8:47a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:47a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPciExpressHelpersLib/PchPciExpressHelpersLib.sdl $
+#
+# 1 2/08/12 8:47a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchPciExpressHelpersLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchPciExpressHelpersLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchPciExpressHelpersLib_DIR"
+End
+
+MODULE
+ File = "PchPciExpressHelpersLib.mak"
+ Help = "Includes PchPciExpressHelpersLib.mak to Project"
+End
+
+ELINK
+ Name = "PchPciExpressHelpersDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPciExpressHelpersDxeLib_Lib.lib"
+ Parent = "PchPciExpressHelpersDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPciExpressHelpersPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPciExpressHelpersPeiLib_Lib.lib"
+ Parent = "PchPciExpressHelpersPeiLib_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/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
new file mode 100644
index 0000000..7d622b3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.c
@@ -0,0 +1,2201 @@
+/** @file
+ This file contains routines that support PCI Express initialization
+
+@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 "PchPciExpressHelpersLibrary.h"
+// AMI_OVERRIDE, [EIP84720]>
+#include "Token.h"
+// AMI_OVERRIDE, [EIP84720]<
+
+/**
+ 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] Function 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 Function,
+ IN UINT8 CapId
+ )
+{
+ UINT8 CapHeaderOffset;
+ UINT8 CapHeaderId;
+ UINTN DeviceBase;
+
+ DeviceBase = MmPciAddress (0, Bus, Device, Function, 0);
+
+ ///
+ /// Check the header layout to determine the Offset of Capabilities Pointer Register
+ ///
+ if ((MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE)) {
+ ///
+ /// If CardBus bridge, start at Offset 0x14
+ ///
+ CapHeaderOffset = 0x14;
+ } else {
+ ///
+ /// Otherwise, start at Offset 0x34
+ ///
+ CapHeaderOffset = 0x34;
+ }
+ ///
+ /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+ ///
+ CapHeaderId = 0;
+ CapHeaderOffset = MmioRead8 (DeviceBase + CapHeaderOffset) & ((UINT8) ~(BIT0 | BIT1));
+ while (CapHeaderOffset != 0 && CapHeaderId != 0xFF) {
+ CapHeaderId = MmioRead8 (DeviceBase + CapHeaderOffset);
+ if (CapHeaderId == CapId) {
+ return CapHeaderOffset;
+ }
+ ///
+ /// Each capability must be DWORD aligned.
+ /// The bottom two bits of all pointers (including the initial pointer at 34h) are reserved
+ /// and must be implemented as 00b although software must mask them to allow for future uses of these bits.
+ ///
+ CapHeaderOffset = MmioRead8 (DeviceBase + CapHeaderOffset + 1) & ((UINT8) ~(BIT0 | BIT1));
+ }
+
+ return 0;
+}
+
+/**
+ Search and return the offset of desired Pci Express Capability ID
+ CAPID list:
+ 0x0001 = Advanced Error Rreporting Capability
+ 0x0002 = Virtual Channel Capability
+ 0x0003 = Device Serial Number Capability
+ 0x0004 = Power Budgeting Capability
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] Function Pci Function Number
+ @param[in] CapId Extended CAPID to search for
+
+ @retval 0 CAPID not found
+ @retval Other CAPID found, Offset of desired CAPID
+**/
+UINT16
+PcieFindExtendedCapId (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT16 CapId
+ )
+{
+ UINT16 CapHeaderOffset;
+ UINT16 CapHeaderId;
+ UINTN DeviceBase;
+
+ DeviceBase = MmPciAddress (0, Bus, Device, Function, 0);
+
+ ///
+ /// Start to search at Offset 0x100
+ /// Get Capability Header, A pointer value of 00h is used to indicate the last capability in the list.
+ ///
+ CapHeaderId = 0;
+ CapHeaderOffset = 0x100;
+ while (CapHeaderOffset != 0 && CapHeaderId != 0xFFFF) {
+ CapHeaderId = MmioRead16 (DeviceBase + CapHeaderOffset);
+ if (CapHeaderId == CapId) {
+ return CapHeaderOffset;
+ }
+ ///
+ /// Each capability must be DWORD aligned.
+ /// The bottom two bits of all pointers are reserved and must be implemented as 00b
+ /// although software must mask them to allow for future uses of these bits.
+ ///
+ CapHeaderOffset = (MmioRead16 (DeviceBase + CapHeaderOffset + 2) >> 4) & ((UINT16) ~(BIT0 | BIT1));
+ }
+
+ return 0;
+}
+
+/**
+ Map a TC to VC0 for port and endpoint
+
+ @param[in] Bus1 The bus number of the port
+ @param[in] Device1 The device number of the port
+ @param[in] Function1 The function number of the port
+ @param[in] Bus2 The bus number of the endpoint
+ @param[in] Device2 The device number of the endpoint
+ @param[in] TCx The TC number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMapTcxVc0 (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2,
+ IN UINT8 TCx
+ )
+{
+ UINT16 Offset;
+ UINTN DeviceBase1;
+ UINTN DeviceBase2;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function2;
+
+ DeviceBase1 = MmPciAddress (0, Bus1, Device1, Function1, 0);
+
+ ///
+ /// Set TCx-VC0 value on the port
+ ///
+ Offset = PcieFindExtendedCapId (Bus1, Device1, Function1, 2);
+ if (Offset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MmioAndThenOr8 (DeviceBase1 + Offset + 0x014, (UINT8) (~0xF), 1);
+ MmioWrite8 (DeviceBase1 + Offset + 0x014, (UINT8) (1 << TCx));
+
+ ///
+ /// Set TCx-VC0 value on the Endpoint
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= Device2; DeviceIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase2 + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase2 + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function2 = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function2 = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= Function2; FunctionIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, FunctionIndex, 0);
+
+ Offset = PcieFindExtendedCapId (Bus2, DeviceIndex, FunctionIndex, 2);
+ if (Offset == 0) {
+ continue;
+ }
+
+ MmioAndThenOr8 (DeviceBase2 + Offset + 0x014, (UINT8) (~0xF), 1);
+ MmioWrite8 (DeviceBase2 + Offset + 0x014, (UINT8) (1 << TCx));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set Common clock to Root port and Endpoint PCI device
+
+ @param[in] Bus1 Root port Pci Bus Number
+ @param[in] Device1 Root port Pci Device Number
+ @param[in] Function1 Root port Pci Function Number
+ @param[in] Bus2 Endpoint Pci Bus Number
+ @param[in] Device2 Endpoint Pci Device Number
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS VC mapping correctly initialized
+**/
+EFI_STATUS
+PcieSetCommonClock (
+ IN UINT8 Bus1,
+ IN UINT8 Device1,
+ IN UINT8 Function1,
+ IN UINT8 Bus2,
+ IN UINT8 Device2
+ )
+{
+ UINT8 CapOffset1;
+ UINT8 CapOffset2;
+ BOOLEAN CommonClockSupport;
+ EFI_STATUS Status;
+ UINTN DeviceBase1;
+ UINTN DeviceBase2;
+ UINT16 RegData16;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function2;
+
+ DeviceBase1 = MmPciAddress (0, Bus1, Device1, Function1, 0);
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ CommonClockSupport = FALSE;
+ CapOffset1 = PcieFindCapId (Bus1, Device1, Function1, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset1 == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Check the Port Slot Clock Configuration Bit.
+ ///
+ if ((MmioRead16 (DeviceBase1 + CapOffset1 + 0x012) & BIT12) == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for (DeviceIndex = 0; DeviceIndex <= Device2; DeviceIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase2 + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase2 + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function2 = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function2 = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= Function2; FunctionIndex++) {
+ DeviceBase2 = MmPciAddress (0, Bus2, DeviceIndex, FunctionIndex, 0);
+ ///
+ /// Check the Endpoint Slot Clock Configuration Bit.
+ ///
+ CapOffset2 = PcieFindCapId (Bus2, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if ((CapOffset2 != 0) && ((MmioRead16 (DeviceBase2 + CapOffset2 + 0x012) & BIT12) != 0)) {
+ ///
+ /// Common clock is supported, set common clock bit on root port
+ /// and the endpoint
+ ///
+ if (CommonClockSupport == FALSE) {
+ MmioOr8 (DeviceBase1 + CapOffset1 + 0x010, BIT6);
+ CommonClockSupport = TRUE;
+ }
+
+ MmioOr8 (DeviceBase2 + CapOffset2 + 0x010, BIT6);
+ }
+ }
+ }
+ ///
+ /// If common clock not supported on root port and endpoint, return EFI_UNSUPPORTED
+ ///
+ if (CommonClockSupport == FALSE) {
+ Status = EFI_UNSUPPORTED;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+ ///
+ /// Set Pci + D4h Bit 6 and Bit 12 to 1 for root port only
+ ///
+ if (Bus1 == 0) {
+ MmioOr32 (DeviceBase1 + 0xD4, ((UINT32)(BIT6 | BIT12)));
+ }
+ ///
+ /// Retrain the Link per PCI Express Specification.
+ ///
+ MmioOr8 (DeviceBase1 + CapOffset1 + 0x010, BIT5);
+
+// AMI_OVERRIDE >>>
+#ifdef PCIE_CLEAR_RETRAIN_BIT_SUPPORT_FLAG
+ PchPmTimerStall (1);
+
+ if((MmioRead8 (DeviceBase1 + CapOffset1 + 0x010) & BIT5) == 1){
+ MmioAnd8 (DeviceBase1 + CapOffset1 + 0x010, BIT5);
+ }
+#endif
+// AMI_OVERRIDE <<<
+
+ ///
+ /// Wait until Re-Training has completed.
+ ///
+ do {
+ RegData16 = MmioRead16 (DeviceBase1 + CapOffset1 + 0x012) & BIT11;
+ } while (RegData16 != 0);
+
+ return Status;
+}
+
+/**
+ This function enables the CLKREQ# PM on all the end point functions
+
+ @param[in] Bus Pci Bus Number
+ @param[in] Device Pci Device Number
+ @param[in] RootFunction Rootport Function Number
+
+ @retval None
+**/
+VOID
+PcieSetClkreq (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 RootFunction
+ )
+{
+ UINT8 CapOffset;
+ UINTN DeviceBase;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 Function;
+ UINT32 Data32;
+ UINT16 GpioBase;
+ BOOLEAN ClkreqPerPortSupported;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+ UINT32 RootComplexBar;
+
+
+ PchSeries = GetPchSeries();
+
+ 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;
+
+ RootComplexBar = PCH_RCRB_BASE;
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32 = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32 != 0) {
+ ///
+ /// CLKREQ not supported on root port
+ ///
+ return;
+ }
+ }
+
+ for (DeviceIndex = 0; DeviceIndex <= Device; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+
+ ClkreqPerPortSupported = TRUE;
+
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ Function = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ Function = 0;
+ }
+ ///
+ /// Parse thro all the functions of the endpoint and find the PCIe Cap ID (offset 10h) and if
+ /// exists then enable the CLKREQ# bit (BIT8) on that function
+ ///
+ for (FunctionIndex = 0; FunctionIndex <= Function; FunctionIndex++) {
+ ///
+ /// Find the PCIe Cap Id (offset 10h)
+ ///
+ CapOffset = PcieFindCapId (Bus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset == 0) {
+ continue;
+ }
+
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, FunctionIndex, 0);
+ ///
+ /// Check if CLKREQ# is supported by the endpoints
+ ///
+ if ((MmioRead32 (DeviceBase + CapOffset + 0x0C) & BIT18) == 0) {
+ ///
+ /// CLKREQ# is not supported so dont do anything
+ ///
+ ClkreqPerPortSupported = FALSE;
+ break;
+ }
+ }
+
+ if (ClkreqPerPortSupported == FALSE) {
+ continue;
+ }
+ ///
+ /// Now enable the CLKREQ#
+ ///
+ for (FunctionIndex = 0; FunctionIndex <= Function; FunctionIndex++) {
+ ///
+ /// Find the PCIe Cap Id (offset 10h)
+ ///
+ CapOffset = PcieFindCapId (Bus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (CapOffset == 0) {
+ continue;
+ }
+
+ DeviceBase = MmPciAddress (0, Bus, DeviceIndex, FunctionIndex, 0);
+ MmioOr16 (DeviceBase + CapOffset + 0x010, BIT8);
+ }
+ }
+}
+
+/**
+ This function get or set the Max Payload Size on all the end point functions
+
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+ @param[in, out] MaxPayload The Max Payolad Size of the root port
+ @param[in] Operation True: Set the Max Payload Size on all the end point functions
+ False: Get the Max Payload Size on all the end point functions
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieMaxPayloadSize (
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice,
+ IN OUT UINT16 *MaxPayload,
+ IN BOOLEAN Operation
+ )
+{
+ UINTN DeviceBase;
+ UINT8 PcieCapOffset;
+ UINT16 EndPointMaxPayload;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 EndPointFunction;
+
+ ///
+ /// Obtain the Max Payload Size for all the end point functions
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= EndPointDevice; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ if (MmioRead16 (DeviceBase + 0x0) != 0xFFFF) {
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ PcieCapOffset = PcieFindCapId (EndPointBus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (PcieCapOffset == 0) {
+ continue;
+ }
+
+ if (Operation == TRUE) {
+ ///
+ /// Set the Max Payload Size of the end point function
+ ///
+ MmioAndThenOr16 (
+ DeviceBase + PcieCapOffset + 0x08,
+ (UINT16)~(BIT7 | BIT6 | BIT5),
+ *MaxPayload << 5
+ );
+ } else {
+ ///
+ /// Get the end point function Max Payload Size support
+ ///
+ EndPointMaxPayload = MmioRead16 (DeviceBase + PcieCapOffset + 0x04) & (BIT2 | BIT1 | BIT0);
+ ///
+ /// Obtain the minimum Max Payload Size between the PCIE root Port and the end point functions
+ ///
+ if (*MaxPayload > EndPointMaxPayload) {
+ *MaxPayload = EndPointMaxPayload;
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function disable the forwarding of EOI messages unless it discovers
+ an IOAPIC behind this root port.
+
+ @param[in] RootBus The Bus Number of the root port
+ @param[in] RootDevice The Device Number of the root port
+ @param[in] RootFunction The Function Number of the root port
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @param[in] EndPointDevice The Device Number of the Endpoint
+
+ @exception EFI_UNSUPPORTED Unsupported operation.
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+PcieSetEoiFwdDisable (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ IN UINT8 EndPointBus,
+ IN UINT8 EndPointDevice
+ )
+{
+ BOOLEAN IoApicBehind;
+ UINTN RootDeviceBase;
+ UINTN DeviceBase;
+ UINT8 ProgInterface;
+ UINT8 SubClassCode;
+ UINT8 BaseClassCode;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT8 EndPointFunction;
+
+ IoApicBehind = FALSE;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+
+ ///
+ /// Check if an IOAPIC behind the root port
+ ///
+ for (DeviceIndex = 0; DeviceIndex <= EndPointDevice; DeviceIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (DeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (DeviceBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ DeviceBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ BaseClassCode = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET + 2);
+ SubClassCode = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET + 1);
+ ProgInterface = MmioRead8 (DeviceBase + PCI_CLASSCODE_OFFSET);
+
+ if ((BaseClassCode == PCI_CLASS_SYSTEM_PERIPHERAL) &&
+ (SubClassCode == PCI_SUBCLASS_PIC) &&
+ ((ProgInterface == PCI_IF_APIC_CONTROLLER) ||
+ (ProgInterface == PCI_IF_APIC_CONTROLLER2))) {
+ IoApicBehind = TRUE;
+ }
+ }
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.14 Additional PCI Express* Programming Steps
+ /// Step 20
+ /// If there is no IOAPIC behind the root port, set EOI Forwarding Disable bit (B0:D28:F0-F7:D4h[1]) to 1b.
+ ///
+ if (IoApicBehind == FALSE) {
+ #ifdef HOTPLUG_EOI_FLAG // AMI_OVERRIDE, [EIP84720]>
+ MmioOr8 (RootDeviceBase + 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 == RootFunction) || (!(MmioRead8 (DeviceBase + 0x54) & 0x40))){
+ #else
+ if(!(MmioRead8 (DeviceBase + 0x54) & 0x40)){
+ #endif
+ MmioOr8 (RootDeviceBase + 0xD4, (UINT8) (BIT1));
+ }
+ #endif // AMI_OVERRIDE, [EIP84720]<
+ }
+
+ return EFI_SUCCESS;
+}
+
+typedef enum {
+ CalculateAspm,
+ ManualAspm,
+ SetAspm
+} OPERATION;
+
+/**
+ This function compares the actual latency in LatencyValue1
+ with actual latency in LatencyValue2 and stores the minimum
+ back to LatencyValue1, in the required format.
+ If this is the first call, then LatencyValue1 will be replaced by LatencyValue2.
+
+ @param[in, out] LatencyValue1 - Current latency value
+ @param[in] LatencyValue2 - Latency value from the Table
+
+ @retval None
+**/
+VOID
+DetermineLatencyValue (
+ IN OUT UINT16 *LatencyValue1,
+ IN UINT16 *LatencyValue2
+ )
+{
+ ASSERT (LTR_SCALE_VALUE (*LatencyValue1) < 6);
+ ASSERT (LTR_SCALE_VALUE (*LatencyValue2) < 6);
+ ///
+ /// If there are more than one device behind a bridge that are part of the override table,
+ /// store the lower latency value and corresponding scale bits back to LatencyValue1
+ ///
+ if ((LTR_LATENCY_NS(*LatencyValue1) == 0) || (LTR_LATENCY_NS(*LatencyValue1) > LTR_LATENCY_NS(*LatencyValue2))) {
+ *LatencyValue1 = *LatencyValue2;
+ }
+}
+
+/**
+ Calculate/Set EndPoint device Power management settings
+
+ @param[in] RootDeviceBase The Root Port PCI Express address
+ @param[in] RootPcieCapOffset The pointer to the Root Port PCI Express Capability Structure
+ @param[in] EndPointBus The Bus Number of the Endpoint
+ @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, out] LinkAspmVal Resulting Link ASPM value programmed
+ @param[in] Operation Operation Types
+ @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, out] LtrOverrideVal Resulting LTR override value to be programmed
+ @param[in] RootL1SubstateExtCapOffset The register offset of Root Port L1 Substates
+ @param[in, out] L1SubstatesSupported Input and return the result of L1 Substates support
+ @param[in] L1SubstatesConfig L1 Substates configurations
+ @param[in, out] PortCommonModeRestoreTime Input and return common mode restore time of L1 Substate setting
+ @param[in, out] PortTpowerOnValue Input and return power on value of L1 Substate setting
+ @param[in, out] PortTpowerOnScale Input and return power on scale of L1 Substate setting
+ @param[in] PchPwrOptPcie Pcie Power Optimizer Configuration
+ @param[in, out] AspmOverride Input and return the Aspm Override enable for pre-1.1 devices
+ @param[in, out] ClkreqPerPortSupported Input to check if clkreq per port is supportted
+ @param[in, out] RpAndEndPointsLtrSupported Return to check if all endpoints support LTR
+ @param[in] PolicyRevision Policy revision for codes compatibility
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device
+ @retval EFI_OUT_OF_RESOURCES The endpoint device is a bridge, but the Subordinate Bus Number of
+ the root port is not greater than its Secondary Bus Number. You may
+ get this error if PCI emulation is not done before this function gets
+ called and the platform policy settings of "TempRootPortBusNumMax" and
+ "TempRootPortBusNumMin" do not provide enough resource for temp bus
+ number usage.
+**/
+EFI_STATUS
+PcieEndPointPm (
+ IN UINTN RootDeviceBase,
+ IN UINT32 RootPcieCapOffset,
+ IN UINT8 EndPointBus,
+ IN UINT8 NumOfDevAspmOverride,
+ IN PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride,
+ IN OUT UINT16 *LinkAspmVal,
+ IN OPERATION Operation,
+ IN UINT8 NumOfDevLtrOverride,
+ IN PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride,
+ IN OUT UINT32 *LtrOverrideVal,
+ IN UINT16 RootL1SubstateExtCapOffset,
+ IN OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN OUT UINT32 *PortCommonModeRestoreTime,
+ IN OUT UINT32 *PortTpowerOnValue,
+ IN OUT UINT32 *PortTpowerOnScale,
+ IN PCH_PCIE_PWR_OPT *PchPwrOptPcie,
+ IN OUT BOOLEAN *AspmOverride,
+ IN BOOLEAN *ClkreqPerPortSupported,
+ IN OUT BOOLEAN *RpAndEndPointsLtrSupported,
+ IN UINT8 PolicyRevision
+ )
+{
+ EFI_STATUS Status;
+ UINTN EndPointBase;
+ UINT8 EndPointFunction;
+ UINT8 EndPointPcieCapOffset;
+ UINT8 PcieDeviceIndex;
+ UINT16 EndPointAspm;
+ UINT16 EndPointVendorId;
+ UINT16 EndPointDeviceId;
+ UINT8 EndPointRevId;
+ UINT8 EndPointBaseClassCode;
+ UINT8 EndPointSubClassCode;
+ UINT32 PortLxLat;
+ UINT32 EndPointLxLat;
+ UINT32 LxLat;
+ UINT8 DownStreamBusMin;
+ UINT8 ClassCode;
+ UINT8 RootDevSubBusNum;
+ BOOLEAN BusAssign;
+ UINT8 DeviceIndex;
+ UINT8 FunctionIndex;
+ UINT16 LtrExtendedCapOffset;
+ UINT32 DeviceCapabilities2;
+ UINT16 DefaultMaxLatency;
+ UINT16 Data16;
+ UINT32 Data32;
+ UINT16 EndPointL1SubStateCapOffset;
+ UINT32 RootDeviceL1Substates;
+ UINT32 EndPointL1Substates;
+ UINT8 EndPointPortCommonModeRestoreTime;
+ UINT8 EndPointTpowerOnScale;
+ UINT8 EndPointTpowerOnValue;
+ UINT32 Multiplier[4] = {2, 10, 100, 0};
+ UINT32 EndPointL1SubstCapMask;
+ PCH_SERIES PchSeries;
+
+ DefaultMaxLatency = 0;
+ PchSeries = GetPchSeries();
+ for (DeviceIndex = 0; DeviceIndex <= PCI_MAX_DEVICE; DeviceIndex++) {
+ EndPointBase = MmPciAddress (0, EndPointBus, DeviceIndex, 0, 0);
+ if (MmioRead16 (EndPointBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ continue;
+ }
+ ///
+ /// Check if EndPoint device is Multi-Function Device
+ ///
+ if (MmioRead8 (EndPointBase + PCI_HEADER_TYPE_OFFSET) & HEADER_TYPE_MULTI_FUNCTION) {
+ ///
+ /// If multi-function Device, check function 0-7
+ ///
+ EndPointFunction = PCI_MAX_FUNC;
+ } else {
+ ///
+ /// Otherwise, check function 0 only
+ ///
+ EndPointFunction = 0;
+ }
+
+ for (FunctionIndex = 0; FunctionIndex <= EndPointFunction; FunctionIndex++) {
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ EndPointPcieCapOffset = PcieFindCapId (EndPointBus, DeviceIndex, FunctionIndex, EFI_PCI_CAPABILITY_ID_PCIEXP);
+
+ if (EndPointPcieCapOffset == 0) {
+ if (FunctionIndex < EndPointFunction) {
+ continue;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+ EndPointBase = MmPciAddress (0, EndPointBus, DeviceIndex, FunctionIndex, 0);
+ EndPointVendorId = MmioRead16 (EndPointBase + R_PCH_PCIE_VENDOR_ID);
+ EndPointDeviceId = MmioRead16 (EndPointBase + R_PCH_PCIE_DEVICE_ID);
+ EndPointRevId = MmioRead8 (EndPointBase + R_PCH_PCIE_RID);
+ EndPointL1SubStateCapOffset = 0;
+ RootDeviceL1Substates = 0;
+ EndPointL1Substates = 0;
+ EndPointL1SubstCapMask = 0x0000001F;
+ if (PchSeries == PchLp) {
+ ///
+ /// Get the endpoint supports L1 Substates Capabilities
+ ///
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevAspmOverride; PcieDeviceIndex++) {
+ if ((PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) &&
+ ((DevAspmOverride[PcieDeviceIndex].OverrideConfig & PchPcieL1SubstatesOverride) == PchPcieL1SubstatesOverride) &&
+ (EndPointVendorId == DevAspmOverride[PcieDeviceIndex].VendorId) &&
+ (EndPointDeviceId == DevAspmOverride[PcieDeviceIndex].DeviceId) &&
+ ((EndPointRevId == DevAspmOverride[PcieDeviceIndex].RevId) ||
+ (DevAspmOverride[PcieDeviceIndex].RevId == 0xFF))) {
+ if ((EndPointVendorId == 0x8086) &&
+ ((EndPointDeviceId == 0x08B1) || (EndPointDeviceId == 0x08B2) ||
+ (EndPointDeviceId == 0x08B3) || (EndPointDeviceId == 0x08B4))) {
+ if ((MmioRead32 (EndPointBase + DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset) & 0xFFFF) == 0xCAFE) {
+ EndPointL1SubStateCapOffset = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset;
+ EndPointL1SubstCapMask = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapMask;
+ }
+ } else {
+ EndPointL1SubStateCapOffset = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapOffset;
+ EndPointL1SubstCapMask = DevAspmOverride[PcieDeviceIndex].L1SubstatesCapMask;
+ }
+ }
+ }
+ if (EndPointL1SubStateCapOffset == 0) {
+ EndPointL1SubStateCapOffset = PcieFindExtendedCapId (
+ EndPointBus,
+ DeviceIndex,
+ FunctionIndex,
+ 0x1E);
+ }
+ if (EndPointL1SubStateCapOffset != 0) {
+ RootDeviceL1Substates = MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04);
+ EndPointL1Substates = MmioRead32 (EndPointBase + EndPointL1SubStateCapOffset + 0x04);
+ }
+ }
+ DeviceCapabilities2 = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x24);
+ if (((DeviceCapabilities2 & BIT11) == 0) || (PchPwrOptPcie->LtrEnable != TRUE)) {
+ *RpAndEndPointsLtrSupported = FALSE;
+ }
+ ///
+ /// Configure downstream device if present.
+ ///
+
+ if (Operation == CalculateAspm || Operation == ManualAspm) {
+ if ((MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & BIT18) != BIT18) {
+ *ClkreqPerPortSupported = FALSE;
+ }
+ EndPointAspm = (MmioRead16 (EndPointBase + EndPointPcieCapOffset + 0x00C) >> 10) & 3;
+ DEBUG ((EFI_D_INFO, "Endpoint Device %0x Capability ASPM: %0x\n", DeviceIndex, EndPointAspm));
+ if (Operation == CalculateAspm) {
+ ///
+ /// Check endpoint for pre-1.1 devices based on the Role based Error Reporting Capability bit
+ /// and enable Aspm Override
+ ///
+ if (!(MmioRead16 (EndPointBase + EndPointPcieCapOffset + 0x4) & BIT15)) {
+ DEBUG ((EFI_D_INFO, "Override root port ASPM to L1 for pre-1.1 devices\n"));
+ *AspmOverride = TRUE;
+ }
+ ///
+ /// Mask APMC with values from lookup table.
+ /// RevID of 0xFF applies to all steppings.
+ ///
+ EndPointBaseClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_BCC);
+ EndPointSubClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_SCC);
+
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevAspmOverride; PcieDeviceIndex++) {
+ if ((PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) &&
+ ((DevAspmOverride[PcieDeviceIndex].OverrideConfig & PchPcieL1L2Override) == PchPcieL1L2Override) &&
+ ((DevAspmOverride[PcieDeviceIndex].VendorId == EndPointVendorId) ||
+ (DevAspmOverride[PcieDeviceIndex].VendorId == 0xFFFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].DeviceId == EndPointDeviceId) ||
+ (DevAspmOverride[PcieDeviceIndex].DeviceId == 0xFFFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].RevId == EndPointRevId) ||
+ (DevAspmOverride[PcieDeviceIndex].RevId == 0xFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].BaseClassCode == EndPointBaseClassCode) ||
+ (DevAspmOverride[PcieDeviceIndex].BaseClassCode == 0xFF)) &&
+ ((DevAspmOverride[PcieDeviceIndex].SubClassCode == EndPointSubClassCode) ||
+ (DevAspmOverride[PcieDeviceIndex].SubClassCode == 0xFF))) {
+ ///
+ /// Override value of 0xFF applies to all.
+ ///
+ EndPointAspm = DevAspmOverride[PcieDeviceIndex].EndPointAspm;
+ break;
+ }
+ }
+ ///
+ /// Check if L1 should be enabled based on port and endpoint L1 exit latency.
+ ///
+ if (EndPointAspm & BIT1) {
+ PortLxLat = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x00C) & (BIT17 + BIT16 + BIT15);
+ EndPointLxLat = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & (BIT17 + BIT16 + BIT15);
+
+ LxLat = PortLxLat;
+ if (PortLxLat < EndPointLxLat) {
+ LxLat = EndPointLxLat;
+ }
+ ///
+ /// check if the value is bigger than endpoint L1 acceptable exit latency, if it is
+ /// larger than accepted value, then we should disable L1
+ ///
+ LxLat >>= 6;
+ if (LxLat > (MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x004) & (BIT11 + BIT10 + BIT9))) {
+ EndPointAspm &= ~BIT1;
+ }
+ }
+ ///
+ /// Check if L0s should be enabled based on port and endpoint L0s exit latency.
+ ///
+ if (EndPointAspm & BIT0) {
+ PortLxLat = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x00C) & (BIT14 + BIT13 + BIT12);
+ EndPointLxLat = MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x00C) & (BIT14 + BIT13 + BIT12);
+
+ LxLat = PortLxLat;
+ if (PortLxLat < EndPointLxLat) {
+ LxLat = EndPointLxLat;
+ }
+ ///
+ /// check if the value is bigger than endpoint L0s acceptable exit latency, if it is
+ /// larger than accepted value, then we should disable L0s
+ ///
+ LxLat >>= 6;
+ if (LxLat > (MmioRead32 (EndPointBase + EndPointPcieCapOffset + 0x004) & (BIT8 + BIT7 + BIT6))) {
+ EndPointAspm &= ~BIT0;
+ }
+ }
+ }
+
+ *LinkAspmVal &= EndPointAspm;
+ DEBUG ((EFI_D_INFO, "Calculate Endpoint Device %0x Aspm Value: %0x\n", DeviceIndex, EndPointAspm));
+ if (PchSeries == PchLp) {
+ ///
+ /// Check if the endpoint supports L1 Substates Capabilities
+ ///
+ if ((EndPointL1SubStateCapOffset != 0) && (RootL1SubstateExtCapOffset != 0)) {
+ ///
+ /// If both Root and endpoint's L1 Sub-States Extended Capability Offset + 0x04[4:0] are 11111b,
+ /// a. Read L1 Sub-States Extended Capability Offset + 0x04[15:8], and program the highest value advertised
+ /// between PCIe rootport and device to L1 Sub-States Extended Capability Offset + 0x08[15:8] on
+ /// Pcie root port.
+ /// b. Read L1 Sub-States Extended Capability Offset + 0x04[23:19] and [17:16], and program the highest value
+ /// advertised between PCIe root port and device.to L1 Sub-States Extended Capability Offset + 0x08 [7:0] on
+ /// both Pcie root port and device.
+ /// c. Program L1 Sub-States Extended Capability Offset + 0x08[31:29] to 010b for both Pcie root port and device
+ /// d. Program L1 Sub-States Extended Capability Offset + 0x08[25:16] to 0010100000b for both Pcie root port and device
+ /// e. Program L1 Sub-States Extended Capability Offset + 0x08[4:0] to 01111b for both Pcie root port and device
+ ///
+ if (((RootDeviceL1Substates & 0x1F) == 0x1F) &&
+ ((EndPointL1Substates & EndPointL1SubstCapMask) == EndPointL1SubstCapMask) &&
+ (L1SubstatesConfig != PchPcieL1SubstatesDisabled)) {
+ *L1SubstatesSupported = TRUE;
+ EndPointPortCommonModeRestoreTime = (EndPointL1Substates >> 8) & 0xFF;
+ EndPointTpowerOnScale = (EndPointL1Substates >> 16) & 0x3;
+ EndPointTpowerOnValue = (EndPointL1Substates >> 19) & 0x1F;
+
+ if (EndPointPortCommonModeRestoreTime > *PortCommonModeRestoreTime) {
+ *PortCommonModeRestoreTime = EndPointPortCommonModeRestoreTime;
+ }
+
+ if ((EndPointTpowerOnValue * Multiplier[EndPointTpowerOnScale]) >
+ (*PortTpowerOnValue * Multiplier[*PortTpowerOnScale])) {
+ *PortTpowerOnValue = EndPointTpowerOnValue;
+ *PortTpowerOnScale = EndPointTpowerOnScale;
+ }
+ }
+ }
+ }
+ ///
+ /// For each device detected, scan the LTR override table
+ /// If there are endpoints connected directly to the rootport then
+ /// LtrOverrideVal will be replaced by the value from the table for that endpoint
+ /// If there are endpoints that are behind a bridge and that are also part of the table then
+ /// LtrOverrideVal will maintain the minimum of all such values.
+ /// A non zero value of LtrOverrideVal will indicate:
+ /// i):That there is atleast one entry in the LTR override Table
+ /// ii):The final value to be programmed in offset 0x400. This value will be applied for all the devices
+ /// connected to this root port
+ ///
+ Data32 = *LtrOverrideVal;
+ if (DevLtrOverride != NULL) {
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevLtrOverride; PcieDeviceIndex++) {
+ if ((DevLtrOverride[PcieDeviceIndex].VendorId == EndPointVendorId) &&
+ ((DevLtrOverride[PcieDeviceIndex].DeviceId == EndPointDeviceId) ||
+ (DevLtrOverride[PcieDeviceIndex].DeviceId == 0xFFFF)) &&
+ ((DevLtrOverride[PcieDeviceIndex].RevId == EndPointRevId) ||
+ (DevLtrOverride[PcieDeviceIndex].RevId == 0xFF))) {
+
+ ///
+ /// Get the Non-Snoop latency value from the table, compare and store the minimum
+ ///
+ if (DevLtrOverride[PcieDeviceIndex].NonSnoopLatency & BIT15) {
+ Data16 = (UINT16)((Data32 & 0xFFFF0000) >> 16);
+ DetermineLatencyValue(&Data16, &DevLtrOverride[PcieDeviceIndex].NonSnoopLatency);
+ Data32 = (Data32 & 0xFFFF) | ((UINT32)(Data16 << 16));
+ }
+
+ ///
+ /// Get the Snoop latency value from the table, compare and store the minimum
+ ///
+ if (DevLtrOverride[PcieDeviceIndex].SnoopLatency & BIT15) {
+ Data16 = (UINT16)(Data32 & 0xFFFF);
+ DetermineLatencyValue(&Data16, &DevLtrOverride[PcieDeviceIndex].SnoopLatency);
+ Data32 = (Data32 & 0xFFFF0000) | (UINT32)Data16;
+ }
+ *LtrOverrideVal = Data32;
+ break;
+ }
+ }
+ }
+ } else if (Operation == SetAspm) {
+ if (PchSeries == PchLp) {
+ if ((EndPointL1SubStateCapOffset != 0) && (*L1SubstatesSupported)) {
+ if (((RootDeviceL1Substates & 0x1F) == 0x1F) &&
+ ((EndPointL1Substates & EndPointL1SubstCapMask) == EndPointL1SubstCapMask)) {
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x0C,
+ (UINT32) ~(0xF8),
+ (*PortTpowerOnValue << 3)
+ );
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x0C,
+ (UINT32) ~(0x03),
+ *PortTpowerOnScale);
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x08,
+ (UINT32) ~(0xE3FF0000),
+ (UINT32) (BIT30 | BIT23 | BIT21)
+ );
+ Data32 = (BIT3 | BIT2 | BIT1 | BIT0);
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_1) {
+ Data32 &= (UINT32)~(BIT0);
+ }
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_2) {
+ Data32 &= (UINT32)~(BIT1);
+ }
+ MmioAndThenOr32 (
+ EndPointBase + EndPointL1SubStateCapOffset + 0x08,
+ (UINT32) ~(0x1F),
+ Data32
+ );
+ }
+ }
+ }
+ ///
+ /// Write it to the Link Control register
+ ///
+ DEBUG ((EFI_D_INFO, "Program Endpoint Device %0x Aspm Value: %0x\n", DeviceIndex, *LinkAspmVal));
+ MmioAndThenOr16 (EndPointBase + EndPointPcieCapOffset + 0x10, 0xFFFC, *LinkAspmVal);
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3
+ /// For PCIe Endpoint,
+ /// If Endpoint device supported LTR, Device Capabilities 2 Register Offset 24h [11] = 1b,
+ ///
+ if ((DeviceCapabilities2 & BIT11) && (PchPwrOptPcie->LtrEnable == TRUE)) {
+ ///
+ /// Step 3.1
+ /// Program Endpoint LTR Mechanism Enable, Device Control 2 Register Offset 28h [10] = 1b
+ /// when device supports LTR but is not found in override table (table listing correct
+ /// latency requirements for devices that supports LTR and also for devices that do not
+ /// support LTR)
+ ///
+ if (DevLtrOverride != NULL) {
+ for (PcieDeviceIndex = 0; PcieDeviceIndex < NumOfDevLtrOverride; PcieDeviceIndex++) {
+ if ((DevLtrOverride[PcieDeviceIndex].VendorId != EndPointVendorId) ||
+ ((DevLtrOverride[PcieDeviceIndex].DeviceId != EndPointDeviceId) &&
+ (DevLtrOverride[PcieDeviceIndex].DeviceId != 0xFFFF)) ||
+ ((DevLtrOverride[PcieDeviceIndex].RevId != EndPointRevId) &&
+ (DevLtrOverride[PcieDeviceIndex].RevId != 0xFF))) {
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, BIT10);
+ break;
+ }
+ }
+ } else {
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, BIT10);
+ }
+ }
+ ///
+ /// Get the pointer to the Endpoint PCI Express Extended Capability Structure
+ /// and configure the Max Snoop and Max No-Snoop Latency for the endpoint
+ ///
+ LtrExtendedCapOffset = PcieFindExtendedCapId (EndPointBus, DeviceIndex, FunctionIndex, 0x18);
+ if (LtrExtendedCapOffset != 0) {
+ Data32 = *LtrOverrideVal;
+ if (PchSeries == PchH) {
+ DefaultMaxLatency = 0x0846;
+ }
+ if (PchSeries == PchLp) {
+ DefaultMaxLatency = 0x1003;
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3.2
+ /// Program Endpoint Max Snoop Latency Register, Latency Tolerance Reporting(LTR)
+ /// Capability Offset 04h [15:0] with Intel recommended default value for max snoop
+ /// latency if there is no snoop latency override value getting programmed in the
+ /// override register else program the endpoint Max Snoop Latency Register with the
+ /// minimum of snoop latency override value for that root port and Intel recommended
+ /// default value for max snoop latency
+ /// Intel recommended default value for max snoop latency for LPT-H = 0x0846
+ /// Intel recommended default value for max snoop latency for LPT-LP = 0x1003
+ ///
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ DefaultMaxLatency = PchPwrOptPcie->LtrMaxSnoopLatency;
+ }
+
+ Data16 = (UINT16)(Data32 & 0xFFFF);
+ ///
+ /// Set the max snoop latency to either the default max snoop latency or to the snoop latency override value
+ /// that is being programmed for this root port
+ ///
+ DetermineLatencyValue(&Data16, &DefaultMaxLatency);
+ MmioAndThenOr16 (
+ EndPointBase + LtrExtendedCapOffset + 4,
+ (UINT16) (~0x1FFF),
+ Data16
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.6, Section 8.14.1 Power Optimizer Configuration
+ /// Step 3.3
+ /// Program Endpoint Max No-Snoop Latency Register, Latency Tolerance Reporting(LTR)
+ /// Capability Offset 06h [15:0] with Intel recommended default value for max no-snoop
+ /// latency if there is no No-snoop latency override value getting programmed in the
+ /// override register else program the endpoint Max No-Snoop Latency Register with the
+ /// minimum of No-snoop latency override value for that root port and Intel recommended
+ /// default value for max no-snoop latency
+ /// Intel recommended default value for max no-snoop latency for LPT-H = 0x0846
+ /// Intel recommended default value for max no-snoop latency for LPT-LP = 0x1003
+ ///
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ DefaultMaxLatency = PchPwrOptPcie->LtrMaxNoSnoopLatency;
+ }
+ Data16 = (UINT16)((Data32 & 0xFFFF0000) >> 16);
+ DetermineLatencyValue(&Data16, &DefaultMaxLatency);
+ MmioAndThenOr16 (
+ EndPointBase + LtrExtendedCapOffset + 6,
+ (UINT16) (~0x1FFF),
+ Data16
+ );
+ }
+ ///
+ /// Step 4
+ /// For PCIe Endpoint,
+ /// If Endpoint device supported OBFF, Device Capabilities 2 Register Offset 24h [19:18] = 2h,
+ ///
+ if ((DeviceCapabilities2 & BIT19) && (PchPwrOptPcie->ObffEnable == PCH_DEVICE_ENABLE)) {
+ ///
+ /// Step 4.1
+ /// Program Endpoint OBFF Mechanism Enable, Device Control 2 Register Offset 28h [14:13] = 3h
+ ///
+ MmioOr16 (EndPointBase + EndPointPcieCapOffset + 0x28, (BIT14 + BIT13));
+ }
+ }
+ ///
+ /// Check if this device is a bridge
+ ///
+ ClassCode = MmioRead8 (EndPointBase + R_PCH_PCIE_BCC);
+
+ if (ClassCode == PCI_CLASS_BRIDGE) {
+ ///
+ /// Get the downstream Bus number
+ ///
+ DownStreamBusMin = (UINT8) (MmioRead32 (EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of endpoint device is not assigned
+ ///
+ if (DownStreamBusMin == 0) {
+ RootDevSubBusNum = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 16);
+ ///
+ /// If the endpoint device is a bridge, the Subordinate Bus Number of the root port will need to be greater
+ /// than the Secondary Bus Number of the root port (the Bus Number of endpoint device).
+ ///
+ if (RootDevSubBusNum > EndPointBus) {
+ ///
+ /// Assign the Primary, Secondary and Subordinate Bus Number to endpoint device
+ ///
+ MmioAndThenOr32 (
+ EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF000000,
+ EndPointBus | (((UINT32) (EndPointBus + 1) << 8)) | ((UINT32) (RootDevSubBusNum << 16))
+ );
+ DownStreamBusMin = EndPointBus + 1;
+ } else {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+
+ if (DownStreamBusMin > EndPointBus) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ DownStreamBusMin,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ LinkAspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ LtrOverrideVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ PortCommonModeRestoreTime,
+ PortTpowerOnValue,
+ PortTpowerOnScale,
+ PchPwrOptPcie,
+ AspmOverride,
+ ClkreqPerPortSupported,
+ RpAndEndPointsLtrSupported,
+ PolicyRevision
+ );
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_INFO, "Check DownStreamBus:%d and no device found!\n", DownStreamBusMin));
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (EndPointBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+ }
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function checks if the root port and downstream device support Clkreq per port, ASPM L1 and L1 substates
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction 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
+ @param[in, out] L1SubstatesSupported Flag to indicate if L1 Substates are supported
+ @param[in] L1SubstatesConfig L1 Substates configuration
+ @param[in] PolicyRevision Revision of the policy
+ @param[in, out] AspmVal Aspm value for both rootport and end point devices
+ @param[in, out] ClkreqPerPortSupported Clkreq support for both rootport and endpoint devices
+ @param[out] LtrSupported Check and return if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieCheckPmConfig (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ 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 OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN OUT UINT16 *AspmVal,
+ IN OUT BOOLEAN *ClkreqPerPortSupported,
+ OUT BOOLEAN *LtrSupported
+ )
+{
+ EFI_STATUS Status;
+ UINTN RootDeviceBase;
+ UINT32 RootPcieCapOffset;
+ UINT8 EndPointBus;
+ OPERATION Operation;
+ UINT16 SlotStatus;
+ BOOLEAN BusAssign;
+ UINT32 DeviceCapabilities2;
+ UINT32 LtrOvrVal;
+ UINT32 Data32Or;
+ UINT16 GpioBase;
+ UINT32 RootComplexBar;
+ UINT16 RootL1SubstateExtCapOffset;
+ UINT32 PortCommonModeRestoreTime;
+ UINT32 PortTpowerOnValue;
+ UINT32 PortTpowerOnScale;
+ BOOLEAN AspmOverride;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+ RootComplexBar = PCH_RCRB_BASE;
+ PortCommonModeRestoreTime = 0;
+ PortTpowerOnValue = 0;
+ PortTpowerOnScale = 0;
+ *L1SubstatesSupported = FALSE;
+ AspmOverride = FALSE;
+ *ClkreqPerPortSupported = FALSE;
+ GpioBase = 0;
+
+ if (MmioRead16 (RootDeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ 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;
+
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32Or = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32Or == 0) {
+ *ClkreqPerPortSupported = TRUE;
+ }
+ }
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (RootPcieCapOffset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ DeviceCapabilities2 = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x24);
+
+ *AspmVal = (MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x00C) >> 10) & 3;
+ if (RootPortAspm == PchPcieAspmAutoConfig) {
+ Operation = CalculateAspm;
+ } else {
+ Operation = ManualAspm;
+ *AspmVal &= RootPortAspm;
+ }
+ ///
+ /// Get the downstream Bus number
+ ///
+ EndPointBus = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of the root port is not assigned
+ /// Note:
+ /// It will be better that PCI emulation has been done before PcieSetPm(). Or, you will need to assign
+ /// a larger number to TempRootPortBusNumMax to support the specific card which has many bridges behind.
+ /// If it is not, the platform policy settings of "TempRootPortBusNumMax" and "TempRootPortBusNumMin"
+ /// will be assigned to the Subordinate and Secondary Bus Number of the root ports.
+ /// The assigned bus number will be cleared in the end of PcieSetPm().
+ ///
+ if (EndPointBus == 0) {
+ MmioAndThenOr32 (
+ RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF0000FF,
+ ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ EndPointBus = TempBusNumberMin;
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ SlotStatus = MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x1A);
+ LtrOvrVal = 0;
+
+ RootL1SubstateExtCapOffset = 0;
+ if (PchSeries == PchLp) {
+ RootL1SubstateExtCapOffset = PcieFindExtendedCapId (RootBus, RootDevice, RootFunction, 0x1E);
+ if (RootL1SubstateExtCapOffset != 0) {
+ PortCommonModeRestoreTime = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 8) & 0xFF;
+ PortTpowerOnScale = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 16) & 0x3;
+ PortTpowerOnValue = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 19) & 0x1F;
+ }
+ }
+ ///
+ /// Obtain initial ASPM settings from respective port capability registers.
+ /// Scan LTR override table for device match and calculate the lowest override
+ /// value to be programmed into B0:D28:F0~F7 + 400h
+ ///
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ AspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RootDeviceBase + 0x018, 0xFF0000FF);
+ }
+
+ return Status;
+}
+/**
+ This function performs the Power Management settings for root port and downstream device
+
+ @param[in] RootBus Pci Bus Number of the root port
+ @param[in] RootDevice Pci Device Number of the root port
+ @param[in] RootFunction 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
+ @param[in, out] L1SubstatesSupported Flag to indicate if L1 Substates are supported
+ @param[in] L1SubstatesConfig L1 Substates configuration
+ @param[in] PolicyRevision Policy revision for codes compatibility
+ @param[in] FirstRpToSetPm Indicates if this is the first root port to be set
+ @param[in] L1SupportedInAllEnabledPorts Check if L1 is supported in all enabled ports
+ @param[in] ClkreqSupportedInAllEnabledPorts Check if clkreq is supported in all enabled ports
+ @param[out] LtrSupported Check and return if all endpoints support LTR
+
+ @retval EFI_SUCCESS The function completed successfully
+ @exception EFI_UNSUPPORTED The pointer to the Port PCI Express Capability Structure is not found
+**/
+EFI_STATUS
+PcieSetPm (
+ IN UINT8 RootBus,
+ IN UINT8 RootDevice,
+ IN UINT8 RootFunction,
+ 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 OUT BOOLEAN *L1SubstatesSupported,
+ IN PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig,
+ IN UINT8 PolicyRevision,
+ IN BOOLEAN FirstRPToSetPm,
+ IN BOOLEAN L1SupportedInAllEnabledPorts,
+ IN BOOLEAN ClkreqSupportedInAllEnabledPorts,
+ OUT BOOLEAN *LtrSupported
+ )
+{
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ ///
+ /// When enabling L0s / L1 support, BIOS should enable upstream device before downstream
+ /// device. When disabling ASPM, BIOS should make sure downstream device is disabled
+ /// before upstream device.
+ /// The System BIOS must perform the following steps to enable
+ /// L0s/L1 on the root ports:
+ ///
+ /// 1. Determine whether the endpoint supports L1 by checking the Active State Link PM
+ /// Support field of the endpoint Link Capability Register. If the endpoint does not
+ /// support L1, the System BIOS can skip the L1 calculations below. Likewise, System
+ /// BIOS should not enable L1 on the root port or the endpoint if the endpoint does not
+ /// support L1.
+ /// 2. Calculate the total L0s and L1 exit latency. A description of this calculation
+ /// is provided in Section 8.3.1.1.
+ /// 3. Compare the calculated total exit latency with Endpoint L0s/L1 Acceptable Latency
+ /// read from the Device Capabilities Register of the Endpoint to determine if L0s or
+ /// L1 can be enabled for all or some of the links on the entire path to satisfy the
+ /// Acceptable Latency reported by the Endpoint. The Exit Latency fields reported by
+ /// the registers are given as a range. It is recommended that System BIOS uses the
+ /// high end of the range for the latency calculation and comparison. For example, if
+ /// the latency field reports "2 us to less than 4 us", then 4 us should be used for
+ /// the calculation.
+ /// 4. If the comparison in step 3 indicates L0s and L1 can be enabled on a root port and
+ /// the endpoints attached to the root port, then set the root port register
+ /// D28:F0~F7:Reg E8h[1], then set the APMC field, D28:F0~F7:Reg 50h[1:0] to 11b and write
+ /// the same value to the APMC field of the endpoint Link Control register. If the
+ /// comparison in step 1 indicates only L0s can be enabled on a root port and the
+ /// endpoints attached to the root port, then set the APMC field, D28:F0~F7:Reg 50h[1:0]
+ /// to 01b and write the same value to the APMC field of the endpoint Link Control
+ /// register.
+ ///
+ /// NOTE: current implementation does not support full length exit latency calculation
+ ///
+ UINT16 AspmVal;
+ EFI_STATUS Status;
+ UINTN RootDeviceBase;
+ UINT32 RootPcieCapOffset;
+ UINT8 EndPointBus;
+ OPERATION Operation;
+ UINT16 SlotStatus;
+ BOOLEAN BusAssign;
+ UINT32 DeviceCapabilities2;
+ UINT32 LtrOvrVal;
+ UINT32 Data32Or;
+ UINT8 Data8And;
+ UINT8 Data8Or;
+ UINT16 GpioBase;
+ BOOLEAN ClkreqPerPortSupported;
+ UINT32 RootComplexBar;
+ UINT16 RootL1SubstateExtCapOffset;
+ UINT32 PortCommonModeRestoreTime;
+ UINT32 PortTpowerOnValue;
+ UINT32 PortTpowerOnScale;
+ BOOLEAN AspmOverride;
+ PCH_SERIES PchSeries;
+ UINT8 RootPortNumber;
+#ifdef ULT_FLAG
+ UINT32 Data32;
+ UINT8 Response;
+#endif // ULT_FLAG
+
+ PchSeries = GetPchSeries();
+ Status = EFI_SUCCESS;
+ RootDeviceBase = MmPciAddress (0, RootBus, RootDevice, RootFunction, 0);
+ RootComplexBar = PCH_RCRB_BASE;
+ PortCommonModeRestoreTime = 0;
+ PortTpowerOnValue = 0;
+ PortTpowerOnScale = 0;
+ *L1SubstatesSupported = FALSE;
+ AspmOverride = FALSE;
+ ClkreqPerPortSupported = FALSE;
+ GpioBase = 0;
+
+ if (MmioRead16 (RootDeviceBase + PCI_VENDOR_ID_OFFSET) == 0xFFFF) {
+ return EFI_NOT_FOUND;
+ }
+ 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;
+
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, RootFunction);
+ Data32Or = (IoRead32 ((UINTN) (GpioBase + R_PCH_GP_X_CONFIG0(18 + RootPortNumber))) & B_PCH_GPIO_OWN0_GPIO_USE_SEL);
+
+ if (Data32Or == 0) {
+ ClkreqPerPortSupported = TRUE;
+ }
+ }
+
+ ///
+ /// Get the pointer to the Port PCI Express Capability Structure.
+ ///
+ RootPcieCapOffset = PcieFindCapId (RootBus, RootDevice, RootFunction, EFI_PCI_CAPABILITY_ID_PCIEXP);
+ if (RootPcieCapOffset == 0) {
+ return EFI_UNSUPPORTED;
+ }
+ DeviceCapabilities2 = MmioRead32 (RootDeviceBase + RootPcieCapOffset + 0x24);
+
+ ///
+ /// Enable LTR mechanism for this root port if it is capable
+ ///
+ if ((DeviceCapabilities2 & BIT11) && (PchPwrOptPcie->LtrEnable == TRUE)) {
+ MmioOr16 (RootDeviceBase + RootPcieCapOffset + 0x28, BIT10);
+ }
+
+ ///
+ /// Enable OBFF using WAKE# signaling for this root port if it is capable
+ ///
+ if ((DeviceCapabilities2 & BIT19) && (PchPwrOptPcie->ObffEnable == TRUE)) {
+ MmioOr16 (RootDeviceBase + RootPcieCapOffset + 0x28, (BIT14 + BIT13));
+ }
+ AspmVal = (MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x00C) >> 10) & 3;
+ if (RootPortAspm == PchPcieAspmAutoConfig) {
+ Operation = CalculateAspm;
+ } else {
+ Operation = ManualAspm;
+ AspmVal &= RootPortAspm;
+ }
+ ///
+ /// Get the downstream Bus number
+ ///
+ EndPointBus = (UINT8) (MmioRead32 (RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET) >> 8);
+ ///
+ /// If the Secondary Bus Number of the root port is not assigned
+ /// Note:
+ /// It will be better that PCI emulation has been done before PcieSetPm(). Or, you will need to assign
+ /// a larger number to TempRootPortBusNumMax to support the specific card which has many bridges behind.
+ /// If it is not, the platform policy settings of "TempRootPortBusNumMax" and "TempRootPortBusNumMin"
+ /// will be assigned to the Subordinate and Secondary Bus Number of the root ports.
+ /// The assigned bus number will be cleared in the end of PcieSetPm().
+ ///
+ if (EndPointBus == 0) {
+ MmioAndThenOr32 (
+ RootDeviceBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF0000FF,
+ ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ EndPointBus = TempBusNumberMin;
+ BusAssign = FALSE;
+ } else {
+ BusAssign = TRUE;
+ }
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ SlotStatus = MmioRead16 (RootDeviceBase + RootPcieCapOffset + 0x1A);
+ LtrOvrVal = 0;
+
+ RootL1SubstateExtCapOffset = 0;
+ if (PchSeries == PchLp) {
+ RootL1SubstateExtCapOffset = PcieFindExtendedCapId (RootBus, RootDevice, RootFunction, 0x1E);
+ if (RootL1SubstateExtCapOffset != 0) {
+ PortCommonModeRestoreTime = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 8) & 0xFF;
+ PortTpowerOnScale = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 16) & 0x3;
+ PortTpowerOnValue = (MmioRead32 (RootDeviceBase + RootL1SubstateExtCapOffset + 0x04) >> 19) & 0x1F;
+ }
+ }
+ ///
+ /// Obtain initial ASPM settings from respective port capability registers.
+ /// Scan LTR override table for device match and calculate the lowest override
+ /// value to be programmed into B0:D28:F0~F7 + 400h
+ ///
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ &AspmVal,
+ Operation,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ &ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ if (PchPwrOptPcie->LtrEnable == PCH_DEVICE_ENABLE) {
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ if (PchPwrOptPcie->SnoopLatencyOverrideMode == 1) {
+ LtrOvrVal &= 0xFFFF0000;
+ LtrOvrVal |= (UINT32) BIT15 |
+ (UINT32) (PchPwrOptPcie->SnoopLatencyOverrideMultiplier << 10) |
+ (UINT32) (PchPwrOptPcie->SnoopLatencyOverrideValue);
+ }
+
+ if (PchPwrOptPcie->NonSnoopLatencyOverrideMode == 1) {
+ LtrOvrVal &= 0x0000FFFF;
+ LtrOvrVal |= (UINT32) BIT31 |
+ (UINT32) (PchPwrOptPcie->NonSnoopLatencyOverrideMultiplier << 26) |
+ (UINT32) (PchPwrOptPcie->NonSnoopLatencyOverrideValue << 16);
+ }
+ }
+ if (LtrOvrVal != 0) {
+ ///
+ /// Program B0:D28:F0~F7 + 400h only if we find a device in the LTR override table
+ ///
+ MmioWrite32 (RootDeviceBase + R_PCH_PCIE_LTROVR, LtrOvrVal);
+ ///
+ /// Step 1.2
+ /// Program B0:D28:F0~F7 + 404h [1:0] = 11b for ports which has a PCIe device
+ /// device attached to it.
+ ///
+ Data32Or = BIT1 | BIT0;
+ if (PolicyRevision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ if (PchPwrOptPcie->SnoopLatencyOverrideMode == 0) {
+ Data32Or &= (UINT32) ~BIT0;
+ }
+ if (PchPwrOptPcie->NonSnoopLatencyOverrideMode == 0) {
+ Data32Or &= (UINT32) ~BIT1;
+ }
+ if (PchPwrOptPcie->LtrConfigLock == PCH_DEVICE_ENABLE) {
+ ///
+ /// Set the lock bit
+ ///
+ Data32Or |= BIT2;
+ }
+ }
+ MmioWrite32 (RootDeviceBase + R_PCH_PCIE_LTROVR2, Data32Or);
+ }
+ }
+ }
+#ifdef ULT_FLAG
+ if (PchSeries == PchLp) {
+ ///
+ /// If both Root and endpoint's L1 Sub-States Extended Capability Offset + 0x04[4:0] are 11111b,
+ ///
+ if (*L1SubstatesSupported) {
+ ///
+ /// a. Read L1 Sub-States Extended Capability Offset + 0x04[15:8], and Set the highest value advertised
+ /// between PCIe rootport and device to L1 Sub-States Extended Capability Offset + 0x08[15:8] on both
+ /// Pcie root port and device.
+ ///
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(0xFF00),
+ (UINT32) PortCommonModeRestoreTime << 8
+ );
+
+ ///
+ /// b. Read L1 Sub-States Extended Capability Offset + 0x04[23:19] and [17:16], and Set the highest value
+ /// advertised between PCIe root port and device to L1 Sub-States Extended Capability Offset + 0x0C [7:0] on
+ /// both Pcie root port and device.
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x0C,
+ 0xFFFFFF04,
+ (UINT32) ((PortTpowerOnValue << 3) | PortTpowerOnScale)
+ );
+
+ ///
+ /// c. Set L1 Sub-States Extended Capability Offset + 0x08[31:29] to 010b for both Pcie root port and device
+ /// d. Set L1 Sub-States Extended Capability Offset + 0x08[25:16] to 0010100000b for both Pcie root port and device
+ ///
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(0xE3FF0000),
+ (UINT32) (BIT30 | BIT23 | BIT21)
+ );
+
+ ///
+ /// e. If clkreq per port is suported, set D28:F0~F5:420h[0] to 1b prior to L1 enabling
+ ///
+ if (((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) == V_PCH_PCIE_LCTL_APMC_L1) && ClkreqPerPortSupported) {
+ MmioOr32 (RootDeviceBase + R_PCH_PCIE_PCIEPMECTL, BIT0);
+ }
+
+ ///
+ /// f. Set L1 Sub-States Extended Capability Offset + 0x08[4:0] to 01111b for both Pcie root port and device
+ ///
+ Data32Or = (BIT3 | BIT2 | BIT1 | BIT0);
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_1) {
+ Data32Or &= (UINT32)~(BIT0);
+ }
+ if (L1SubstatesConfig == PchPcieL1SubstatesL1_2) {
+ Data32Or &= (UINT32)~(BIT1);
+ }
+ MmioAndThenOr32 (
+ RootDeviceBase + RootL1SubstateExtCapOffset + 0x08,
+ (UINT32) ~(BIT4 | BIT3 | BIT2 | BIT1 | BIT0),
+ Data32Or
+ );
+ }
+
+
+ if ((AspmVal & V_PCH_PCIE_LCTL_APMC_L1) == V_PCH_PCIE_LCTL_APMC_L1) {
+ ///
+ /// Program D28:F0~F5:E2h[5:4] to 11b prior to enabling ASPM L1,
+ /// if all enabled ports support ASPM L1
+ ///
+ if (FirstRPToSetPm && L1SupportedInAllEnabledPorts) {
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigRead,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ Data32 |= ((B_PCH_PCIE_RPPGEN_LMSDOCGE | B_PCH_PCIE_RPPGEN_SEOCGE) << 16);
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigWrite,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ if (ClkreqPerPortSupported) {
+ ///
+ /// Program D28:F0~F5:420h[17] to 0b prior to enabling ASPM L1
+ ///
+ if (*L1SubstatesSupported) {
+ MmioAnd32 (RootDeviceBase + R_PCH_PCIE_PCIEPMECTL, (UINT32)~B_PCH_PCIE_PCIEPMECTL_L1LE);
+ }
+
+ ///
+ /// Program D28:F0~F5:420h[29] to 1b, when D28:F0:E1h[6] is set to 1b
+ ///
+ Data32Or = B_PCH_PCIE_PCIEPMECTL_DLSULDLSD;
+ MmioOr32 (
+ RootDeviceBase + R_PCH_PCIE_PCIEPMECTL,
+ Data32Or
+ );
+
+ ///
+ /// If dedicated CLKREQ# per-port is supported on all enabled ports, set D28:F0:E1h[6] to 1b prior to enabling ASPM L1
+ ///
+ if (FirstRPToSetPm && ClkreqSupportedInAllEnabledPorts) {
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigRead,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ Data32 |= (B_PCH_PCIE_RPDCGEN_POCGE << 8);
+ Status = PchIobpExecution (
+ RootComplexBar,
+ 0xE00000E0,
+ PciConfigWrite,
+ 0xE0 + GetPchPcieRpfn( RootComplexBar, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1),
+ &Data32,
+ &Response
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+ }
+ }
+#endif // ULT_FLAG
+ ///
+ /// Set Root Port Aspm and enable LTR capability of the device
+ ///
+ MmioAndThenOr16 (RootDeviceBase + RootPcieCapOffset + 0x010, 0xFFFC, AspmVal);
+ ///
+ /// Based on the Role based Error Reporting Capability bit, for pre-1.1 devices,
+ /// program root port 0xD4[4] to 1 and 0xD4[3:2] to 10.
+ ///
+ if (AspmOverride) {
+ MmioAndThenOr8 (RootDeviceBase + R_PCH_PCIE_MPC2,
+ (UINT8)~(B_PCH_PCIE_MPC2_ASPMCOEN | B_PCH_PCIE_MPC2_ASPMCO),
+ (B_PCH_PCIE_MPC2_ASPMCOEN | V_PCH_PCIE_MPC2_ASPMCO_L1)
+ );
+ } else {
+ MmioAnd8 (RootDeviceBase + R_PCH_PCIE_MPC2, (UINT8)~(B_PCH_PCIE_MPC2_ASPMCOEN | B_PCH_PCIE_MPC2_ASPMCO));
+ }
+ ///
+ /// PCH BIOS Spec Rev 0.5.5, Section 8.14.1 Power Optimizer Configuration
+ /// Step 1
+ /// Enable support Latency Tolerance Reporting (LTR)
+ ///
+
+ if (EndPointBus != 0 && (SlotStatus & BIT6) != 0) {
+ ///
+ /// Set Endpoint Aspm and LTR capabilities
+ ///
+ Status = PcieEndPointPm (
+ RootDeviceBase,
+ RootPcieCapOffset,
+ EndPointBus,
+ NumOfDevAspmOverride,
+ DevAspmOverride,
+ &AspmVal,
+ SetAspm,
+ NumOfDevLtrOverride,
+ DevLtrOverride,
+ &LtrOvrVal,
+ RootL1SubstateExtCapOffset,
+ L1SubstatesSupported,
+ L1SubstatesConfig,
+ &PortCommonModeRestoreTime,
+ &PortTpowerOnValue,
+ &PortTpowerOnScale,
+ PchPwrOptPcie,
+ &AspmOverride,
+ &ClkreqPerPortSupported,
+ LtrSupported,
+ PolicyRevision
+ );
+ }
+
+ if (BusAssign == FALSE) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RootDeviceBase + 0x018, 0xFF0000FF);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// If L0s and L1 can be enabled on a root port and the endpoints attached to the root port,
+ /// then set the root port register D28:Fx:Reg E8h[1]
+ ///
+ if (AspmVal == V_PCH_PCIE_LCTL_APMC_L0S_L1) {
+ if (PchSeries == PchLp) {
+ ///
+ /// Set the root port register D28:Fx:REG E8h[3:2] to 10b before setting D28:Fx:Reg E8h[0] or E8h[1]
+ ///
+ Data8Or = BIT3;
+ Data8And = (UINT8) ~(V_PCH_PCIE_PECR1_FIELD_3);
+ MmioAndThenOr8 (
+ RootDeviceBase + R_PCH_PCIE_PECR1,
+ Data8And,
+ Data8Or
+ );
+ }
+ MmioOr8 (RootDeviceBase + R_PCH_PCIE_PECR1, B_PCH_PCIE_PECR1_FIELD_2);
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Initializes the root port and its down stream devices
+
+ @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
+ @param[in, out] MaxPayload The Max Payolad Size of the root port
+ @param[out] DeviceClassDword Get the downstream device code dword for unstream RootPort reference
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device.
+**/
+EFI_STATUS
+PchPcieInitDownstreamDevices (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ IN OUT UINT16 *MaxPayload,
+ OUT UINT32 *DeviceClassDword
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN RPBase;
+ UINTN EndPointBase;
+
+ RPBase = MmPciAddress (0, RootPortBus, RootPortDevice, RootPortFunc, 0);
+ ///
+ /// Temporarily Hardcode the Root Port Bridge Number to TempBusNumberMin
+ ///
+ MmioAndThenOr32 (
+ RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+ 0xFF000000,
+ RootPortBus | ((UINT32) (TempBusNumberMin << 8)) | ((UINT32) (TempBusNumberMax << 16))
+ );
+ ///
+ /// This Endpoint check should immediately pass. Howerver, a 1.0s delay
+ /// has been added to match the timing requirements of the PCI Express Base
+ /// Specification, Revision 1.0A, Section 6.6 ("...software must allow 1.0s
+ /// after a reset of a device, before it may determine that a device which
+ /// fails to return a Successful Completion status for a valid Configuration
+ /// Request is a broken device").
+ ///
+ EndPointBase = MmPciAddress (0, TempBusNumberMin, 0, 0, 0);
+ ///
+ /// A config write is required in order for the device to re-capture the Bus number,
+ /// according to PCI Express Base Specification, 2.2.6.2 ("Note that the Bus Number
+ /// and Device Number may be changed at run time, and so it is necessary to re-capture
+ /// this information with each and every Configuration Write Request")
+ ///
+ MmioWrite8 (EndPointBase + 0x0, 0);
+ for (Index = 0; Index < 100000; Index++) {
+ if (MmioRead16 (EndPointBase + PCI_VENDOR_ID_OFFSET) != 0xFFFF) {
+ break;
+ }
+
+ PchPmTimerStall (10);
+ }
+
+ if (Index >= 100000) {
+ ///
+ /// Clear Bus Numbers.
+ ///
+ MmioAnd32 (RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Get the device class code dword for upstream RootPort reference
+ ///
+ if (DeviceClassDword != NULL) {
+ *DeviceClassDword = MmioRead32 (EndPointBase + R_PCH_PCIE_RID);
+ }
+ ///
+ /// Get the Max Payload Size on all the end point functions
+ ///
+ PcieMaxPayloadSize (TempBusNumberMin, PCI_MAX_DEVICE, MaxPayload, FALSE);
+ ///
+ /// Check if this device is a bridge
+ ///
+ if (MmioRead8 (EndPointBase + R_PCH_PCIE_BCC) == PCI_CLASS_BRIDGE) {
+ ///
+ /// Initialize downstream devices
+ ///
+ if (TempBusNumberMax > TempBusNumberMin) {
+ Status = PchPcieInitDownstreamDevices (
+ TempBusNumberMin,
+ 0,
+ 0,
+ TempBusNumberMin + 1,
+ TempBusNumberMax,
+ MaxPayload,
+ NULL
+ );
+ }
+ }
+ ///
+ /// Complete Common Port and Endpoint Configuration.
+ ///
+ ///
+ /// Map TC0-VC0
+ ///
+ PcieMapTcxVc0 (RootPortBus, RootPortDevice, (UINT8) RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE, 0x0);
+
+ ///
+ /// Set Common Clock for inserted cards
+ ///
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 8.3.1 ASPM on DMI and the PCI Express* Root Ports
+ /// Before determining whether ASPM can be enabled or not,
+ /// the System BIOS must perform the following steps:
+ ///
+ /// For PCH H
+ /// 1. Update the Link Capabilities of the DMI to indicate L1 is
+ /// supported on the interface by setting the LCAP Register
+ /// RCBA + 21A4h [11:10] = 11b
+ /// (Done in PchPm.c)
+ ///
+ /// 2. Enable L0s on DMI for Desktop platforms by setting the APMC field,
+ /// RCBA + offset 21A8h[1:0] to 01b.
+ /// Enable L0s/L1 on DMI by setting RCBA + offset 21A8h[1:0] to 11b.
+ /// (Done in PchPm.c)
+ ///
+ /// 3. For each root port, read the Slot Clock Configuration bit, D28:F0~F7:Reg 52h[12],
+ /// of the root port and the endpoint device connected to the port (i.e., D0:F0 on the
+ /// secondary bus behind the root port). If both components have this bit set, then the
+ /// System BIOS should set the Common Clock Configuration (CCC) bit, D28:F0~F7:Reg 50h[6],
+ /// for both components at both sides of the link to indicate that components at both ends
+ /// of the link use a common clock source.
+ ///
+ /// 4. If the CCC bit was changed by the System BIOS in step 3, System BIOS should initiate
+ /// a link training by setting the Retrain Link (RL) bit, D28:F0~F7:Reg 50h[5], and then poll the Link
+ /// Training (LT) bit, D28:F0~F7:Reg 52h[11], until it is clear.
+ /// Note that System BIOS should save and restore CCC bit on S3.
+ ///
+ PcieSetCommonClock (RootPortBus, RootPortDevice, (UINT8) RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE);
+
+ ///
+ /// Enable the PCIe CLKREQ#
+ ///
+ PcieSetClkreq (TempBusNumberMin, PCI_MAX_DEVICE, (UINT8) RootPortFunc);
+
+ ///
+ /// Set the Max Payload Size on all the end point functions
+ ///
+ PcieMaxPayloadSize (TempBusNumberMin, PCI_MAX_DEVICE, MaxPayload, TRUE);
+
+ ///
+ /// Disable the forwarding of EOI messages unless it discovers an IOAPIC behind this root port
+ ///
+ PcieSetEoiFwdDisable (RootPortBus, RootPortDevice, RootPortFunc, TempBusNumberMin, PCI_MAX_DEVICE);
+ ///
+ /// Clear Bus Numbers
+ ///
+ MmioAnd32 (RPBase + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET, 0xFF000000);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes the root port and its down stream devices
+
+ @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
+ @param[out] DeviceClassDword Get the downstream device code dword for unstream RootPort reference
+
+ @retval EFI_SUCCESS Successfully completed
+ @retval EFI_NOT_FOUND Can not find device.
+**/
+EFI_STATUS
+PchPcieInitRootPortDownstreamDevices (
+ IN UINT8 RootPortBus,
+ IN UINT8 RootPortDevice,
+ IN UINT8 RootPortFunc,
+ IN UINT8 TempBusNumberMin,
+ IN UINT8 TempBusNumberMax,
+ OUT UINT32 *DeviceClassDword
+ )
+{
+ UINT16 SlotStatus;
+ UINTN RPBase;
+ UINT16 RootPortMaxPayload;
+ UINT8 PcieCapOffset;
+ EFI_STATUS Status;
+
+ RPBase = MmPciAddress (0, RootPortBus, RootPortDevice, RootPortFunc, 0);
+ ///
+ /// Check for a Presence Detect Change.
+ ///
+ SlotStatus = MmioRead16 (RPBase + R_PCH_PCIE_SLSTS);
+
+ ///
+ /// Check whether the slot has a device connected
+ ///
+ if ((SlotStatus & BIT6) == 0) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Get the pointer to the Endpoint PCI Express Capability Structure.
+ ///
+ PcieCapOffset = PcieFindCapId (
+ RootPortBus,
+ RootPortDevice,
+ RootPortFunc,
+ EFI_PCI_CAPABILITY_ID_PCIEXP
+ );
+
+ ///
+ /// Get the root port Max Payload Size support
+ ///
+ RootPortMaxPayload = MmioRead16 (RPBase + PcieCapOffset + 0x04) & (BIT2 | BIT1 | BIT0);
+
+ ///
+ /// Initialize downstream devices
+ ///
+ Status = PchPcieInitDownstreamDevices (
+ RootPortBus,
+ RootPortDevice,
+ RootPortFunc,
+ TempBusNumberMin,
+ TempBusNumberMax,
+ &RootPortMaxPayload,
+ DeviceClassDword
+ );
+
+ ///
+ /// Set the PCIE root Port Max Payload Size
+ ///
+ MmioAndThenOr16 (RPBase + PcieCapOffset + 0x08, (UINT16)~(BIT7 | BIT6 | BIT5), RootPortMaxPayload << 5);
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
new file mode 100644
index 0000000..7f32fe0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPciExpressHelpersLib/PchPciExpressHelpersLibrary.h
@@ -0,0 +1,42 @@
+/** @file
+ Header file for PCH Pci Express helps library implementation.
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+#ifndef _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+#define _PCH_PCI_EXPRESS_HELPERS_LIBRARY_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "PchPlatformPolicy.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchPciExpressHelperslib.h"
+#include "pci23.h"
+#include "pci22.h"
+#endif
+
+#define LTR_VALUE_MASK (BIT0 + BIT1 + BIT2 + BIT3 + BIT4 + BIT5 + BIT6 + BIT7 + BIT8 + BIT9)
+#define LTR_SCALE_MASK (BIT10 + BIT11 + BIT12)
+
+//
+// LTR related macros
+//
+#define LTR_LATENCY_VALUE(x) ((x) & LTR_VALUE_MASK)
+#define LTR_SCALE_VALUE(x) (((x) & LTR_SCALE_MASK) >> 10)
+#define LTR_LATENCY_NS(x) (LTR_LATENCY_VALUE(x) * (1 << (5 * LTR_SCALE_VALUE(x))))
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c
new file mode 100644
index 0000000..d21a181
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/IobpAccess.c
@@ -0,0 +1,295 @@
+/** @file
+ Program IOBP register.
+
+@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 "PchPlatformLibrary.h"
+
+/**
+ Configures PCH IOBP
+
+ @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 Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ProgramIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN UINT32 AndMask,
+ IN UINT32 OrMask
+ )
+{
+ UINT32 Data32;
+ UINT8 ResponseStatus;
+ EFI_STATUS Status;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 7.1.4 IOSF SBI Programming
+ /// Step 1 to Step 8
+ ///
+ Status = ReadIobp (RootComplexBar, Address, &Data32);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Step 9
+ /// Update the SBI data accordingly
+ ///
+ Data32 &= AndMask;
+ Data32 |= OrMask;
+ ///
+ /// Step 10
+ /// Set RCBA + 2338h[15:8] = 00000111b
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_W
+ );
+ ///
+ /// Step 11
+ /// Write RCBA + 2334h[31:0] with updated SBI data
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), Data32);
+
+ ///
+ /// Step 12
+ /// Set RCBA + 233Ah[15:0] = F000h
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ 0xF000
+ );
+
+ ///
+ /// Step 13
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 14
+ /// Poll RCBA + Offset 2338h[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 15
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Read data from PCH IOBP register block
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[out] Data Data contain in the IOBP register block
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+ReadIobp (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ OUT UINT32 *Data
+ )
+{
+ UINT8 ResponseStatus;
+
+ ///
+ /// Step 1 Poll RCBA + 2338[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 2
+ /// Write RCBA + Offset 2330h[31:0] with IOBP register address
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address);
+ ///
+ /// Step 3
+ /// Set RCBA + 2338h[15:8] = 00000110b
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) V_PCH_RCRB_IOBPS_IOBPIA_R
+ );
+ ///
+ /// Step 4
+ /// Set RCBA + 233Ah[15:0] = F000h
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ 0xF000
+ );
+ ///
+ /// Step 5
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 6
+ /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 7
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ ResponseStatus = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (ResponseStatus == V_PCH_RCRB_IOBPS_SUCCESS) {
+ ///
+ /// Step 8
+ /// Read RCBA + 2334h[31:0] for IOBP data
+ ///
+ *Data = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD);
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+}
+
+/**
+ Configures PCH IOBP
+
+ @param[in] RootComplexBar RootComplexBar value of this PCH device
+ @param[in] Address Address of the IOBP register block
+ @param[in] Opcode Iobp Opcode
+ @param[in] RouteId Route Id
+ @param[in, out] Data32 Read/Write data
+ @param[out] Response Response
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_DEVICE_ERROR Transaction fail
+**/
+EFI_STATUS
+EFIAPI
+PchIobpExecution (
+ IN UINT32 RootComplexBar,
+ IN UINT32 Address,
+ IN PCH_IOBP_OPCODE Opcode,
+ IN UINT8 RouteId,
+ IN OUT UINT32 *Data32,
+ OUT UINT8 *Response
+ )
+{
+ ///
+ /// Step 1 Poll RCBA + 2338[0] = 0b
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+ ///
+ /// Step 2
+ /// Write RCBA + Offset 2330h[31:0] with IOBP register address
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPIRI), Address);
+ ///
+ /// Step 3
+ /// Set RCBA + 2338h[15:8] to the opcode passed in
+ ///
+ MmioAndThenOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) (~B_PCH_RCRB_IOBPS_IOBPIA),
+ (UINT16) (Opcode << 8)
+ );
+ ///
+ /// Step 4
+ /// Set RCBA + 233Ah[15:8] = F0h
+ /// Set RCBA + 233Ah[7:0] = Route Id passed in
+ ///
+ MmioWrite16 (
+ (RootComplexBar + 0x233A),
+ (0xF000 | RouteId)
+ );
+ switch (Opcode) {
+ case MemoryMapWrite:
+ case IoMapWrite:
+ case PciConfigWrite:
+ case PrivateControlWrite:
+ ///
+ /// Step 5
+ /// Write RCBA + 2334h[31:0] with updated SBI data
+ ///
+ MmioWrite32 ((RootComplexBar + R_PCH_RCRB_IOBPD), *Data32);
+ break;
+ default:
+ break;
+ }
+ ///
+ /// Step 6
+ /// Set RCBA + 2338h[0] = 1b
+ ///
+ MmioOr16 (
+ (RootComplexBar + R_PCH_RCRB_IOBPS),
+ (UINT16) BIT0
+ );
+
+ ///
+ /// Step 7
+ /// Poll RCBA + Offset 2338h[0] = 0b, Polling for Busy bit
+ ///
+ while (MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS_BUSY);
+
+ ///
+ /// Step 8
+ /// Check if RCBA + 2338h[2:1] = 00b for successful transaction
+ ///
+ *Response = MmioRead8 (RootComplexBar + R_PCH_RCRB_IOBPS) & B_PCH_RCRB_IOBPS;
+ if (*Response == V_PCH_RCRB_IOBPS_SUCCESS) {
+ switch (Opcode) {
+ case MemoryMapRead:
+ case IoMapRead:
+ case PciConfigRead:
+ case PrivateControlRead:
+ ///
+ /// Step 9
+ /// Read RCBA + 2334h[31:0] for IOBP data
+ ///
+ *Data32 = MmioRead32 (RootComplexBar + R_PCH_RCRB_IOBPD);
+ break;
+ default:
+ break;
+ }
+
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif
new file mode 100644
index 0000000..d146e3b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchPlatformLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchPlatformLib"
+ RefName = "PchPlatformLib"
+[files]
+"PchPlatformLib.mak"
+"PchPlatformLib.sdl"
+"PchPlatformLibrary.h"
+"PchPlatformLibrary.c"
+"PchPlatformLib.inf"
+"IobpAccess.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf
new file mode 100644
index 0000000..2aa9a25
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for PEI/DXE PCH Platform Lib
+#
+#@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
+#
+
+
+[defines]
+BASE_NAME = PchPlatformLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ PchPlatformLibrary.h
+ PchPlatformLibrary.c
+ IobpAccess.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.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
+#
+# 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]
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueBaseLib
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak
new file mode 100644
index 0000000..d6ca967
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.mak
@@ -0,0 +1,112 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchPlatformLib/PchPlatformLib.mak 3 10/16/12 2:52a Scottyang $
+#
+# $Revision: 3 $
+#
+# $Date: 10/16/12 2:52a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.mak $
+#
+# 3 10/16/12 2:52a Scottyang
+# [TAG] EIP103924
+# [Category] Improvement
+# [Description] Update RC 0.7.1
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 2 7/02/12 9:17a Victortu
+#
+# 1 2/08/12 8:48a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:PchPlatformLib
+EDK : PchPlatformLib
+
+PchPlatformLib : PchPlatformSmmLib PchPlatformDxeLib PchPlatformPeiLib
+
+$(PchPlatformSmmLib_LIB) : PchPlatformSmmLib
+$(PchPlatformDxeLib_LIB) : PchPlatformDxeLib
+$(PchPlatformPeiLib_LIB) : PchPlatformPeiLib
+
+PchPlatformSmmLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibSmmBin
+
+PchPlatformDxeLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibDxeBin
+
+PchPlatformPeiLib : $(BUILD_DIR)\PchPlatformLib.mak PchPlatformLibPeiBin
+
+$(BUILD_DIR)\PchPlatformLib.mak : $(PchPlatformLib_DIR)\$(@B).cif $(PchPlatformLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchPlatformLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchPlatformLib_INCLUDES =\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(EDK_INCLUDES)\
+
+PchPlatformLib_LIBS=\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+
+PchPlatformLibSmmBin : $(PchPlatformLib_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \
+ TYPE=LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformSmmLib_LIB)
+
+PchPlatformLibDxeBin : $(PchPlatformLib_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)" \
+ "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformDxeLib_LIB)
+
+PchPlatformLibPeiBin : $(PchPlatformLib_LIBS)
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+!ENDIF
+ /f $(BUILD_DIR)\PchPlatformLib.mak all\
+ "MY_INCLUDES=$(PchPlatformLib_INCLUDES)"\
+ "CFLAGS=$(CFLAGS) $(PchPlatformLib_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARIES=\
+ LIBRARY_NAME=$(PchPlatformPeiLib_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/Library/PchPlatformLib/PchPlatformLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl
new file mode 100644
index 0000000..4704a8c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLib.sdl
@@ -0,0 +1,93 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchPlatformLib/PchPlatformLib.sdl 1 2/08/12 8:48a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:48a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchPlatformLib/PchPlatformLib.sdl $
+#
+# 1 2/08/12 8:48a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchPlatformLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchPlatformLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchPlatformLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchPlatformLib.mak to Project"
+ File = "PchPlatformLib.mak"
+End
+
+ELINK
+ Name = "PchPlatformSmmLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformSmmLib.lib"
+ Parent = "PchPlatformSmmLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPlatformDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformDxeLib.lib"
+ Parent = "PchPlatformDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchPlatformPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPlatformPeiLib.lib"
+ Parent = "PchPlatformPeiLib_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/Library/PchPlatformLib/PchPlatformLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c
new file mode 100644
index 0000000..2d9c6ac
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.c
@@ -0,0 +1,831 @@
+/** @file
+ PCH Platform Lib implementation.
+@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 "PchPlatformLibrary.h"
+
+/**
+ Delay for at least the request number of microseconds.
+ This function would be called by runtime driver, please do not use any MMIO marco here.
+
+ @param[in] Microseconds Number of microseconds to delay.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchPmTimerStall (
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINTN CurrentTick;
+ UINTN OriginalTick;
+ UINTN RemainingTick;
+ UINT16 AcpiBaseAddr;
+
+ if (Microseconds == 0) {
+ return;
+ }
+ ///
+ /// Please use PciRead here, it will link to MmioRead
+ /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer
+ /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details.
+ /// For the rest please use EdkIIGlueBasePciLibPciExpress library
+ ///
+ AcpiBaseAddr = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ OriginalTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ CurrentTick = OriginalTick;
+
+ ///
+ /// The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ ///
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+
+ ///
+ /// The loops needed by timer overflow
+ ///
+ Counts = Ticks / V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ ///
+ /// Remaining clocks within one loop
+ ///
+ RemainingTick = Ticks % V_PCH_ACPI_PM1_TMR_MAX_VAL;
+
+ ///
+ /// not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ /// one I/O operation, and maybe generate SMI
+ ///
+ while ((Counts != 0) || (RemainingTick > CurrentTick)) {
+ CurrentTick = IoRead32 ((UINTN) (AcpiBaseAddr + R_PCH_ACPI_PM1_TMR)) & B_PCH_ACPI_PM1_TMR_VAL;
+ ///
+ /// Check if timer overflow
+ ///
+ if ((CurrentTick < OriginalTick)) {
+ if (Counts != 0) {
+ Counts--;
+ } else {
+ ///
+ /// If timer overflow and Counts equ to 0, that means we already stalled more than
+ /// RemainingTick, break the loop here
+ ///
+ break;
+ }
+ }
+
+ OriginalTick = CurrentTick;
+ }
+}
+
+/**
+ Check whether SPI is in descriptor mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE SPI is in descriptor mode
+ @retval FALSE SPI is not in descriptor mode
+**/
+BOOLEAN
+EFIAPI
+PchIsSpiDescriptorMode (
+ IN UINTN PchRootComplexBar
+ )
+{
+ if ((MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FDV) == B_PCH_SPI_HSFS_FDV) {
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)),
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_FSDM | R_PCH_SPI_FDBAR_FLVALSIG)
+ );
+ if ((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FDOD)) == V_PCH_SPI_FDBAR_FLVALSIG) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Return Pch stepping type
+
+ @param[in] None
+
+ @retval PCH_STEPPING Pch stepping type
+**/
+PCH_STEPPING
+EFIAPI
+PchStepping (
+ VOID
+ )
+{
+ UINT8 RevId;
+ UINT16 LpcDeviceId;
+
+ RevId = MmioRead8 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_RID)
+ );
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) {
+ switch (RevId) {
+ case V_PCH_LPT_LPC_RID_2:
+ return LptHB0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_3:
+ return LptHC0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_4:
+ return LptHC1;
+ break;
+
+ case V_PCH_LPT_LPC_RID_5:
+ return LptHC2;
+ break;
+
+ default:
+ return PchSteppingMax;
+ break;
+ }
+ }
+
+ if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) {
+ switch (RevId) {
+ case V_PCH_LPT_LPC_RID_2:
+ return LptLpB0;
+ break;
+
+ case V_PCH_LPT_LPC_RID_3:
+ return LptLpB1;
+ break;
+
+ case V_PCH_LPT_LPC_RID_4:
+ return LptLpB2;
+ break;
+
+ default:
+ return PchSteppingMax;
+ break;
+ }
+ }
+
+ return PchSteppingMax;
+}
+
+/**
+ Determine if PCH is supported
+
+ @param[in] None
+
+ @retval TRUE PCH is supported
+ @retval FALSE PCH is not supported
+**/
+BOOLEAN
+IsPchSupported (
+ VOID
+ )
+{
+ UINT16 LpcDeviceId;
+
+ LpcDeviceId = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ ///
+ /// Verify that this is a supported chipset
+ ///
+ if (MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_VENDOR_ID)
+ ) != V_PCH_LPC_VENDOR_ID ||
+ !IS_PCH_LPT_LPC_DEVICE_ID (LpcDeviceId)) {
+ DEBUG ((EFI_D_ERROR, "PCH code doesn't support the LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/**
+ This function can be called to enable/disable Alternate Access Mode
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+ @param[in] AmeCtrl If TRUE, enable Alternate Access Mode.
+ If FALSE, disable Alternate Access Mode.
+
+ @retval NONE
+**/
+VOID
+EFIAPI
+PchAlternateAccessMode (
+ IN UINTN PchRootComplexBar,
+ IN BOOLEAN AmeCtrl
+ )
+{
+ UINT32 Data32Or;
+ UINT32 Data32And;
+
+ Data32Or = 0;
+ Data32And = 0xFFFFFFFF;
+
+ if (AmeCtrl == TRUE) {
+ ///
+ /// 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.
+ ///
+ Data32Or = (UINT32) (B_PCH_RCRB_GCS_AME);
+ }
+
+ if (AmeCtrl == FALSE) {
+ ///
+ /// Disable Alternate Access Mode
+ ///
+ Data32And = (UINT32) ~(B_PCH_RCRB_GCS_AME);
+ }
+
+ ///
+ /// Program Alternate Access Mode Enable bit
+ ///
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_RCRB_GCS,
+ Data32And,
+ Data32Or
+ );
+
+ ///
+ /// Reads back for posted write to take effect
+ ///
+ MmioRead32(PchRootComplexBar + R_PCH_RCRB_GCS);
+}
+
+/**
+ Check whether Gbe Region is valid in SPI Flash
+
+ @param[in] PchRootComplexBar The PCH Root Complex Bar
+
+ @retval TRUE Gbe Region is valid
+ @retval FALSE Gbe Region is invalid
+**/
+BOOLEAN
+EFIAPI
+PchIsGbeRegionValid (
+ IN UINTN PchRootComplexBar
+ )
+{
+ ///
+ /// If the GbE region is not used,
+ /// Region Limit of Flash Region 3 (GbE) Register (SPIBAR + 60h[30:16]) must be programmed to 0000h
+ /// Region Base of Flash Region 3 (GbE) Register (SPIBAR + 60h[14:0] ) must be programmed to 7FFFh
+ ///
+ if (PchIsSpiDescriptorMode (PchRootComplexBar) == TRUE) {
+ if (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG3_GBE) == 0x00007FFF) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Check if integrated Gbe controller present
+
+ @param[in] None
+
+ @retval TRUE Integrated Gbe present
+ @retval FALSE Integrated Gbe not present
+**/
+BOOLEAN
+EFIAPI
+PchIsIntegratedGbePresent (
+ IN VOID
+ )
+{
+ UINT32 Softstrap4;
+ UINT32 Softstrap15;
+ BOOLEAN IntegratedGbe;
+
+ ///
+ /// Check if Gbe region is present by reading PCH straps 15 (bit 6) and 4 (bits 1:0)
+ ///
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP4)
+ );
+
+ Softstrap4 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP15)
+ );
+
+ Softstrap15 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ ///
+ /// Both values have to be non-zero if integrated phy present
+ ///
+ IntegratedGbe = !!(Softstrap4 & B_PCH_SPI_STRP4_PHYCON) && !!(Softstrap15 & B_PCH_SPI_STRP15_IWL_EN);
+
+ return IntegratedGbe;
+}
+
+/**
+ Return Pch Series
+
+ @param[in] None
+
+ @retval PCH_SERIES Pch Series
+**/
+PCH_SERIES
+EFIAPI
+GetPchSeries (
+ VOID
+ )
+{
+ UINT16 LpcDeviceId;
+ UINT32 PchSeries;
+
+ ///
+ /// Please use PciRead here, it will link to MmioRead
+ /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer
+ /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details.
+ /// For the rest please use EdkIIGlueBasePciLibPciExpress library
+ ///
+ LpcDeviceId = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_DEVICE_ID)
+ );
+
+ if (IS_PCH_LPTH_LPC_DEVICE_ID (LpcDeviceId)) {
+ PchSeries = PchH;
+ } else if (IS_PCH_LPTLP_LPC_DEVICE_ID (LpcDeviceId)) {
+ PchSeries = PchLp;
+ } else {
+ PchSeries = PchUnknownSeries;
+ DEBUG ((EFI_D_ERROR, "Unsupported PCH SKU, LpcDeviceId: 0x%04x!\n", LpcDeviceId));
+ ASSERT (FALSE);
+ }
+
+ return PchSeries;
+}
+
+/**
+ Get Pch Maximum Pcie Root Port Number
+
+ @param[in] None
+
+ @retval Pch Maximum Pcie Root Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxPciePortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_PCIE_MAX_ROOT_PORTS;
+
+ case PchH:
+ return LPTH_PCIE_MAX_ROOT_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Sata Port Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Port Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_AHCI_MAX_PORTS;
+
+ case PchH:
+ return LPTH_AHCI_MAX_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Sata Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum Sata Controller Number
+**/
+UINT8
+EFIAPI
+GetPchMaxSataControllerNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_SATA_MAX_CONTROLLERS;
+
+ case PchH:
+ return LPTH_SATA_MAX_CONTROLLERS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb Port Number of EHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb Port Number of EHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxUsbPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_EHCI_MAX_PORTS;
+
+ case PchH:
+ return LPTH_EHCI_MAX_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum EHCI Controller Number
+
+ @param[in] None
+
+ @retval Pch Maximum EHCI Controller Number
+**/
+UINT8
+EFIAPI
+GetPchEhciMaxControllerNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_EHCI_MAX_CONTROLLERS;
+
+ case PchH:
+ return LPTH_EHCI_MAX_CONTROLLERS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Usb Maximum Physical Port Number
+
+ @param[in] None
+
+ @retval Pch Usb Maximum Physical Port Number
+**/
+UINT8
+EFIAPI
+GetPchUsbMaxPhysicalPortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_USB_MAX_PHYSICAL_PORTS;
+
+ case PchH:
+ return LPTH_USB_MAX_PHYSICAL_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb2 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb2 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb2PortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_XHCI_MAX_USB2_PORTS;
+
+ case PchH:
+ return LPTH_XHCI_MAX_USB2_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Get Pch Maximum Usb3 Port Number of XHCI Controller
+
+ @param[in] None
+
+ @retval Pch Maximum Usb3 Port Number of XHCI Controller
+**/
+UINT8
+EFIAPI
+GetPchXhciMaxUsb3PortNum (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ switch (PchSeries) {
+ case PchLp:
+ return LPTLP_XHCI_MAX_USB3_PORTS;
+
+ case PchH:
+ return LPTH_XHCI_MAX_USB3_PORTS;
+
+ default:
+ return 0;
+ }
+}
+
+/**
+ Query PCH to determine the Pm Status
+
+ @param[in] PmStatus - The Pch Pm Status to be probed
+
+ @retval Return TRUE if Status querried is Valid or FALSE if otherwise
+**/
+BOOLEAN
+GetPchPmStatus (
+ PCH_PM_STATUS PmStatus
+ )
+{
+ UINT16 PmCon2;
+ UINT16 PmCon3;
+
+ PmCon2 = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_2
+ )
+ );
+ PmCon3 = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_3
+ )
+ );
+
+ switch(PmStatus){
+ case WarmBoot:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlr:
+ if (PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlrSys:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case PwrFlrPch:
+ if (PmCon2 & B_PCH_LPC_GEN_PMCON_PWROK_FLR) {
+ return TRUE;
+ }
+ break;
+
+ case ColdBoot:
+ ///
+ /// Check following conditions for cold boot.
+ /// (1)GEN_PMCON_2 (0:31:0 offset 0A2) bit[5] = 0
+ /// (2)GEN_PMCON_2 (0:31:0 offset 0A2) bit[1] = 1
+ /// (3)GEN_PMCON_3 (0:31:0 offset 0A4) bit[1] = 1
+ ///
+ if ((PmCon3 & B_PCH_LPC_GEN_PMCON_PWR_FLR) &&
+ (PmCon2 & B_PCH_LPC_GEN_PMCON_SYSPWR_FLR) &&
+ (!(PmCon2 & B_PCH_LPC_GEN_PMCON_MEM_SR))) {
+ return TRUE;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+}
+
+/**
+ Get Pch Pcie Root Port Function Number by Root Port Number
+
+ @param[in] UINT8 Root Port Number (start from 0)
+
+ @retval Pch Pcie Root Port Function Number
+**/
+UINT8
+EFIAPI
+GetPchPcieRpfn (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 RpNumber
+ )
+{
+ return ((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (RpNumber * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN);
+}
+
+/**
+ Get Pch Pcie Root Port Number by Root Port Function Number
+
+ @param[in] UINT8 Root Port Function Number
+
+ @retval Pch Pcie Root Port Number
+ @retval 0xFF No Root Port Number found
+**/
+UINT8
+EFIAPI
+GetPchPcieRpNumber (
+ IN UINTN PchRootComplexBar,
+ IN UINT8 Rpfn
+ )
+{
+ UINT8 PortIndex;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum(); PortIndex++) {
+ if (((MmioRead32(PchRootComplexBar + R_PCH_RCRB_RPFN) >> (PortIndex * S_PCH_RCRB_PRFN_RP_FIELD)) & B_PCH_RCRB_RPFN_RP1FN) == Rpfn) {
+ return PortIndex;
+ }
+ }
+
+ //Assert if function number not found for a root port
+ ASSERT (FALSE);
+ return 0xff;
+}
+
+
+/**
+ Returns GbE over PCIe port number.
+
+ @return Root port number (0-based)
+ @retval 0xff
+**/
+UINTN
+PchGetGbePortNumber (
+ VOID
+ )
+{
+ UINT32 Softstrap9;
+ UINT32 GbePortSel;
+
+ ///
+ /// Check if Intel PHY Over PCI Express Enable by reading PCH straps 9 (bit 11)
+ ///
+ MmioAnd32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK))
+ );
+
+ MmioOr32 (
+ PCH_RCRB_BASE + R_PCH_SPI_FDOC,
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_PCHS | R_PCH_SPI_STRP9)
+ );
+
+ Softstrap9 = MmioRead32 (PCH_RCRB_BASE + R_PCH_SPI_FDOD);
+
+ ///
+ /// If Intel PHY Over PCI Express Enable bit is set, return GbE port number
+ ///
+ if (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_EN) {
+ GbePortSel = (Softstrap9 & B_PCH_SPI_STRP9_GBE_PCIE_PSC) >> N_PCH_SPI_STRP9_GBE_PCIE_PSC;
+ DEBUG ((EFI_D_INFO, "GbePortSel=%d\n", GbePortSel));
+ if (GetPchSeries () == PchLp) {
+ switch (GbePortSel) {
+ case 0: return 2; // Root Port 3
+ case 1: return 3; // Root Port 4
+ case 2: // Root Port 5, lane 0
+ case 3: // Root Port 5, lane 1
+ case 4: // Root Port 5, lane 2
+ case 5: // Root Port 5, lane 3
+ return 4;
+ default:
+ ASSERT (FALSE);
+ }
+ } else {
+ return GbePortSel;
+ }
+ }
+
+ return 0xff;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h
new file mode 100644
index 0000000..0eec474
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchPlatformLib/PchPlatformLibrary.h
@@ -0,0 +1,29 @@
+/** @file
+ Header file for PCH Platform Lib implementation.
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+#ifndef _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_PLATFORM_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "Library/EdkIIGlueMemoryAllocationLib.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif
new file mode 100644
index 0000000..c6371c9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusComLib.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "PchSmbusComLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Common\"
+ RefName = "PchSmbusComLib"
+[files]
+"PchSmbusLib.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c
new file mode 100644
index 0000000..dcb46e2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Common/PchSmbusLib.c
@@ -0,0 +1,54 @@
+/** @file
+ This file contains routines that support PCH SMBUS FUNCTION
+
+@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
+**/
+#include "PchSmbusLib.h"
+
+/**
+ This function provides a standard way to execute Smbus sequential
+ I2C Read. This function allows the PCH to perform block reads to
+ certain I2C devices, such as serial E2PROMs. Typically these data
+ bytes correspond to an offset (address) within the serial memory
+ chips.
+
+ @param[in] SmBusAddress Address that encodes the SMBUS Slave Address,
+ SMBUS Command, SMBUS Data Length, and PEC.
+ @param[out] Buffer Pointer to the buffer to store the bytes read
+ from the SMBUS
+ @param[out] Status eturn status for the executed command.
+
+ @retval UINTN The number of bytes read
+**/
+UINTN
+EFIAPI
+SmBusSeqI2CRead (
+ IN UINTN SmBusAddress,
+ OUT VOID *Buffer,
+ OUT RETURN_STATUS * Status OPTIONAL
+ )
+{
+ UINTN Length;
+
+ ASSERT (Buffer != NULL);
+ ASSERT (SMBUS_LIB_LENGTH (SmBusAddress) >= 1);
+ ASSERT (SMBUS_LIB_RESEARVED (SmBusAddress) == 0);
+
+ Length = SMBUS_LIB_LENGTH (SmBusAddress);
+ return InternalSmBusExec (EfiSmbusReadByte, SmBusAddress, Length, Buffer, Status);
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif
new file mode 100644
index 0000000..b1b49b0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusDxeLib.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "PchSmbusDxeLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Dxe\"
+ RefName = "PchSmbusDxeLib"
+[files]
+"PchSmbusLib.h"
+"PchSmbusLibDxe.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h
new file mode 100644
index 0000000..64c639d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLib.h
@@ -0,0 +1,25 @@
+/** @file
+ Header file for PCH Smbus DXE Lib implementation.
+
+@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 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
+**/
+#ifndef _PCH_SMBUS_DXE_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_SMBUS_DXE_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "DxeSmbusLibInternal.h"
+#endif
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf
new file mode 100644
index 0000000..57c7e50
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Dxe/PchSmbusLibDxe.inf
@@ -0,0 +1,63 @@
+## @file
+# Component description file for DXE PCH Smbus Lib
+#
+#@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 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 = PchSmbusLibDxe
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ../Common/PchSmbusLib.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# 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/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Library/DxeSmbusLib
+#
+# 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]
+
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif
new file mode 100644
index 0000000..3263fa9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\"
+ RefName = "PchSmbusLib"
+[files]
+"PchSmbusLib.sdl"
+"PchSmbusLib.mak"
+"Common\PchSmbusComLib.cif"
+"Common\PchSmbusLib.c"
+[parts]
+"PchSmbusDxeLib"
+"PchSmbusPeiLib"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak
new file mode 100644
index 0000000..35a4d8e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.mak
@@ -0,0 +1,74 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/PchSmbusLib/PchSmbusLib.mak 1 2/08/12 8:49a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:49a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/PchSmbusLib/PchSmbusLib.mak $
+#
+# 1 2/08/12 8:49a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchSmbusLib
+
+$(PchSmbusLib_LIB) : PchSmbusLib
+
+PchSmbusLib : $(BUILD_DIR)\PchSmbusLib.mak PchSmbusLibBin
+
+$(BUILD_DIR)\PchSmbusLib.mak : $(PchSmbusLib_DIR)\$(@B).cif $(PchSmbusLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusPeiLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(EdkIIGluePeiSmbusLib_DIR)\
+ /I$(PchSmbusLib_DIR)\Pei\
+
+PchSmbusDxeLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(EdkIIGlueDxeSmbusLib_DIR)\
+ /I$(PchSmbusLib_DIR)\Dxe\
+
+PchSmbusLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusLib.mak all\
+ "MY_INCLUDES=$(PchSmbusDxeLib_INCLUDES)" \
+ TYPE=LIBRARY
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\PchSmbusLib.mak all\
+ "MY_INCLUDES=$(PchSmbusPeiLib_INCLUDES)" \
+ TYPE=PEI_LIBRARY
+!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/Library/PchSmbusLib/PchSmbusLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl
new file mode 100644
index 0000000..4f41e9a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/PchSmbusLib.sdl
@@ -0,0 +1,59 @@
+TOKEN
+ Name = "PchSmbusLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchSmbusLib.mak to Project"
+ File = "PchSmbusLib.mak"
+End
+
+ELINK
+ Name = "PchSmbusDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PchSmbusPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+TOKEN
+ Name = "PchSmbusLib_LIB"
+ Value = "$$(LIB_BUILD_DIR)\PchSmbusLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "$(PchSmbusLib_LIB)"
+ Parent = "PchSmbusDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EdkIIGlueDxeSmbusLib_LIB)"
+ Parent = "PchSmbusDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PchSmbusLib_LIB)"
+ Parent = "PchSmbusPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EdkIIGluePeiSmbusLib_LIB)"
+ Parent = "PchSmbusPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h
new file mode 100644
index 0000000..b169af6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLib.h
@@ -0,0 +1,25 @@
+/** @file
+ Header file for PCH Smbus PEI Lib implementation.
+
+@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 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
+**/
+#ifndef _PCH_SMBUS_PEI_LIBRARY_IMPLEMENTATION_H_
+#define _PCH_SMBUS_PEI_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "PeiSmbusLibInternal.h"
+#endif
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf
new file mode 100644
index 0000000..e533165
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusLibPei.inf
@@ -0,0 +1,64 @@
+## @file
+# Component description file for PEI PCH Smbus Lib
+#
+#@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 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 = PchSmbusLibPei
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ../Common/PchSmbusLib.c
+
+[sources.ia32]
+
+[sources.x64]
+
+[sources.ipf]
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# 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/Library/PeiSmbusLib
+#
+# 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]
+
+
+[nmake.common]
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif
new file mode 100644
index 0000000..22aba6f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/PchSmbusLib/Pei/PchSmbusPeiLib.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "PchSmbusPeiLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\PchSmbusLib\Pei\"
+ RefName = "PchSmbusPeiLib"
+[files]
+"PchSmbusLib.h"
+"PchSmbusLibPei.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c
new file mode 100644
index 0000000..e97d65b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/CreateFviLibrary.c
@@ -0,0 +1,225 @@
+/** @file
+ Firmware Version Info Interface Lib implementation.
+
+@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
+**/
+#include "RcFviLib.h"
+
+EFI_DATA_HUB_PROTOCOL *mDataHub = NULL;
+
+/**
+ Initialize callback context for Firmware Version Info (FVI) Interface Spec v0.7
+ implementation.
+
+ @param[in] String The pointer to the string for calculating length
+
+ @retval None
+**/
+UINT32
+GetStringLen (
+ IN UINT8 *String
+ )
+{
+ UINT8 Length;
+
+ for (Length = 0; *String != 0; String++, Length++) {
+ if (Length >= SMBIOS_STRING_MAX_LENGTH) {
+ break;
+ }
+ }
+
+ return (UINT32) (Length + 1);
+}
+
+/**
+ Initialize callback context for Firmware Version Info (FVI) Interface Spec v0.7
+ implementation.
+
+ @param[in] Type Value is defined in SMBIOS Type 14 - Group Associaction structure - item type.
+ @param[in] Count Number of elements included by this SMBIOS table
+ @param[in] FviContext Context of FVI elements for data hub log
+
+ @retval None
+**/
+VOID
+InitFviDataHubCbContext (
+ IN UINT8 Type,
+ IN UINT8 Count,
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ )
+{
+ ///
+ /// Locate the Data hub protocol
+ ///
+ if (mDataHub == NULL) {
+ gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **)&mDataHub);
+ }
+
+ if (FviContext != NULL) {
+ FviContext->FviHeader.FviHdr.Header.Type = Type;
+ FviContext->FviHeader.FviHdr.Count = Count;
+ FviContext->FviHeader.FviHdr.Header.Length = sizeof (FVI_HEADER) + FVI_ELEMENTS_SIZE_NOSTRING * Count;
+ } else {
+ ASSERT (FALSE);
+ }
+
+ return ;
+}
+
+/**
+ Create the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ to Data Hub.
+
+ @param[in] FviContext Pointer to the notification functions context, which is context of FVI
+ elements for data hub log
+
+ @retval None
+**/
+VOID
+CreateRcFviDatahub (
+ IN FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext
+ )
+{
+ VOID *Registration;
+
+ if (mDataHub == NULL) {
+ EfiCreateProtocolNotifyEvent (
+ &gEfiDataHubProtocolGuid,
+ EFI_TPL_CALLBACK,
+ DataHubCallback,
+ (VOID *) FviContext,
+ &Registration
+ );
+ } else {
+ DataHubCallback ((EFI_EVENT) NULL, (VOID *) FviContext);
+ }
+}
+
+/**
+ Publish the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ using MiscSubClass Data Hub.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification functions context, which is implementation dependent.
+
+ @retval None
+**/
+VOID
+EFIAPI
+DataHubCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ FVI_DATA_HUB_CALLBACK_CONTEXT *FviContext;
+ UINT8 Index;
+ UINT8 StrIndex;
+ UINT8 *Record;
+ UINT8 *LastRecord;
+ UINT8 *String;
+ UINT8 Count;
+ UINT32 Length;
+ FVI_ELEMENT_AND_FUNCTION *NewElement;
+
+ Status = EFI_SUCCESS;
+ if (mDataHub == NULL) {
+ Status = gBS->LocateProtocol (&gEfiDataHubProtocolGuid, NULL, (VOID **)&mDataHub);
+ }
+
+ if ((mDataHub != NULL) && (Context != NULL)) {
+
+ if (Event != NULL) {
+ gBS->CloseEvent (Event);
+ }
+
+ FviContext = (FVI_DATA_HUB_CALLBACK_CONTEXT *) Context;
+ Count = FviContext->FviHeader.FviHdr.Count;
+
+ ///
+ /// Allocate a buffer to record data sorted later
+ ///
+ Length = sizeof (MISC_SUBCLASS_FVI_HEADER) + (sizeof (FVI_ELEMENTS) * Count);
+
+ Status = EFI_OUT_OF_RESOURCES;
+ Record = (UINT8 *) AllocateZeroPool (Length);
+ if (Record != NULL) {
+ LastRecord = Record;
+
+ ///
+ /// Copy the headers including Data Hub and SMBIOS FviSmbios OEM type
+ ///
+ CopyMem (LastRecord, &(FviContext->FviHeader), sizeof (MISC_SUBCLASS_FVI_HEADER));
+ LastRecord += sizeof (MISC_SUBCLASS_FVI_HEADER);
+ String = LastRecord + FVI_ELEMENTS_SIZE_NOSTRING * Count;
+
+ NewElement = FviContext->Elements;
+
+ ///
+ /// Copy elements including strings
+ ///
+ for (Index = 0, StrIndex = 1; Index < Count; Index++) {
+ if (NewElement->Function != NULL) {
+ NewElement->Function (&(NewElement->Element));
+ }
+
+ ///
+ /// If string is implemented for ComponentName or VersionString, and then string
+ /// index of ComponentName or VersionString can't be zero. The string index of
+ /// ComponentName and VersionString will be updated and calculated while analyse
+ /// all elements here.String index must be non-zero if implemented.
+ ///
+ if (NewElement->Element.ComponentName != 0) {
+ NewElement->Element.ComponentName = StrIndex;
+ Length = GetStringLen (NewElement->Element.NameString);
+ CopyMem (String, &(NewElement->Element.NameString), Length);
+ String += Length;
+ StrIndex++;
+ }
+
+ if (NewElement->Element.VersionString != 0) {
+ NewElement->Element.VersionString = StrIndex;
+ Length = GetStringLen (NewElement->Element.VerString);
+ CopyMem (String, &(NewElement->Element.VerString), Length);
+ String += Length;
+ StrIndex++;
+ }
+
+ CopyMem (LastRecord, &(NewElement->Element), FVI_ELEMENTS_SIZE_NOSTRING);
+ LastRecord += FVI_ELEMENTS_SIZE_NOSTRING;
+
+ NewElement++;
+ }
+
+ Length = (UINT32) (String - Record) + 1;
+ Status = mDataHub->LogData (
+ mDataHub,
+ &gMiscSubClassName,
+ &gMiscProducerGuid,
+ EFI_DATA_RECORD_CLASS_DATA,
+ (VOID *) Record,
+ Length
+ );
+ }
+
+ ASSERT (!EFI_ERROR (Status));
+ if (Record != NULL) {
+ FreePool (Record);
+ }
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif
new file mode 100644
index 0000000..57f9263
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "RcFviDxeLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Library\RcFviDxeLib"
+ RefName = "RcFviDxeLib"
+[files]
+"RcFviDxeLib.sdl"
+"RcFviDxeLib.mak"
+"CreateFviLibrary.c"
+"RcFviLib.h"
+"RcFviDxeLib.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf
new file mode 100644
index 0000000..ad9f04c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.inf
@@ -0,0 +1,67 @@
+## @file
+# Component description file for the PchRcFviDxeLib
+#
+#@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 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 = RcFviDxeLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ CreateFviLibrary.c
+
+[sources.ia32]
+
+
+[sources.x64]
+
+
+[sources.ipf]
+
+
+[sources.ebc]
+
+
+[includes.common]
+ .
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkFrameworkProtocolLib
+[libraries.ia32]
+
+
+[libraries.x64]
+
+
+[nmake.common] \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak
new file mode 100644
index 0000000..4e8a698
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.mak
@@ -0,0 +1,69 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/RcFviDxeLib/RcFviDxeLib.mak 1 2/08/12 8:50a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:50a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.mak $
+#
+# 1 2/08/12 8:50a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#
+#*************************************************************************
+all : RcFviDxeLib
+
+$(RcFviDxeLib_LIB) : RcFviDxeLib
+
+RcFviDxeLib : $(BUILD_DIR)\RcFviDxeLib.mak RcFviDxeLibBin
+
+$(BUILD_DIR)\RcFviDxeLib.mak : $(RcFviDxeLib_DIR)\$(@B).cif $(RcFviDxeLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(RcFviDxeLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+RcFviDxeLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+RcFviDxeLib_LIB_LINKS =\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+
+RcFviDxeLibBin:
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\RcFviDxeLib.mak all \
+ "MY_INCLUDES=$(RcFviDxeLib_INCLUDES)" \
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(RcFviDxeLib_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/Library/RcFviDxeLib/RcFviDxeLib.sdl b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl
new file mode 100644
index 0000000..15c1fd4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviDxeLib.sdl
@@ -0,0 +1,73 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchLib/RcFviDxeLib/RcFviDxeLib.sdl 1 2/08/12 8:50a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:50a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchLib/RcFviDxeLib/RcFviDxeLib.sdl $
+#
+# 1 2/08/12 8:50a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#
+#*************************************************************************
+TOKEN
+ Name = "RcFviDxeLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable RcFviDxeLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "RcFviDxeLib_DIR"
+End
+
+MODULE
+ File = "RcFviDxeLib.mak"
+ Help = "Includes RcFviDxeLib.mak to Project"
+End
+
+ELINK
+ Name = "RcFviDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\RcFviDxeLib_Lib.lib"
+ Parent = "RcFviDxeLib_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/Library/RcFviDxeLib/RcFviLib.h b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h
new file mode 100644
index 0000000..70a5556
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Library/RcFviDxeLib/RcFviLib.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for Reference code Firmware Version Info Interface Lib implementation.
+
+@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 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
+**/
+#ifndef _RC_FVI_LIBRARY_IMPLEMENTATION_H_
+#define _RC_FVI_LIBRARY_IMPLEMENTATION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#include "EdkIIGlueDxe.h"
+#include "Library/EdkIIGlueMemoryAllocationLib.h"
+
+#include EFI_GUID_DEFINITION (DataHubRecords)
+#include EFI_PROTOCOL_CONSUMER (DataHub)
+
+#include "RcFviDxeLib.h"
+
+#endif
+
+/**
+ Publish the Reference code version info as per Firmware Version Info (FVI) Interface Spec v0.7
+ using MiscSubClass Data Hub.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification functions context, which is implementation dependent.
+
+ @retval None
+**/
+VOID
+EFIAPI
+DataHubCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/LynxPoint.cif b/ReferenceCode/Chipset/LynxPoint/LynxPoint.cif
new file mode 100644
index 0000000..1722234
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/LynxPoint.cif
@@ -0,0 +1,47 @@
+<component>
+ name = "Intel Pch SB Refcode"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint"
+ RefName = "Intel Pch SB Refcode"
+[files]
+"Pch.sdl"
+[parts]
+"PchAcpiTables"
+"ActiveBios"
+"IntelPchInclude"
+"IoTrap"
+"IntelLegacyInterrupt"
+"PchLib"
+"PchInitDxe"
+"PchInitPeim"
+"PchSmiDispatcher"
+"PchPcieSmm"
+"IntelPchPpiLib"
+"IntelPchProtocolLib"
+"PchReset"
+"PchResetPeim"
+"PchResetCommonLib"
+"PchSampleCode"
+"SataController"
+"PchSerialGpio"
+"SmartTimer"
+"PchSmbusCommonLib"
+"PchSmbusDxe"
+"PchSmbusArpDisabled"
+"PeiSmmControl"
+"SmmControl"
+"PchSpiCommonLib"
+"PchSpiPeim"
+"PchSpiSmm"
+"PchSpiRuntime"
+"PchSmbusSmm"
+"PchSmbusArpEnabled"
+"PchUsbCommonLib"
+"PchUsb"
+"Wdt"
+"PchGuidLib"
+"PchLateInitSmm"
+"PchS3Support"
+"PchS3Peim"
+"S3SupportSmm"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Pch.sdl b/ReferenceCode/Chipset/LynxPoint/Pch.sdl
new file mode 100644
index 0000000..2b372e3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pch.sdl
@@ -0,0 +1,485 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Pch.sdl 8 1/10/13 8:33a Scottyang $
+#
+# $Revision: 8 $
+#
+# $Date: 1/10/13 8:33a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Pch.sdl $
+#
+# 8 1/10/13 8:33a Scottyang
+# [TAG] None
+# [Category] Improvement
+# [Description] PCIE port swap function support.
+# [Files] Pch.sdl, PchRootPorts.c
+#
+# 7 11/20/12 9:38a Scottyang
+# [TAG] EIP107014
+# [Category] Improvement
+# [Description] Update RC 0.8.0
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 6 10/16/12 4:28a Scottyang
+# [TAG] EIP103924
+#
+# [Category] Improvement
+#
+# [Description] Update RC 0.7.1
+#
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 5 9/26/12 3:45a Victortu
+# [TAG] None
+# [Category] Improvement
+# [Description] Update for Intel PCH LPT RC070.
+# [Files] SB.sdl, SBDXE.c, SBPEI.c, Pch.sdl, SB.sd, SB.uni
+#
+# 4 8/13/12 8:22a Victortu
+# [TAG] None
+# [Category] Improvement
+# [Description] Remove PCH_A0PWRON_SAFEMODE.
+# [Files] SBDxe.c, Pch.sdl
+#
+# 3 7/27/12 6:29a Victortu
+# [TAG] None
+# [Category] Improvement
+# [Description] Support Server/Workstation PCH ID. Please set
+# "PCH_SVR_WS_ID_SUPPORT".
+# [Files] SBSetup.c, PchRegs.h, Pch.sdl
+#
+# [TAG] None
+# [Category] Improvement
+# [Description] Support ASLPREPROCESS_FLAG to include Iintel RC flags.
+# [Files] Pch.sdl
+#
+# [TAG] None
+# [Category] Improvement
+# [Description] Update to support ULT Platform.
+# [Files] SB.H, SB.mak, SB.sdl, SB.sd, SBSetup.c,
+# AcpiModeEnable.c, SBDxe.c, SBPEI.c, SBSMI.c, SleepSmi.c,
+# SmiHandlerPorting.c, SmiHandlerPorting2.c, SBPPI.h, Pch.sdl
+#
+# 2 7/02/12 10:07a Victortu
+#
+# 1 2/08/12 8:38a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PCH_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PCH support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CougarPoint_SUPPORT"
+ Value = "$(PCH_SUPPORT)"
+ Help = ""
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCHLP_SUPPORT"
+ Value = "0"
+ Help = "PCH LynxPoint-LP Support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCIE_PORT_SWAP"
+ Value = "0"
+ Help = "PCH PCIE pport swap function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+ELINK
+ Name = "INTEL_PCH_RC_FLAGS"
+ Help = "PCH Reference Code command line options of the compiler"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(INTEL_PCH_RC_FLAGS)"
+ Parent = "GLOBAL_DEFINES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(INTEL_PCH_RC_FLAGS)"
+ Parent = "ASLPREPROCESS_FLAG"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D PCH_SUPPORT"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D CougarPoint_SUPPORT"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "PCH_DEBUG_INFO"
+ Value = "1"
+ Help = "Enable/disable debug message in debug build for PCH drivers."
+ TokenType = Integer
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SERIAL_IO_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "PCHLP_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ADSP_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "PCHLP_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SUS_WELL_RESTORE"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "RapidStart_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "USB_PRECONDITION_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "INTEL_COUGAR_POINT_DIR"
+End
+
+PATH
+ Name = "INTEL_PCH_DIR"
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\Include"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\Include"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\Protocol"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\Protocol"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\SampleCode"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\SampleCode"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\Include\Library"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\Include\Library"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_INCLUDE_DIR)\PchRegs"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_INCLUDE_DIR)\PchRegs"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\Protocol\PchPlatformPolicy"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\Protocol\PchPlatformPolicy"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\PciExpress\Dxe"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\PciExpress\Dxe"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\S3Support\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\S3Support\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\SmBus\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\SmBus\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\Spi\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\Spi\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchUsbCommonLib_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchResetCommonLib_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchS3SupportDxe_DIR)"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)\PchInit\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)\PchInit\Common"
+ Parent = "INTEL_PCH_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchSpiPeim_DIR)"
+ Parent = "PCH_SPI_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchSpiSmm_DIR)"
+ Parent = "PCH_SPI_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchSpiRuntime_DIR)"
+ Parent = "PCH_SPI_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchInitDxe_DIR)"
+ Parent = "PCH_INITDXE_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchInitPeim_DIR)"
+ Parent = "PCH_INITPEI_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "INTEL_PCH_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PCH_SPI_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PCH_INITDXE_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PCH_INITPEI_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PERF_TUNE_INCLUDES"
+ InvokeOrder = ReplaceParent
+ Token = "PERF_TUNE_SUPPORT" "!=" "1"
+End
+
+ELINK
+ Name = "/I$(INTEL_COUGAR_POINT_DIR)"
+ Parent = "PERF_TUNE_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(INTEL_PCH_DIR)"
+ Parent = "PERF_TUNE_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchReset_DIR)"
+ Parent = "PCH_INITDXE_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(PchResetPeim_DIR)"
+ Parent = "PCH_INITPEI_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D SERIAL_IO_FLAG"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ Token = "SERIAL_IO_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D ADSP_FLAG"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ Token = "ADSP_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D SUS_WELL_RESTORE"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ Token = "SUS_WELL_RESTORE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D USB_PRECONDITION_ENABLE_FLAG"
+ Parent = "INTEL_PCH_RC_FLAGS"
+ Token = "USB_PRECONDITION_SUPPORT" "=" "1"
+ 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/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 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.cif b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.cif
new file mode 100644
index 0000000..51c2e34
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "PchSmiDispatcher"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\PchSmiDispatcher\Smm"
+ RefName = "PchSmiDispatcher"
+[files]
+"PchSmiDispatcher.sdl"
+"PchSmiDispatcher.mak"
+"PchSmm.h"
+"PchSmmCore.c"
+"PchSmmHelpers.h"
+"PchSmmHelpers.c"
+"PchxSmmHelpers.h"
+"PchxSmmHelpers.c"
+"PchSmmUsb.c"
+"PchSmmGpi.c"
+"PchSmmPowerButton.c"
+"PchSmmSw.c"
+"PchSmmSx.c"
+"PchSmmIchn.c"
+"PchSmmPeriodicTimer.c"
+"PchSmiDispatcher.dxs"
+"PchSmiDispatcher.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.dxs b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.dxs
new file mode 100644
index 0000000..e0f4908
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.dxs
@@ -0,0 +1,43 @@
+/** @file
+ Dispatch dependency expression file for the PchSmmDispatcher 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 (SmmBase)
+#include EFI_PROTOCOL_CONSUMER(PciRootBridgeIo)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.inf b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
new file mode 100644
index 0000000..a251b73
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.inf
@@ -0,0 +1,104 @@
+## @file
+# Component description file for the Pch SMI Dispatch Handlers module
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchSmiDispatcher
+FILE_GUID = B0D6ED53-B844-43f5-BD2F-61095264E77E
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSmm.h
+ PchSmmCore.c
+ PchSmmHelpers.h
+ PchSmmHelpers.c
+ PchxSmmHelpers.h
+ PchxSmmHelpers.c
+ PchSmmUsb.c
+ PchSmmGpi.c
+ PchSmmPowerButton.c
+ PchSmmSw.c
+ PchSmmSx.c
+ PchSmmIchn.c
+ PchSmmPeriodicTimer.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+[libraries.common]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EdkIIGlueSmmFirmwarePerformanceLib
+
+[libraries.ia32,libraries.x64]
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/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
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSmiDispatcher.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmmDispatcher
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_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_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.mak b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.mak
new file mode 100644
index 0000000..d4308f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.mak
@@ -0,0 +1,115 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmiDispatcher/PchSmiDispatcher.mak 3 6/24/13 6:08a Scottyang $
+#
+# $Revision: 3 $
+#
+# $Date: 6/24/13 6:08a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmiDispatcher/PchSmiDispatcher.mak $
+#
+# 3 6/24/13 6:08a Scottyang
+# [TAG] EIP127297
+# [Category] Improvement
+# [Description] Update PCH RC 1.6.0.
+# [Files] SB.sd, SBDxe.c, ..\ReferenceCode\Chipset\LynxPoint\*.*
+#
+# 2 2/24/12 2:14a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:54a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmiDispatcher Driver
+#---------------------------------------------------------------------------
+EDK : PchSmiDispatcher
+PchSmiDispatcher : $(BUILD_DIR)\PchSmiDispatcher.mak PchSmiDispatcherBin
+
+
+$(BUILD_DIR)\PchSmiDispatcher.mak : $(PchSmiDispatcher_DIR)\$(@B).cif $(PchSmiDispatcher_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmiDispatcher_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmiDispatcher_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmiDispatcher_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmmDispatcher"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+
+PchSmiDispatcher_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformSmmLib_LIB)\
+ $(EdkIIGlueSmmFirmwarePerformanceLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+
+PchSmiDispatcherBin: $(COMPILERSTUB) $(PchSmiDispatcher_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmiDispatcher.mak all \
+ "MY_INCLUDES=$(PchSmiDispatcher_INCLUDES)" \
+ "MY_DEFINES=$(PchSmiDispatcher_DEFINES)" \
+ GUID=B0D6ED53-B844-43f5-BD2F-61095264E77E\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchSmiDispatcher_DIR)\PchSmiDispatcher.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/PchSmiDispatcher/Smm/PchSmiDispatcher.sdl b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.sdl
new file mode 100644
index 0000000..93c2ae0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmiDispatcher.sdl
@@ -0,0 +1,102 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmiDispatcher/PchSmiDispatcher.sdl 3 12/30/13 5:10a Barretlin $
+#
+# $Revision: 3 $
+#
+# $Date: 12/30/13 5:10a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmiDispatcher/PchSmiDispatcher.sdl $
+#
+# 3 12/30/13 5:10a Barretlin
+# [TAG] EIP145008
+# [Category] Improvement
+# [Description] Force Power button event phase always as entry to avoid
+# some power button issue
+# [Files] PchSmiDispatcher.sdl PchSmmPowerButton.c
+#
+# 2 4/25/12 9:22a Victortu
+# [TAG] None
+# [Category] Improvement
+# [Description] Reprogram SMM ChildDispatcher drivers.
+# [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c;
+# SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak;
+# SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c;
+# SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs;
+# PchSmiDispatcher.sdl
+#
+# 1 2/08/12 8:54a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmiDispatcher_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmiDispatcher support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "INTEL_RC_SMI_DISPATCHER_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "FORCE_PWB_PHASE_AS_ENTRY"
+ Value = "1"
+ Help = "Force Power button event phase always as entry to avoid some power button issue. EIP145008"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "PchSmiDispatcher_DIR"
+ Help = "PchSmiDispatcher file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmiDispatcher.mak to Project"
+ File = "PchSmiDispatcher.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmiDispatcher.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/PchSmiDispatcher/Smm/PchSmm.h b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmm.h
new file mode 100644
index 0000000..864615b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmm.h
@@ -0,0 +1,727 @@
+/** @file
+ Prototypes and defines for the PCH SMM Dispatcher.
+
+@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
+
+**/
+#ifndef PCH_SMM_H
+#define PCH_SMM_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"
+
+//
+// Driver Consumed Protocol Prototypes
+//
+//
+// Used during initialization
+//
+#include EFI_PROTOCOL_DEPENDENCY (PciRootBridgeIo)
+#include EFI_PROTOCOL_CONSUMER (LoadedImage)
+//
+// Used during SMI dispatch
+//
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_CONSUMER (SmmControl)
+//
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SUPPORTED PROTOCOLS
+//
+#include EFI_PROTOCOL_PRODUCER (SmmUsbDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmSxDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmSwDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmGpiDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmIchnDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmIchnDispatchEx)
+#include EFI_PROTOCOL_PRODUCER (SmmPowerButtonDispatch)
+#include EFI_PROTOCOL_PRODUCER (SmmPeriodicTimerDispatch)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+///
+/// Define an enumeration for all the supported protocols
+///
+typedef enum {
+ UsbType,
+ SxType,
+ SwType,
+ GpiType,
+ IchnType,
+ IchnExType,
+ PowerButtonType,
+ PeriodicTimerType,
+ PchSmmProtocolTypeMax
+} PCH_SMM_PROTOCOL_TYPE;
+
+///
+/// SPECIFYING A REGISTER
+/// We want a general way of referring to addresses. For this case, we'll only
+/// need addresses in the ACPI table (and the TCO entries within the ACPI table).
+/// However, it's interesting to consider what it would take to support other types
+/// of addresses. To address Will's concern, I think it prudent to accommodate it
+/// early on in the design.
+///
+/// Addresses we need to consider:
+///
+/// Type: Required:
+/// I/O Yes
+/// ACPI (special case of I/O) Only if we want to
+/// TCO (special case of ACPI) Only if we want to
+/// GPIO (special case of I/O) Only if we want to
+/// Memory (or Memory Mapped I/O) Only if we want to
+/// PCIE Yes, for BiosWp
+///
+typedef enum {
+ ///
+ /// IO_ADDR_TYPE, /// unimplemented
+ ///
+ ACPI_ADDR_TYPE,
+ GPIO_ADDR_TYPE,
+ ///
+ /// MEMORY_ADDR_TYPE, /// unimplemented
+ ///
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCIE_ADDR_TYPE,
+ NUM_ADDR_TYPES, ///< count of items in this enum
+ PCH_SMM_ADDR_TYPE_NULL = -1 ///< sentinel to indicate NULL or to signal end of arrays
+} ADDR_TYPE;
+
+//
+// Assumption: 32-bits -- enum's evaluate to integer
+// Assumption: This code will only run on IA-32. Justification: IA-64 doesn't have SMIs.
+// We don't have to worry about 64-bit addresses.
+// Typedef the size of addresses in case the numbers I'm using are wrong or in case
+// this changes. This is a good idea because PCI_ADDR will change, for example, when
+// we add support for PciExpress.
+//
+typedef UINT16 IO_ADDR;
+typedef IO_ADDR GPIO_ADDR;
+typedef IO_ADDR ACPI_ADDR; ///< can omit
+typedef IO_ADDR TCO_ADDR; ///< can omit
+typedef UINTN MEM_ADDR;
+typedef MEM_ADDR *MEMORY_MAPPED_IO_ADDRESS;
+typedef union {
+ UINT32 Raw;
+ struct {
+ UINT8 Reg;
+ UINT8 Fnc;
+ UINT8 Dev;
+ UINT8 Bus;
+ } Fields;
+} PCIE_ADDR;
+
+typedef struct {
+ ADDR_TYPE Type;
+ union {
+ ///
+ /// used to initialize during declaration/definition
+ ///
+ UINT32 raw;
+
+ ///
+ /// used to access useful data
+ ///
+ IO_ADDR io;
+ ACPI_ADDR acpi;
+ TCO_ADDR tco;
+ GPIO_ADDR gpio;
+ MEM_ADDR mem;
+ MEMORY_MAPPED_IO_ADDRESS Mmio;
+ PCIE_ADDR pcie;
+
+ } Data;
+
+} PCH_SMM_ADDRESS;
+
+///
+/// SPECIFYING BITS WITHIN A REGISTER
+/// Here's a struct that helps us specify a source or enable bit.
+///
+typedef struct {
+ PCH_SMM_ADDRESS Reg;
+ UINT8 SizeInBytes; ///< of the register
+ UINT8 Bit;
+} PCH_SMM_BIT_DESC;
+
+//
+// Sometimes, we'll have bit descriptions that are unused. It'd be great to have a
+// way to easily identify them:
+//
+#define IS_BIT_DESC_NULL(BitDesc) ((BitDesc).Reg.Type == PCH_SMM_ADDR_TYPE_NULL) ///< "returns" true when BitDesc is NULL
+#define NULL_THIS_BIT_DESC(BitDesc) ((BitDesc).Reg.Type = PCH_SMM_ADDR_TYPE_NULL) ///< will "return" an integer w/ value of 0
+#define NULL_BIT_DESC_INITIALIZER \
+ { \
+ { \
+ PCH_SMM_ADDR_TYPE_NULL, \
+ { \
+ 0 \
+ } \
+ }, \
+ 0, 0 \
+ }
+//
+// I'd like a type to specify the callback's Sts & En bits because they'll
+// be commonly used together:
+//
+#define NUM_EN_BITS 2
+#define NUM_STS_BITS 1
+
+//
+// Flags
+//
+typedef UINT8 PCH_SMM_SOURCE_FLAGS;
+
+//
+// Flags required today
+//
+#define PCH_SMM_NO_FLAGS 0
+#define PCH_SMM_SCI_EN_DEPENDENT 1
+
+//
+// Flags that might be required tomorrow
+//
+///
+/// #define PCH_SMM_CLEAR_WITH_ONE 2 /// may need to support bits that clear by writing 0
+/// #define PCH_SMM_MULTIBIT_FIELD 3 /// may need to support status/enable fields 2 bits wide
+///
+typedef struct {
+ PCH_SMM_SOURCE_FLAGS Flags;
+ PCH_SMM_BIT_DESC En[NUM_EN_BITS];
+ PCH_SMM_BIT_DESC Sts[NUM_STS_BITS];
+} PCH_SMM_SOURCE_DESC;
+//
+// 31 bytes, I think
+//
+#define NULL_SOURCE_DESC_INITIALIZER \
+ { \
+ PCH_SMM_NO_FLAGS, \
+ { \
+ NULL_BIT_DESC_INITIALIZER, NULL_BIT_DESC_INITIALIZER \
+ }, \
+ { \
+ NULL_BIT_DESC_INITIALIZER \
+ } \
+ }
+
+///
+/// CHILD CONTEXTS
+/// To keep consistent w/ the architecture, we'll need to provide the context
+/// to the child when we call its callback function. After talking with Will,
+/// we agreed that we'll need functions to "dig" the context out of the hardware
+/// in many cases (Sx, Trap, Gpi, etc), and we'll need a function to compare those
+/// contexts to prevent unnecessary dispatches. I'd like a general type for these
+/// "GetContext" functions, so I'll need a union of all the protocol contexts for
+/// our internal use:
+///
+typedef union {
+ //
+ // (in no particular order)
+ //
+ EFI_SMM_ICHN_DISPATCH_CONTEXT Ichn;
+ EFI_SMM_ICHN_DISPATCH_EX_CONTEXT IchnEx;
+ EFI_SMM_SX_DISPATCH_CONTEXT Sx;
+ EFI_SMM_PERIODIC_TIMER_DISPATCH_CONTEXT PeriodicTimer;
+ EFI_SMM_SW_DISPATCH_CONTEXT Sw;
+ EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PowerButton;
+ EFI_SMM_USB_DISPATCH_CONTEXT Usb;
+ EFI_SMM_GPI_DISPATCH_CONTEXT Gpi;
+} PCH_SMM_CONTEXT;
+//
+// Assumption: PeriodicTimer largest at 3x64-bits or 24 bytes
+//
+typedef struct _DATABASE_RECORD DATABASE_RECORD;
+
+///
+/// Assumption: the GET_CONTEXT function will be as small and simple as possible.
+/// Assumption: We don't need to pass in an enumeration for the protocol because each
+/// GET_CONTEXT function is written for only one protocol.
+/// We also need a function to compare contexts to see if the child should be dispatched
+///
+typedef
+VOID
+(EFIAPI *GET_CONTEXT) (
+ IN DATABASE_RECORD * Record,
+ OUT PCH_SMM_CONTEXT * Context
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *CMP_CONTEXT) (
+ IN PCH_SMM_CONTEXT * Context1,
+ IN PCH_SMM_CONTEXT * Context2
+ );
+
+///
+/// Finally, every protocol will require a "Get Context" and "Compare Context" call, so
+/// we may as well wrap that up in a table, too.
+///
+typedef struct {
+ GET_CONTEXT GetContext;
+ CMP_CONTEXT CmpContext;
+} CONTEXT_FUNCTIONS;
+
+extern CONTEXT_FUNCTIONS ContextFunctions[PchSmmProtocolTypeMax];
+
+///
+/// MAPPING CONTEXT TO BIT DESCRIPTIONS
+/// I'd like to have a general approach to mapping contexts to bit descriptions.
+/// Sometimes, we'll find that we can use table lookups or constant assignments;
+/// other times, we'll find that we'll need to use a function to perform the mapping.
+/// If we define a macro to mask that process, we'll never have to change the code.
+/// I don't know if this is desirable or not -- if it isn't, then we can get rid
+/// of the macros and just use function calls or variable assignments. Doesn't matter
+/// to me.
+/// Mapping complex contexts requires a function
+///
+
+/**
+ Maps a USB context to a source description.
+
+ @param[in] Context The context we need to map. Type must be USB.
+ @param[out] SrcDesc The source description that corresponds to the given context.
+
+ @retval None
+**/
+VOID
+MapUsbToSrcDesc (
+ IN PCH_SMM_CONTEXT *Context,
+ OUT PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ Figure out which timer the child is requesting and
+ send back the source description
+
+ @param[in] DispatchContext The pointer to the Dispatch Context instances
+ @param[out] SrcDesc The pointer to the source description
+
+ @retval None
+**/
+VOID
+MapPeriodicTimerToSrcDesc (
+ IN PCH_SMM_CONTEXT *DispatchContext,
+ OUT PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+//
+// Mapping simple contexts can be done by assignment or lookup table
+//
+extern const PCH_SMM_SOURCE_DESC SW_SOURCE_DESC;
+extern const PCH_SMM_SOURCE_DESC SX_SOURCE_DESC;
+extern const PCH_SMM_SOURCE_DESC POWER_BUTTON_SOURCE_DESC;
+
+//
+// With the changes we've made to the protocols, we can now use table
+// lookups for the following protocols:
+//
+#define NUM_SUPPORTED_GPIS 16
+extern const PCH_SMM_SOURCE_DESC LPTH_GPI_SOURCE_DESC[NUM_SUPPORTED_GPIS];
+extern const PCH_SMM_SOURCE_DESC LPTLP_GPI_SOURCE_DESC[NUM_SUPPORTED_GPIS];
+
+extern PCH_SMM_SOURCE_DESC ICHN_H_SOURCE_DESCS[NUM_ICHN_TYPES];
+extern PCH_SMM_SOURCE_DESC ICHN_LP_SOURCE_DESCS[NUM_ICHN_TYPES];
+extern PCH_SMM_SOURCE_DESC ICHN_EX_SOURCE_DESCS[IchnExTypeMAX - IchnExPciExpress];
+
+///
+/// For PCHx, APMC is UINT8 port, so the MAX SWI Value is 0xFF.
+///
+#define MAXIMUM_SWI_VALUE 0xFF
+
+///
+/// GENERALIZING THE CALLBACK
+/// All SmmXxxDispatch callbacks have the same form:
+///
+/// VOID Callback( EFI_HANDLE, EFI_SMM_Xxx_DISPATCH_CONTEXT )
+/// We need a typedef that'll allow us to call any callback
+///
+typedef
+VOID
+(EFIAPI *PCH_SMM_CALLBACK) (
+ IN EFI_HANDLE Handle,
+ IN PCH_SMM_CONTEXT * Context
+ );
+
+///
+/// Open: Need to make sure this kind of type cast will actually work.
+/// May need an intermediate form w/ two VOID* arguments. I'll figure
+/// that out when I start compiling.
+///
+typedef
+VOID
+(EFIAPI *PCH_SMM_CLEAR_SOURCE) (
+ PCH_SMM_SOURCE_DESC * SrcDesc
+ );
+
+///
+/// "DATABASE" RECORD
+/// Linked list data structures
+///
+#define DATABASE_RECORD_SIGNATURE EFI_SIGNATURE_32 ('D', 'B', 'R', 'C')
+
+struct _DATABASE_RECORD {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+
+ ///
+ /// Status and Enable bit description
+ ///
+ PCH_SMM_SOURCE_DESC SrcDesc;
+
+ ///
+ /// Callback function
+ ///
+ PCH_SMM_CALLBACK Callback;
+ PCH_SMM_CONTEXT ChildContext;
+
+ ///
+ /// Special handling hooks -- init them to NULL if unused/unneeded
+ ///
+ PCH_SMM_CLEAR_SOURCE ClearSource; ///< needed for SWSMI timer
+
+ ///
+ /// Functions required to make callback code general
+ ///
+ CONTEXT_FUNCTIONS ContextFunctions;
+
+ ///
+ /// The protocol that this record dispatches
+ ///
+ PCH_SMM_PROTOCOL_TYPE ProtocolType;
+
+};
+
+#define DATABASE_RECORD_FROM_LINK(_record) CR (_record, DATABASE_RECORD, Link, DATABASE_RECORD_SIGNATURE)
+
+///
+/// HOOKING INTO THE ARCHITECTURE
+///
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_GENERIC_REGISTER) (
+ IN VOID **This,
+ IN VOID *DispatchFunction,
+ IN VOID *DispatchContext,
+ OUT EFI_HANDLE * DispatchHandle
+ );
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_GENERIC_UNREGISTER) (
+ IN VOID **This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+///
+/// Define a memory "stamp" equivalent in size and function to most of the protocols
+///
+typedef struct {
+ PCH_SMM_GENERIC_REGISTER Register;
+ PCH_SMM_GENERIC_UNREGISTER Unregister;
+ UINTN Extra1;
+ UINTN Extra2; ///< may not need this one
+} PCH_SMM_GENERIC_PROTOCOL;
+
+/**
+ Register a child SMI dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for this SMI source.
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ @param[out] DispatchHandle Handle of dispatch function, for when interfacing
+ with the parent SMM driver, will be the address of linked
+ list link in the call back record.
+
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database record
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+**/
+EFI_STATUS
+PchSmmCoreRegister (
+ IN PCH_SMM_GENERIC_PROTOCOL *This,
+ IN PCH_SMM_CALLBACK DispatchFunction,
+ IN PCH_SMM_CONTEXT *DispatchContext,
+ OUT EFI_HANDLE *DispatchHandle
+ );
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+PchSmmCoreUnRegister (
+ IN PCH_SMM_GENERIC_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ );
+
+typedef union {
+ PCH_SMM_GENERIC_PROTOCOL Generic;
+
+ EFI_SMM_USB_DISPATCH_PROTOCOL Usb;
+ EFI_SMM_SX_DISPATCH_PROTOCOL Sx;
+ EFI_SMM_SW_DISPATCH_PROTOCOL Sw;
+ EFI_SMM_GPI_DISPATCH_PROTOCOL Gpi;
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL Ichn;
+ EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL IchnEx;
+ EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL PowerButton;
+ EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL PeriodicTimer;
+} PCH_SMM_PROTOCOL;
+
+///
+/// Define a structure to help us identify the generic protocol
+///
+#define PROTOCOL_SIGNATURE EFI_SIGNATURE_32 ('P', 'R', 'O', 'T')
+
+typedef struct {
+ UINTN Signature;
+
+ PCH_SMM_PROTOCOL_TYPE Type;
+ PCH_SMM_PROTOCOL Protocols;
+} PCH_SMM_QUALIFIED_PROTOCOL;
+
+#define QUALIFIED_PROTOCOL_FROM_GENERIC(_generic) \
+ CR ( \
+ _generic, \
+ PCH_SMM_QUALIFIED_PROTOCOL, \
+ Protocols, \
+ PROTOCOL_SIGNATURE \
+ )
+
+///
+/// Create private data for the protocols that we'll publish
+///
+typedef struct {
+ LIST_ENTRY CallbackDataBase;
+ EFI_HANDLE InstallMultProtHandle;
+ PCH_SMM_QUALIFIED_PROTOCOL Protocols[PchSmmProtocolTypeMax];
+} PRIVATE_DATA;
+
+extern PRIVATE_DATA mPrivateData;
+extern EFI_SMM_SYSTEM_TABLE *mSmst;
+extern UINT32 mAcpiBaseAddr;
+extern UINT32 mGpioBaseAddr;
+extern EFI_SMM_BASE_PROTOCOL *mSmmBase;
+
+/**
+ Get the Software Smi value
+
+ @param[in] Record No use
+ @param[out] Context The context that includes Software Smi value to be filled
+
+ @retval None
+**/
+VOID
+EFIAPI
+SwGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ );
+
+/**
+ Check whether software SMI value of two contexts match
+
+ @param[in] Context1 Context 1 that includes software SMI value 1
+ @param[in] Context2 Context 2 that includes software SMI value 2
+
+ @retval FALSE Software SMI value match
+ @retval TRUE Software SMI value don't match
+**/
+BOOLEAN
+EFIAPI
+SwCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ );
+
+/**
+ Get the Sleep type
+
+ @param[in] Record No use
+ @param[out] Context The context that includes SLP_TYP bits to be filled
+
+ @retval None
+**/
+VOID
+EFIAPI
+SxGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ );
+
+/**
+ Check whether sleep type of two contexts match
+
+ @param[in] Context1 Context 1 that includes sleep type 1
+ @param[in] Context2 Context 2 that includes sleep type 2
+
+ @retval FALSE Sleep types match
+ @retval TRUE Sleep types don't match
+**/
+BOOLEAN
+EFIAPI
+SxCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ );
+
+/**
+ Update the elapsed time from the Interval data of DATABASE_RECORD
+
+ @param[in] Record The pointer to the DATABASE_RECORD.
+ @param[out] HwContext The Context to be updated.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PeriodicTimerGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ );
+
+/**
+ Check whether Periodic Timer of two contexts match
+
+ @param[in] Context1 Context 1 that includes Periodic Timer 1
+ @param[in] Context2 Context 2 that includes Periodic Timer 2
+
+ @retval FALSE Periodic Timer match
+ @retval TRUE Periodic Timer don't match
+**/
+BOOLEAN
+EFIAPI
+PeriodicTimerCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ );
+
+/**
+ Get the power button status.
+
+ @param[in] Record The pointer to the DATABASE_RECORD.
+ @param[out] Context Calling context from the hardware, will be updated with the current power button status.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PowerButtonGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ );
+
+/**
+ Check whether Power Button status of two contexts match
+
+ @param[in] Context1 Context 1 that includes Power Button status 1
+ @param[in] Context2 Context 2 that includes Power Button status 2
+
+ @retval FALSE Power Button status match
+ @retval TRUE Power Button status don't match
+**/
+BOOLEAN
+EFIAPI
+PowerButtonCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ );
+
+/**
+ This function is responsible for calculating and enabling any timers that are required
+ to dispatch messages to children. The SrcDesc argument isn't acutally used.
+
+ @param[in] SrcDesc Pointer to the PCH_SMM_SOURCE_DESC instance.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+PchSmmPeriodicTimerClearSource (
+ IN PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ This services returns the next SMI tick period that is supported by the chipset.
+ The order returned is from longest to shortest interval period.
+
+ @param[in] This Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL instance.
+ @param[in, out] SmiTickInterval Pointer to pointer of the next shorter SMI interval period that is supported by the child.
+
+ @retval EFI_SUCCESS The service returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter SmiTickInterval is invalid.
+**/
+EFI_STATUS
+PchSmmPeriodicTimerDispatchGetNextShorterInterval (
+ IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This,
+ IN OUT UINT64 **SmiTickInterval
+ );
+
+/**
+ When we get an SMI that indicates that we are transitioning to a sleep state,
+ we need to actually transition to that state. We do this by disabling the
+ "SMI on sleep enable" feature, which generates an SMI when the operating system
+ tries to put the system to sleep, and then physically putting the system to sleep.
+
+ @param[in] None
+
+ @retval None.
+**/
+VOID
+PchSmmSxGoToSleep (
+ VOID
+ );
+
+/**
+ Clear the SMI status bit after the SMI handling is done
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchSmmIchnClearSource (
+ IN PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ Fix the base address of the source regs and status regs.
+ Since Base should get from register filled by platform modules already.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+PchSmmIchnFixSourceBase (
+ VOID
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c
new file mode 100644
index 0000000..89100d5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmCore.c
@@ -0,0 +1,891 @@
+/** @file
+ This driver is responsible for the registration of child drivers
+ and the abstraction of the PCH SMI sources.
+
+@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 "PchSmm.h"
+#include "PchSmmHelpers.h"
+// AMI_OVERRIDE, GPIO_ROUT >>>
+#include "Token.h"
+// AMI_OVERRIDE, GPIO_ROUT <<<
+
+///
+/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// MODULE / GLOBAL DATA
+///
+/// Module variables used by the both the main dispatcher and the source dispatchers
+/// Declared in PchSmmSources.h
+///
+EFI_SMM_SYSTEM_TABLE *mSmst;
+UINT32 mAcpiBaseAddr;
+UINT32 mGpioBaseAddr;
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+//
+// The reserved mmio address can only be used in Sx handler
+// it's not reserved in ACPI.
+//
+EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+
+PRIVATE_DATA mPrivateData = { ///< for the structure
+ {
+ NULL
+ }, ///< CallbackDataBase linked list head
+ NULL, ///< EFI handle returned when calling InstallMultipleProtocolInterfaces
+ { ///< protocol arrays
+ ///
+ /// elements within the array
+ ///
+ {
+ PROTOCOL_SIGNATURE,
+ UsbType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ SxType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ SwType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister,
+ (UINTN) MAXIMUM_SWI_VALUE
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ GpiType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister,
+ (UINTN) NUM_SUPPORTED_GPIS
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ IchnType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ IchnExType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ PowerButtonType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister
+ }
+ },
+ {
+ PROTOCOL_SIGNATURE,
+ PeriodicTimerType,
+ {
+ (PCH_SMM_GENERIC_REGISTER) PchSmmCoreRegister,
+ (PCH_SMM_GENERIC_UNREGISTER) PchSmmCoreUnRegister,
+ (UINTN) PchSmmPeriodicTimerDispatchGetNextShorterInterval
+ }
+ },
+ }
+};
+
+CONTEXT_FUNCTIONS mContextFunctions[PchSmmProtocolTypeMax] = {
+ {
+ NULL,
+ NULL
+ },
+ {
+ SxGetContext,
+ SxCmpContext
+ },
+ {
+ SwGetContext,
+ SwCmpContext
+ },
+ {
+ NULL,
+ NULL
+ },
+ {
+ NULL,
+ NULL
+ },
+ {
+ NULL,
+ NULL
+ },
+ {
+ PowerButtonGetContext,
+ PowerButtonCmpContext
+ },
+ {
+ PeriodicTimerGetContext,
+ PeriodicTimerCmpContext
+ },
+};
+
+///
+/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// PROTOTYPES
+///
+/// Functions use only in this file
+///
+EFI_STATUS
+EFIAPI
+PchSmmCoreDispatcher (
+ IN EFI_HANDLE SmmImageHandle,
+ IN OUT VOID *CommunicationBuffer,
+ IN OUT UINTN *SourceSize
+ );
+
+///
+/// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+/// FUNCTIONS
+///
+/// Driver entry point
+///
+
+/**
+ Initializes the PCH SMM Dispatcher
+
+ @param[in] ImageHandle Pointer to the loaded image protocol for this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS PchSmmDispatcher Initialization completed.
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmmDispatcher (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate SMM Base Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ return Status;
+ }
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ return Status;
+ }
+
+ PERF_START_EX (ImageHandle, L"SmmModule", NULL, AsmReadTsc(), 8);
+
+ ///
+ /// Access ACPI Base Addresses Register
+ ///
+ mAcpiBaseAddr = (UINT32) (MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR);
+ ASSERT (mAcpiBaseAddr != 0);
+
+ ///
+ /// Access GPIO Base Addresses Register
+ ///
+ mGpioBaseAddr = (UINT32) (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);
+ ASSERT (mGpioBaseAddr != 0);
+
+ ///
+ /// Fix the ICHN_SOURCE_DESCS base, in order to obtain independence with platform.
+ ///
+ PchSmmIchnFixSourceBase ();
+
+ PchSmmPublishDispatchProtocols ();
+
+ ///
+ /// Register a callback function to handle subsequent SMIs. This callback
+ /// will be called by SmmCoreDispatcher.
+ ///
+//AMI_OVERRIDE Support SMM2>>
+ mSmmBase->RegisterCallback (mSmmBase, ImageHandle, PchSmmCoreDispatcher, TRUE, FALSE);
+//AMI_OVERRIDE Support SMM2<<
+
+ ///
+ /// Initialize Callback DataBase
+ ///
+ InitializeListHead (&mPrivateData.CallbackDataBase);
+
+ ///
+ /// Enable SMIs on the PCH now that we have a callback
+ ///
+ PchSmmInitHardware ();
+
+ mResvMmioBaseAddr = 0x0ffffffff;
+#ifndef AMI_OVERRIDE_FOR_PCH
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &mResvMmioBaseAddr,
+ ImageHandle,
+ NULL
+ );
+#else
+ Status = gDS->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchBottomUp,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 16, // 2^16: 64K Alignment
+ 0x10000, // 64K Length
+ &mResvMmioBaseAddr,
+ ImageHandle,
+ NULL
+ );
+#endif
+ ASSERT_EFI_ERROR (Status);
+ DEBUG((EFI_D_INFO,"mResvMmioBaseAddr %x\n", mResvMmioBaseAddr));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Check the Fed SwSmiInputValue to see if there is a duplicated one in the database
+
+ @param[in] FedSwSmiInputValue Fed SwSmiInputValue
+
+ @retval EFI_SUCCESS There is no duplicated SwSmiInputValue
+ @retval EFI_INVALID_PARAMETER There is a duplicated SwSmiInputValue
+**/
+EFI_STATUS
+SmiInputValueDuplicateCheck (
+ UINTN FedSwSmiInputValue
+ )
+{
+
+ DATABASE_RECORD *RecordInDb;
+ LIST_ENTRY *LinkInDb;
+
+ LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+ while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+ RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+
+ if (RecordInDb->ProtocolType == SwType) {
+ if (RecordInDb->ChildContext.Sw.SwSmiInputValue == FedSwSmiInputValue) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Register a child SMI dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the PCH_SMM_GENERIC_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for this SMI source.
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ @param[out] DispatchHandle Handle of dispatch function, for when interfacing
+ with the parent SMM driver, will be the address of linked
+ list link in the call back record.
+
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database record
+ @retval EFI_INVALID_PARAMETER The input parameter is invalid
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+**/
+EFI_STATUS
+PchSmmCoreRegister (
+ IN PCH_SMM_GENERIC_PROTOCOL *This,
+ IN PCH_SMM_CALLBACK DispatchFunction,
+ IN PCH_SMM_CONTEXT *DispatchContext,
+ OUT EFI_HANDLE *DispatchHandle
+ )
+{
+ EFI_STATUS Status;
+ DATABASE_RECORD *Record;
+ PCH_SMM_QUALIFIED_PROTOCOL *Qualified;
+ PCH_SMM_SOURCE_DESC NullSourceDesc = NULL_SOURCE_DESC_INITIALIZER;
+ PCH_SERIES PchSeries;
+ UINTN Index;
+
+ PchSeries = GetPchSeries();
+ Index = 0;
+ ///
+ /// Create database record and add to database
+ ///
+ if (mSmst == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = mSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (DATABASE_RECORD), (VOID **) &Record);
+ if (EFI_ERROR (Status)) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ///
+ /// Gather information about the registration request
+ ///
+ Record->Callback = DispatchFunction;
+ Record->ChildContext = *DispatchContext;
+
+ Qualified = QUALIFIED_PROTOCOL_FROM_GENERIC (This);
+
+ Record->ProtocolType = Qualified->Type;
+
+ Record->ContextFunctions = mContextFunctions[Qualified->Type];
+ ///
+ /// Perform linked list housekeeping
+ ///
+ Record->Signature = DATABASE_RECORD_SIGNATURE;
+
+ switch (Qualified->Type) {
+ ///
+ /// By the end of this switch statement, we'll know the
+ /// source description the child is registering for
+ ///
+ case UsbType:
+ ///
+ /// Check the validity of Context Type
+ ///
+ if ((Record->ChildContext.Usb.Type < UsbLegacy) || (Record->ChildContext.Usb.Type > UsbWake)) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ MapUsbToSrcDesc (DispatchContext, &(Record->SrcDesc));
+ Record->ClearSource = NULL;
+ ///
+ /// use default clear source function
+ ///
+ break;
+
+ case SxType:
+ ///
+ /// Check the validity of Context Type and Phase
+ ///
+ if ((Record->ChildContext.Sx.Type < SxS0) ||
+ (Record->ChildContext.Sx.Type >= EfiMaximumSleepType) ||
+ (Record->ChildContext.Sx.Phase < SxEntry) ||
+ (Record->ChildContext.Sx.Phase >= EfiMaximumPhase)
+ ) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ CopyMem ((VOID *) &(Record->SrcDesc), (VOID *) (&SX_SOURCE_DESC), sizeof (PCH_SMM_SOURCE_DESC));
+ Record->ClearSource = NULL;
+ ///
+ /// use default clear source function
+ ///
+ break;
+
+ case SwType:
+ ///
+ /// Check the validity of Context Value
+ ///
+ if (Record->ChildContext.Sw.SwSmiInputValue > MAXIMUM_SWI_VALUE) {
+ goto Error;
+ }
+
+ if (EFI_ERROR (SmiInputValueDuplicateCheck (Record->ChildContext.Sw.SwSmiInputValue))) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ CopyMem ((VOID *) &(Record->SrcDesc), (VOID *) (&SW_SOURCE_DESC), sizeof (PCH_SMM_SOURCE_DESC));
+ Record->ClearSource = NULL;
+ ///
+ /// use default clear source function
+ ///
+ break;
+
+ case GpiType:
+ Index = Record->ChildContext.Gpi.GpiNum;
+ if (PchSeries == PchH) {
+ Index -= V_PCH_LPTH_ALT_GP_SMI_GPIBASE;
+ if (Index >= S_PCH_LPTH_ALT_GP_SMI_GPISIZE) {
+ goto Error;
+ }
+ } else if (PchSeries == PchLp) {
+ Index -= V_PCH_LPTLP_ALT_GP_SMI_GPIBASE;
+ if (Index >= S_PCH_LPTLP_ALT_GP_SMI_GPISIZE) {
+ goto Error;
+ }
+ } else {
+ goto Error;
+ }
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ if (PchSeries == PchH) {
+ CopyMem (
+ (VOID *) &(Record->SrcDesc),
+ (VOID *) &(LPTH_GPI_SOURCE_DESC[Index]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+ } else if (PchSeries == PchLp) {
+ CopyMem (
+ (VOID *) &(Record->SrcDesc),
+ (VOID *) &(LPTLP_GPI_SOURCE_DESC[Index]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+ }
+ Record->ClearSource = NULL;
+ ///
+ /// use default clear source function
+ ///
+ break;
+
+ case IchnType:
+ ///
+ /// Check the validity of Context Type
+ ///
+ if (Record->ChildContext.Ichn.Type >= NUM_ICHN_TYPES) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ if (PchSeries == PchLp) {
+ CopyMem (
+ (VOID *) &(Record->SrcDesc),
+ (VOID *) &(ICHN_LP_SOURCE_DESCS[Record->ChildContext.Ichn.Type]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+ } else if (PchSeries == PchH) {
+ CopyMem (
+ (VOID *) &(Record->SrcDesc),
+ (VOID *) &(ICHN_H_SOURCE_DESCS[Record->ChildContext.Ichn.Type]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+ }
+ Record->ClearSource = PchSmmIchnClearSource;
+ break;
+
+ case IchnExType:
+ ///
+ /// Check the validity of Context Type
+ ///
+ if ((Record->ChildContext.IchnEx.Type < IchnExPciExpress) || (Record->ChildContext.IchnEx.Type >= IchnExTypeMAX)) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ CopyMem (
+ (VOID *) &(Record->SrcDesc),
+ (VOID *) &(ICHN_EX_SOURCE_DESCS[Record->ChildContext.IchnEx.Type - IchnExPciExpress]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+ Record->ClearSource = NULL;
+ break;
+
+ case PowerButtonType:
+ ///
+ /// Check the validity of Context Phase
+ ///
+ if ((Record->ChildContext.PowerButton.Phase < PowerButtonEntry) ||
+ (Record->ChildContext.PowerButton.Phase > PowerButtonExit)
+ ) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ CopyMem ((VOID *) &(Record->SrcDesc), (VOID *) &POWER_BUTTON_SOURCE_DESC, sizeof (PCH_SMM_SOURCE_DESC));
+ Record->ClearSource = NULL;
+ ///
+ /// use default clear source function
+ ///
+ break;
+
+ case PeriodicTimerType:
+ ///
+ /// Check the validity of timer value
+ ///
+ if (DispatchContext->PeriodicTimer.SmiTickInterval <= 0) {
+ goto Error;
+ }
+
+ InsertTailList (&mPrivateData.CallbackDataBase, &Record->Link);
+ MapPeriodicTimerToSrcDesc (DispatchContext, &(Record->SrcDesc));
+ Record->ClearSource = PchSmmPeriodicTimerClearSource;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (CompareSources (&Record->SrcDesc, &NullSourceDesc)) {
+ goto Error;
+ }
+
+ if (Record->ClearSource == NULL) {
+ ///
+ /// Clear the SMI associated w/ the source using the default function
+ ///
+ PchSmmClearSource (&Record->SrcDesc);
+ } else {
+ ///
+ /// This source requires special handling to clear
+ ///
+ Record->ClearSource (&Record->SrcDesc);
+ }
+
+ PchSmmEnableSource (&Record->SrcDesc);
+
+// AMI_OVERRIDE, GPIO_ROUT >>>
+// Added GPIO_ROUT (B0:D31:F0 Reg#B8h) initialization for GPI SMI register.
+{
+ UINT32 GpioRout;
+ UINT32 GpioSmiRout;
+
+ if (Qualified->Type == GpiType) {
+ if (PchSeries == PchH) {
+ GpioRout = (UINT32) (MmioRead32 ( \
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ PCI_FUNCTION_NUMBER_PCH_LPC, \
+ R_PCH_LPC_GPI_ROUT)\
+ ));
+
+ GpioRout &= ~(3 << (Record->ChildContext.Gpi.GpiNum * 2));
+ GpioRout |= (1 << (Record->ChildContext.Gpi.GpiNum * 2));
+
+ MmioWrite32 ( \
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_LPC, \
+ PCI_FUNCTION_NUMBER_PCH_LPC,\
+ R_PCH_LPC_GPI_ROUT), \
+ GpioRout\
+ );
+ }else if(PchSeries == PchLp){
+ if( Record->ChildContext.Gpi.GpiNum >= 32 && Record->ChildContext.Gpi.GpiNum < 48){
+ GpioRout = IoRead32(GPIO_BASE_ADDRESS + R_PCH_LP_LPC_GPI_ROUT1);
+ GpioSmiRout = IoRead32(GPIO_BASE_ADDRESS + R_PCH_LPTLP_ALT_GP_SMI_EN);
+
+ GpioRout |= (1 << (Record->ChildContext.Gpi.GpiNum - 32));
+ GpioSmiRout |= (1 << (Record->ChildContext.Gpi.GpiNum - 32));
+
+ IoWrite32((GPIO_BASE_ADDRESS + R_PCH_LP_LPC_GPI_ROUT1),GpioRout);
+ IoWrite32((GPIO_BASE_ADDRESS + R_PCH_LPTLP_ALT_GP_SMI_EN),GpioSmiRout);
+ }
+ }
+ }
+}
+// AMI_OVERRIDE, GPIO_ROUT <<<
+
+ ///
+ /// Child's handle will be the address linked list link in the record
+ ///
+ *DispatchHandle = (EFI_HANDLE) (&Record->Link);
+
+ return EFI_SUCCESS;
+
+Error:
+ Status = mSmst->SmmFreePool (Record);
+ ///
+ /// DEBUG((EFI_D_ERROR,"Free pool status %d\n", Status ));
+ ///
+ return EFI_INVALID_PARAMETER;
+}
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+EFI_STATUS
+PchSmmCoreUnRegister (
+ IN PCH_SMM_GENERIC_PROTOCOL *This,
+ IN EFI_HANDLE *DispatchHandle
+ )
+{
+ ///
+ /// BOOLEAN SafeToDisable;
+ ///
+ DATABASE_RECORD *RecordToDelete;
+
+ ///
+ /// DATABASE_RECORD *RecordInDb;
+ /// EFI_LIST_NODE *LinkInDb;
+ ///
+ if (DispatchHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RecordToDelete = DATABASE_RECORD_FROM_LINK (DispatchHandle);
+
+ ///
+ /// Take the entry out of the linked list
+ ///
+ if (RecordToDelete->Link.ForwardLink == (LIST_ENTRY *) EFI_BAD_POINTER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RemoveEntryList (&RecordToDelete->Link);
+
+ ///
+ /// See if we can disable the source, reserved for future use since this might
+ /// not be the only criteria to disable
+ ///
+ /// SafeToDisable = TRUE;
+ /// LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+ /// while(!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+ /// RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+ /// if (CompareEnables (&RecordToDelete->SrcDesc, &RecordInDb->SrcDesc)) {
+ /// SafeToDisable = FALSE;
+ /// break;
+ /// }
+ /// LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+ /// }
+ /// if (SafeToDisable) {
+ /// PchSmmDisableSource( &Record->SrcDesc );
+ /// }
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ The callback function to handle subsequent SMIs. This callback will be called by SmmCoreDispatcher.
+
+ @param[in] SmmImageHandle Not used
+ @param[in, out] CommunicationBuffer Not used
+ @param[in, out] SourceSize Not used
+
+ @retval EFI_SUCCESS Function successfully completed
+**/
+EFI_STATUS
+EFIAPI
+PchSmmCoreDispatcher (
+ IN EFI_HANDLE SmmImageHandle,
+ IN OUT VOID *CommunicationBuffer,
+ IN OUT UINTN *SourceSize
+ )
+{
+ ///
+ /// Used to prevent infinite loops
+ ///
+ UINTN EscapeCount;
+
+ BOOLEAN ContextsMatch;
+ BOOLEAN EosSet;
+ BOOLEAN SxChildWasDispatched;
+
+ DATABASE_RECORD *RecordInDb;
+ LIST_ENTRY *LinkInDb;
+ DATABASE_RECORD *RecordToExhaust;
+ LIST_ENTRY *LinkToExhaust;
+
+ PCH_SMM_CONTEXT Context;
+
+ EFI_STATUS Status;
+
+ PCH_SMM_SOURCE_DESC ActiveSource = NULL_SOURCE_DESC_INITIALIZER;
+
+ EscapeCount = 100;
+ ContextsMatch = FALSE;
+ EosSet = FALSE;
+ SxChildWasDispatched = FALSE;
+ Status = EFI_SUCCESS;
+
+ if (!IsListEmpty (&mPrivateData.CallbackDataBase)) {
+ ///
+ /// We have children registered w/ us -- continue
+ ///
+ while ((!EosSet) && (EscapeCount > 0)) {
+ EscapeCount--;
+
+ LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+
+ while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+ RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+
+ ///
+ /// look for the first active source
+ ///
+ if (!SourceIsActive (&RecordInDb->SrcDesc)) {
+ ///
+ /// Didn't find the source yet, keep looking
+ ///
+ LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+
+ ///
+ /// if it's the last one, try to clear EOS
+ ///
+ if (IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+ EosSet = PchSmmSetAndCheckEos ();
+ }
+ } else {
+ ///
+ /// We found a source. If this is a sleep type, we have to go to
+ /// appropriate sleep state anyway.No matter there is sleep child or not
+ ///
+ if (RecordInDb->ProtocolType == SxType) {
+ SxChildWasDispatched = TRUE;
+ }
+ ///
+ /// "cache" the source description and don't query I/O anymore
+ ///
+ CopyMem ((VOID *) &ActiveSource, (VOID *) &(RecordInDb->SrcDesc), sizeof (PCH_SMM_SOURCE_DESC));
+ LinkToExhaust = LinkInDb;
+
+ ///
+ /// exhaust the rest of the queue looking for the same source
+ ///
+ while (!IsNull (&mPrivateData.CallbackDataBase, LinkToExhaust)) {
+ RecordToExhaust = DATABASE_RECORD_FROM_LINK (LinkToExhaust);
+ ///
+ /// RecordToExhaust->Link might be removed (unregistered) by Callback function, and then the
+ /// system will hang in ASSERT() while calling GetNextNode().
+ /// To prevent the issue, we need to get next record in DB here (before Callback function).
+ ///
+ LinkToExhaust = GetNextNode (&mPrivateData.CallbackDataBase, &RecordToExhaust->Link);
+
+ if (CompareSources (&RecordToExhaust->SrcDesc, &ActiveSource)) {
+ ///
+ /// These source descriptions are equal, so this callback should be
+ /// dispatched.
+ ///
+ if (RecordToExhaust->ContextFunctions.GetContext != NULL) {
+ ///
+ /// This child requires that we get a calling context from
+ /// hardware and compare that context to the one supplied
+ /// by the child.
+ ///
+ ASSERT (RecordToExhaust->ContextFunctions.CmpContext != NULL);
+
+ ///
+ /// Make sure contexts match before dispatching event to child
+ ///
+ RecordToExhaust->ContextFunctions.GetContext (RecordToExhaust, &Context);
+ ContextsMatch = RecordToExhaust->ContextFunctions.CmpContext (&Context, &RecordToExhaust->ChildContext);
+
+ } else {
+ ///
+ /// This child doesn't require any more calling context beyond what
+ /// it supplied in registration. Simply pass back what it gave us.
+ ///
+ ASSERT (RecordToExhaust->Callback != NULL);
+ Context = RecordToExhaust->ChildContext;
+ ContextsMatch = TRUE;
+ }
+
+ if (ContextsMatch) {
+
+ ASSERT (RecordToExhaust->Callback != NULL);
+ PERF_START_EX (NULL, L"SmmFunction", NULL, AsmReadTsc(), RecordToExhaust->ProtocolType);
+ RecordToExhaust->Callback ((EFI_HANDLE) & RecordToExhaust->Link, &Context);
+ PERF_END_EX (NULL, L"SmmFunction", NULL, AsmReadTsc(), RecordToExhaust->ProtocolType);
+ if (RecordToExhaust->ProtocolType == SxType) {
+ SxChildWasDispatched = TRUE;
+ }
+ }
+ }
+ }
+
+ if (RecordInDb->ClearSource == NULL) {
+ ///
+ /// Clear the SMI associated w/ the source using the default function
+ ///
+ PchSmmClearSource (&ActiveSource);
+ } else {
+ ///
+ /// This source requires special handling to clear
+ ///
+ RecordInDb->ClearSource (&ActiveSource);
+ }
+ ///
+ /// Also, try to clear EOS
+ ///
+ EosSet = PchSmmSetAndCheckEos ();
+ ///
+ /// Queue is empty, reset the search
+ ///
+ break;
+ }
+ }
+ }
+ }
+ ///
+ /// If you arrive here, there are two possible reasons:
+ /// (1) you've got problems with clearing the SMI status bits in the
+ /// ACPI table. If you don't properly clear the SMI bits, then you won't be able to set the
+ /// EOS bit. If this happens too many times, the loop exits.
+ /// (2) there was a SMM communicate for callback messages that was received prior
+ /// to this driver.
+ /// If there is an asynchronous SMI that occurs while processing the Callback, let
+ /// all of the drivers (including this one) have an opportunity to scan for the SMI
+ /// and handle it.
+ /// If not, we don't want to exit and have the foreground app. clear EOS without letting
+ /// these other sources get serviced.
+ ///
+ /// This assert is not valid with CSM legacy solution because it generates software SMI
+ /// to test for legacy USB support presence.
+ /// This may not be illegal, so we cannot assert at this time.
+ ///
+ /// ASSERT (EscapeCount > 0);
+ ///
+ if (SxChildWasDispatched) {
+ ///
+ /// A child of the SmmSxDispatch protocol was dispatched during this call;
+ /// put the system to sleep.
+ ///
+ PchSmmSxGoToSleep ();
+ }
+
+ return Status;
+
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c
new file mode 100644
index 0000000..e9b16f9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmGpi.c
@@ -0,0 +1,101 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm Gpi dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+#define LPTH_GPI_INIT_ELEMENT(num) { \
+ PCH_SMM_NO_FLAGS, \
+ { \
+ { \
+ { \
+ ACPI_ADDR_TYPE, R_PCH_LPTH_ALT_GP_SMI_EN \
+ }, \
+ S_PCH_LPTH_ALT_GP_SMI_EN, num, \
+ }, \
+ NULL_BIT_DESC_INITIALIZER \
+ }, \
+ { \
+ { \
+ { \
+ ACPI_ADDR_TYPE, R_PCH_LPTH_ALT_GP_SMI_STS \
+ }, \
+ S_PCH_LPTH_ALT_GP_SMI_STS, (num), \
+ }, \
+ } \
+ }
+
+#define LPTLP_GPI_INIT_ELEMENT(num) { \
+ PCH_SMM_NO_FLAGS, \
+ { \
+ { \
+ { \
+ GPIO_ADDR_TYPE, R_PCH_LPTLP_ALT_GP_SMI_EN \
+ }, \
+ S_PCH_LPTLP_ALT_GP_SMI_EN, num, \
+ }, \
+ NULL_BIT_DESC_INITIALIZER \
+ }, \
+ { \
+ { \
+ { \
+ GPIO_ADDR_TYPE, R_PCH_LPTLP_ALT_GP_SMI_STS \
+ }, \
+ S_PCH_LPTLP_ALT_GP_SMI_STS, (num), \
+ }, \
+ } \
+ }
+
+const PCH_SMM_SOURCE_DESC LPTH_GPI_SOURCE_DESC[NUM_SUPPORTED_GPIS] = {
+ LPTH_GPI_INIT_ELEMENT(0),
+ LPTH_GPI_INIT_ELEMENT(1),
+ LPTH_GPI_INIT_ELEMENT(2),
+ LPTH_GPI_INIT_ELEMENT(3),
+ LPTH_GPI_INIT_ELEMENT(4),
+ LPTH_GPI_INIT_ELEMENT(5),
+ LPTH_GPI_INIT_ELEMENT(6),
+ LPTH_GPI_INIT_ELEMENT(7),
+ LPTH_GPI_INIT_ELEMENT(8),
+ LPTH_GPI_INIT_ELEMENT(9),
+ LPTH_GPI_INIT_ELEMENT(10),
+ LPTH_GPI_INIT_ELEMENT(11),
+ LPTH_GPI_INIT_ELEMENT(12),
+ LPTH_GPI_INIT_ELEMENT(13),
+ LPTH_GPI_INIT_ELEMENT(14),
+ LPTH_GPI_INIT_ELEMENT(15),
+};
+
+const PCH_SMM_SOURCE_DESC LPTLP_GPI_SOURCE_DESC[NUM_SUPPORTED_GPIS] = {
+ LPTLP_GPI_INIT_ELEMENT(0),
+ LPTLP_GPI_INIT_ELEMENT(1),
+ LPTLP_GPI_INIT_ELEMENT(2),
+ LPTLP_GPI_INIT_ELEMENT(3),
+ LPTLP_GPI_INIT_ELEMENT(4),
+ LPTLP_GPI_INIT_ELEMENT(5),
+ LPTLP_GPI_INIT_ELEMENT(6),
+ LPTLP_GPI_INIT_ELEMENT(7),
+ LPTLP_GPI_INIT_ELEMENT(8),
+ LPTLP_GPI_INIT_ELEMENT(9),
+ LPTLP_GPI_INIT_ELEMENT(10),
+ LPTLP_GPI_INIT_ELEMENT(11),
+ LPTLP_GPI_INIT_ELEMENT(12),
+ LPTLP_GPI_INIT_ELEMENT(13),
+ LPTLP_GPI_INIT_ELEMENT(14),
+ LPTLP_GPI_INIT_ELEMENT(15),
+};
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c
new file mode 100644
index 0000000..062f518
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.c
@@ -0,0 +1,317 @@
+/** @file
+ Helper functions for PCH SMM dispatcher.
+
+@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 "PchSmmHelpers.h"
+
+///
+/// #define BIT_ZERO 0x00000001
+///
+const UINT32 BIT_ZERO = 0x00000001;
+
+///
+/// SUPPORT / HELPER FUNCTIONS (PCH version-independent)
+///
+
+/**
+ Compare 2 SMM source descriptors' enable settings.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The enable settings of the 2 SMM source descriptors are identical.
+ @retval FALSE The enable settings of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareEnables (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ )
+{
+ BOOLEAN IsEqual;
+ UINTN loopvar;
+
+ IsEqual = TRUE;
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+ ///
+ /// It's okay to compare a NULL bit description to a non-NULL bit description.
+ /// They are unequal and these tests will generate the correct result.
+ ///
+ if (Src1->En[loopvar].Bit != Src2->En[loopvar].Bit ||
+ Src1->En[loopvar].Reg.Type != Src2->En[loopvar].Reg.Type ||
+ Src1->En[loopvar].Reg.Data.raw != Src2->En[loopvar].Reg.Data.raw
+ ) {
+ IsEqual = FALSE;
+ break;
+ ///
+ /// out of for loop
+ ///
+ }
+ }
+
+ return IsEqual;
+}
+
+/**
+ Compare 2 SMM source descriptors' statuses.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The statuses of the 2 SMM source descriptors are identical.
+ @retval FALSE The statuses of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareStatuses (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ )
+{
+ BOOLEAN IsEqual;
+ UINTN loopvar;
+
+ IsEqual = TRUE;
+
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+ ///
+ /// It's okay to compare a NULL bit description to a non-NULL bit description.
+ /// They are unequal and these tests will generate the correct result.
+ ///
+ if (Src1->Sts[loopvar].Bit != Src2->Sts[loopvar].Bit ||
+ Src1->Sts[loopvar].Reg.Type != Src2->Sts[loopvar].Reg.Type ||
+ Src1->Sts[loopvar].Reg.Data.raw != Src2->Sts[loopvar].Reg.Data.raw
+ ) {
+ IsEqual = FALSE;
+ break;
+ ///
+ /// out of for loop
+ ///
+ }
+ }
+
+ return IsEqual;
+}
+
+/**
+ Compare 2 SMM source descriptors, based on Enable settings and Status settings of them.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The 2 SMM source descriptors are identical.
+ @retval FALSE The 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareSources (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ )
+{
+ return (BOOLEAN) (CompareEnables (Src1, Src2) && CompareStatuses (Src1, Src2));
+}
+
+/**
+ Check if an SMM source is active.
+
+ @param[in] Src Pointer to the PCH SMI source description table
+
+ @retval TRUE It is active.
+ @retval FALSE It is inactive.
+**/
+BOOLEAN
+SourceIsActive (
+ const IN PCH_SMM_SOURCE_DESC *Src
+ )
+{
+ BOOLEAN IsActive;
+ UINTN loopvar;
+
+ BOOLEAN SciEn;
+
+ IsActive = TRUE;
+
+ SciEn = PchSmmGetSciEn ();
+
+ if ((Src->Flags & PCH_SMM_SCI_EN_DEPENDENT) && (SciEn)) {
+ ///
+ /// This source is dependent on SciEn, and SciEn == 1. An ACPI OS is present,
+ /// so we shouldn't do anything w/ this source until SciEn == 0.
+ ///
+ IsActive = FALSE;
+
+ } else {
+ ///
+ /// Read each bit desc from hardware and make sure it's a one
+ ///
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+
+ if (!IS_BIT_DESC_NULL (Src->En[loopvar])) {
+
+ if (ReadBitDesc (&Src->En[loopvar]) == 0) {
+ IsActive = FALSE;
+ break;
+ ///
+ /// out of for loop
+ ///
+ }
+
+ }
+ }
+
+ if (IsActive) {
+ ///
+ /// Read each bit desc from hardware and make sure it's a one
+ ///
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+
+ if (!IS_BIT_DESC_NULL (Src->Sts[loopvar])) {
+
+ if (ReadBitDesc (&Src->Sts[loopvar]) == 0) {
+ IsActive = FALSE;
+ break;
+ ///
+ /// out of for loop
+ ///
+ }
+
+ }
+ }
+ }
+ }
+
+ return IsActive;
+}
+
+/**
+ Enable the SMI source event by set the SMI enable bit, this function would also clear SMI
+ status bit to make initial state is correct
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmEnableSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ UINTN loopvar;
+
+ ///
+ /// Set enables to 1 by writing a 1
+ ///
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+ if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
+ WriteBitDesc (&SrcDesc->En[loopvar], 1, FALSE);
+ }
+ }
+ ///
+ /// Clear statuses to 0 by writing a 1
+ ///
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+ if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
+ WriteBitDesc (&SrcDesc->Sts[loopvar], 1, TRUE);
+ }
+ }
+}
+
+/**
+ Disable the SMI source event by clear the SMI enable bit
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmDisableSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ UINTN loopvar;
+
+ for (loopvar = 0; loopvar < NUM_EN_BITS; loopvar++) {
+ if (!IS_BIT_DESC_NULL (SrcDesc->En[loopvar])) {
+ WriteBitDesc (&SrcDesc->En[loopvar], 0, FALSE);
+ }
+ }
+}
+
+/**
+ Clear the SMI status bit by set the source bit of SMI status register
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmClearSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ UINTN loopvar;
+
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+ if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
+ WriteBitDesc (&SrcDesc->Sts[loopvar], 1, TRUE);
+ }
+ }
+}
+
+/**
+ Sets the source to a 1 and then waits for it to clear.
+ Be very careful when calling this function -- it will not
+ ASSERT. An acceptable case to call the function is when
+ waiting for the NEWCENTURY_STS bit to clear (which takes
+ 3 RTCCLKs).
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmClearSourceAndBlock (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ UINTN loopvar;
+ BOOLEAN IsSet;
+
+ for (loopvar = 0; loopvar < NUM_STS_BITS; loopvar++) {
+
+ if (!IS_BIT_DESC_NULL (SrcDesc->Sts[loopvar])) {
+ ///
+ /// Write the bit
+ ///
+ WriteBitDesc (&SrcDesc->Sts[loopvar], 1, TRUE);
+
+ ///
+ /// Don't return until the bit actually clears.
+ ///
+ IsSet = TRUE;
+ while (IsSet) {
+ IsSet = ReadBitDesc (&SrcDesc->Sts[loopvar]);
+ ///
+ /// IsSet will eventually clear -- or else we'll have
+ /// an infinite loop.
+ ///
+ }
+ }
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h
new file mode 100644
index 0000000..24ef5f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmHelpers.h
@@ -0,0 +1,155 @@
+/** @file
+ Helper functions for PCH SMM
+
+@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
+**/
+#ifndef PCH_SMM_HELPERS_H
+#define PCH_SMM_HELPERS_H
+
+#include "PchSmm.h"
+#include "PchxSmmHelpers.h"
+
+//
+// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// SUPPORT / HELPER FUNCTIONS (PCH version-independent)
+//
+
+/**
+ Publish SMI Dispatch protocols.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+PchSmmPublishDispatchProtocols (
+ VOID
+ );
+
+/**
+ Compare 2 SMM source descriptors' enable settings.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The enable settings of the 2 SMM source descriptors are identical.
+ @retval FALSE The enable settings of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareEnables (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ );
+
+/**
+ Compare 2 SMM source descriptors' statuses.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The statuses of the 2 SMM source descriptors are identical.
+ @retval FALSE The statuses of the 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareStatuses (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ );
+
+/**
+ Compare 2 SMM source descriptors, based on Enable settings and Status settings of them.
+
+ @param[in] Src1 Pointer to the PCH SMI source description table 1
+ @param[in] Src2 Pointer to the PCH SMI source description table 2
+
+ @retval TRUE The 2 SMM source descriptors are identical.
+ @retval FALSE The 2 SMM source descriptors are not identical.
+**/
+BOOLEAN
+CompareSources (
+ const IN PCH_SMM_SOURCE_DESC *Src1,
+ const IN PCH_SMM_SOURCE_DESC *Src2
+ );
+
+/**
+ Check if an SMM source is active.
+
+ @param[in] Src Pointer to the PCH SMI source description table
+
+ @retval TRUE It is active.
+ @retval FALSE It is inactive.
+**/
+BOOLEAN
+SourceIsActive (
+ const IN PCH_SMM_SOURCE_DESC *Src
+ );
+
+/**
+ Enable the SMI source event by set the SMI enable bit, this function would also clear SMI
+ status bit to make initial state is correct
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmEnableSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ Disable the SMI source event by clear the SMI enable bit
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmDisableSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ Clear the SMI status bit by set the source bit of SMI status register
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmClearSource (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+/**
+ Sets the source to a 1 and then waits for it to clear.
+ Be very careful when calling this function -- it will not
+ ASSERT. An acceptable case to call the function is when
+ waiting for the NEWCENTURY_STS bit to clear (which takes
+ 3 RTCCLKs).
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+PchSmmClearSourceAndBlock (
+ const PCH_SMM_SOURCE_DESC *SrcDesc
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c
new file mode 100644
index 0000000..5ecb7d3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmIchn.c
@@ -0,0 +1,2425 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm Ichn dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+#define PCH_RCRB_BASE_NEED_FIX 0
+
+PCH_SMM_SOURCE_DESC ICHN_H_SOURCE_DESCS[NUM_ICHN_TYPES] = {
+ ///
+ /// IchnMch
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_DMISMI
+ }
+ }
+ },
+ ///
+ /// IchnPme
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_EN
+ },
+ S_PCH_ACPI_GPE0a_EN,
+ N_PCH_ACPI_GPE0a_EN_PME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_STS
+ },
+ S_PCH_ACPI_GPE0a_STS,
+ N_PCH_ACPI_GPE0a_STS_PME
+ }
+ }
+ },
+ ///
+ /// IchnRtcAlarm
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_EN
+ },
+ S_PCH_ACPI_PM1_EN,
+ N_PCH_ACPI_PM1_EN_RTC
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_STS
+ },
+ S_PCH_ACPI_PM1_STS,
+ N_PCH_ACPI_PM1_STS_RTC
+ }
+ }
+ },
+ ///
+ /// IchnRingIndicate
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_EN
+ },
+ S_PCH_ACPI_GPE0a_EN,
+ N_PCH_ACPI_GPE0a_EN_RI
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_STS
+ },
+ S_PCH_ACPI_GPE0a_STS,
+ N_PCH_ACPI_GPE0a_STS_RI
+ }
+ }
+ },
+ ///
+ /// IchnAc97Wake
+ /// ICH8M has removed AC97 but IchnAc97Wake is the enumed index reserved in framework SmmIchnDispatch protocol,
+ /// we just fill in invalid initializer and not use it.
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnSerialIrq
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_SERIRQ
+ }
+ }
+ },
+ ///
+ /// IchnY2KRollover
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_NEWCENTURY
+ }
+ }
+ },
+ ///
+ /// IchnTcoTimeout
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_TIMEOUT
+ }
+ }
+ },
+ ///
+ /// IchnOsTco
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_SW_TCO_SMI
+ }
+ }
+ },
+ ///
+ /// IchnNmi
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_CNT)
+ },
+ S_PCH_TCO1_CNT,
+ N_PCH_TCO_CNT_NMI2SMI_EN
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_NMI2SMI
+ }
+ }
+ },
+ ///
+ /// IchnIntruderDetect
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO2_CNT)
+ },
+ S_PCH_TCO2_CNT,
+ N_PCH_TCO2_CNT_INTRD_SEL
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO2_STS)
+ },
+ S_PCH_TCO2_STS,
+ N_PCH_TCO2_STS_INTRD_DET
+ }
+ }
+ },
+ ///
+ /// IchnBiosWp
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_LPC << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_LPC << 8) |
+ R_PCH_LPC_BIOS_CNTL
+ )
+ },
+ S_PCH_LPC_BIOS_CNTL,
+ N_PCH_LPC_BIOS_CNTL_BLE
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_BIOSWR
+ }
+ }
+ },
+ ///
+ /// IchnMcSmi
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_MCSMI
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_MCSMI
+ }
+ }
+ },
+ ///
+ /// IchnPmeB0
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_EN
+ },
+ S_PCH_ACPI_GPE0a_EN,
+ N_PCH_ACPI_GPE0a_EN_PME_B0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0a_STS
+ },
+ S_PCH_ACPI_GPE0a_STS,
+ N_PCH_ACPI_GPE0a_STS_PME_B0
+ }
+ }
+ },
+ ///
+ /// IchnThrmSts (THRM# signal no longer existed in PCH)
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnSmBus
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_SMBUS
+ }
+ }
+ },
+ ///
+ /// IchnIntelUsb2
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_INTEL_USB2
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_INTEL_USB2
+ }
+ }
+ },
+ ///
+ /// IchnMonSmi7
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi6
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi5
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi4
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap13
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap12, KBC_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 12
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap11
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap10
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap9, PIRQDH_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 9
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap8, PIRQCG_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 8
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap7, PIRQBF_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 7
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap6, PIRQAE_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 6
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap5
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap3
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap2
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap1
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap0, IDE_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 0
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 3 monitor,
+ /// The "PCH_RCRB_BASE_NEED_FIX" should be fixed since the RCRB base should get from the RCBA register filled by platform module.
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_3
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 3
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 2 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_2
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 2
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 1 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_1
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 1
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 0 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_0
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 0
+ }
+ }
+ }
+};
+
+PCH_SMM_SOURCE_DESC ICHN_LP_SOURCE_DESCS[NUM_ICHN_TYPES] = {
+ ///
+ /// IchnMch
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_DMISMI
+ }
+ }
+ },
+ ///
+ /// IchnPme
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_EN_127_96
+ },
+ S_PCH_ACPI_GPE0_EN_127_96,
+ N_PCH_ACPI_GPE0_EN_127_96_PME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_STS_127_96
+ },
+ S_PCH_ACPI_GPE0_STS_127_96,
+ N_PCH_ACPI_GPE0_STS_127_96_PME
+ }
+ }
+ },
+ ///
+ /// IchnRtcAlarm
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_EN
+ },
+ S_PCH_ACPI_PM1_EN,
+ N_PCH_ACPI_PM1_EN_RTC
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_STS
+ },
+ S_PCH_ACPI_PM1_STS,
+ N_PCH_ACPI_PM1_STS_RTC
+ }
+ }
+ },
+ ///
+ /// IchnRingIndicate
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_EN_127_96
+ },
+ S_PCH_ACPI_GPE0_EN_127_96,
+ N_PCH_ACPI_GPE0_EN_127_96_RI
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_STS_127_96
+ },
+ S_PCH_ACPI_GPE0_STS_127_96,
+ N_PCH_ACPI_GPE0_STS_127_96_RI
+ }
+ }
+ },
+ ///
+ /// IchnAc97Wake
+ /// ICH8M has removed AC97 but IchnAc97Wake is the enumed index reserved in framework SmmIchnDispatch protocol,
+ /// we just fill in invalid initializer and not use it.
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnSerialIrq
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_SERIRQ
+ }
+ }
+ },
+ ///
+ /// IchnY2KRollover
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_NEWCENTURY
+ }
+ }
+ },
+ ///
+ /// IchnTcoTimeout
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_TIMEOUT
+ }
+ }
+ },
+ ///
+ /// IchnOsTco
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_SW_TCO_SMI
+ }
+ }
+ },
+ ///
+ /// IchnNmi
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_CNT)
+ },
+ S_PCH_TCO1_CNT,
+ N_PCH_TCO_CNT_NMI2SMI_EN
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_NMI2SMI
+ }
+ }
+ },
+ ///
+ /// IchnIntruderDetect
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO2_CNT)
+ },
+ S_PCH_TCO2_CNT,
+ N_PCH_TCO2_CNT_INTRD_SEL
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO2_STS)
+ },
+ S_PCH_TCO2_STS,
+ N_PCH_TCO2_STS_INTRD_DET
+ }
+ }
+ },
+ ///
+ /// IchnBiosWp
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_TCO
+ },
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_LPC << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_LPC << 8) |
+ R_PCH_LPC_BIOS_CNTL
+ )
+ },
+ S_PCH_LPC_BIOS_CNTL,
+ N_PCH_LPC_BIOS_CNTL_BLE
+ }
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ (PCH_TCO_BASE + R_PCH_TCO1_STS)
+ },
+ S_PCH_TCO1_STS,
+ N_PCH_TCO1_STS_BIOSWR
+ }
+ }
+ },
+ ///
+ /// IchnMcSmi
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_MCSMI
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_MCSMI
+ }
+ }
+ },
+ ///
+ /// IchnPmeB0
+ ///
+ {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_EN_127_96
+ },
+ S_PCH_ACPI_GPE0_EN_127_96,
+ N_PCH_ACPI_GPE0_EN_127_96_PME_B0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_GPE0_STS_127_96
+ },
+ S_PCH_ACPI_GPE0_STS_127_96,
+ N_PCH_ACPI_GPE0_STS_127_96_PME_B0
+ }
+ }
+ },
+ ///
+ /// IchnThrmSts (THRM# signal no longer existed in PCH)
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnSmBus
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_SMBUS
+ }
+ }
+ },
+ ///
+ /// IchnIntelUsb2
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_INTEL_USB2
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_INTEL_USB2
+ }
+ }
+ },
+ ///
+ /// IchnMonSmi7
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi6
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi5
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnMonSmi4
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap13
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap12, KBC_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 12
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap11
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap10
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap9, PIRQDH_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 9
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap8, PIRQCG_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 8
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap7, PIRQBF_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 7
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap6, PIRQAE_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 6
+ }
+ }
+ },
+ ///
+ /// IchnDevTrap5
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap3
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap2
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap1
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ NULL_BIT_DESC_INITIALIZER
+ }
+ },
+ ///
+ /// IchnDevTrap0, IDE_ACT_STS
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_DEVACT_STS
+ },
+ S_PCH_DEVACT_STS,
+ 0
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 3 monitor,
+ /// The "PCH_RCRB_BASE_NEED_FIX" should be fixed since the RCRB base should get from the RCBA register filled by platform module.
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_3
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 3
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 2 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_2
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 2
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 1 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_1
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 1
+ }
+ }
+ },
+ ///
+ /// PCH I/O Trap register 0 monitor
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_IO_TRAP_0
+ },
+ 8,
+ 0
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ MEMORY_MAPPED_IO_ADDRESS_TYPE,
+ PCH_RCRB_BASE_NEED_FIX + R_PCH_RCRB_TRSR
+ },
+ 1,
+ 0
+ }
+ }
+ }
+};
+
+PCH_SMM_SOURCE_DESC ICHN_EX_SOURCE_DESCS[IchnExTypeMAX - IchnExPciExpress] = {
+ ///
+ /// IchnExPciExpress
+ ///
+ NULL_SOURCE_DESC_INITIALIZER,
+ ///
+ /// IchnExMonitor
+ ///
+ NULL_SOURCE_DESC_INITIALIZER,
+ ///
+ /// IchnExSpi
+ ///
+ NULL_SOURCE_DESC_INITIALIZER,
+ ///
+ /// IchnExQRT
+ ///
+ NULL_SOURCE_DESC_INITIALIZER,
+ ///
+ /// IchnExGpioUnlock
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_GPIO_UNLOCK
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_GPIO_UNLOCK
+ }
+ }
+ },
+ ///
+ /// IchnExTmrOverflow
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_EN
+ },
+ S_PCH_ACPI_PM1_EN,
+ N_PCH_ACPI_PM1_EN_TMROF
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_STS
+ },
+ S_PCH_ACPI_PM1_STS,
+ N_PCH_ACPI_PM1_STS_TMROF
+ }
+ }
+ },
+ ///
+ /// IchnExPcie0Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie1Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie2Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie3Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie4Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie5Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie6Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie7Hotplug
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPPDM
+ }
+ }
+ },
+ ///
+ /// IchnExPcie0LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie1LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie2LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie3LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie4LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_5 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie5LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_6 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie6LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_7 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ },
+ ///
+ /// IchnExPcie7LinkActive
+ ///
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8 << 8) |
+ R_PCH_PCIE_MPC
+ )
+ },
+ S_PCH_PCIE_MPC,
+ N_PCH_PCIE_MPC_HPME
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ PCIE_ADDR_TYPE,
+ (
+ (DEFAULT_PCI_BUS_NUMBER_PCH << 24) |
+ (PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS << 16) |
+ (PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_8 << 8) |
+ R_PCH_PCIE_SMSCS
+ )
+ },
+ S_PCH_PCIE_SMSCS,
+ N_PCH_PCIE_SMSCS_HPLAS
+ }
+ }
+ }
+};
+
+///
+/// TCO_STS bit that needs to be cleared
+///
+PCH_SMM_SOURCE_DESC TCO_STS = {
+ PCH_SMM_NO_FLAGS,
+ {
+ NULL_BIT_DESC_INITIALIZER,
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_TCO
+ }
+ }
+};
+
+/**
+ Clear the SMI status bit after the SMI handling is done
+
+ @param[in] SrcDesc Pointer to the PCH SMI source description table
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchSmmIchnClearSource (
+ PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ if ((
+ (SrcDesc->Sts[0].Reg.Data.acpi == PCH_TCO_BASE + R_PCH_TCO1_STS) &&
+ (SrcDesc->Sts[0].Bit == N_PCH_TCO1_STS_NEWCENTURY)
+ ) ||
+ (
+ (SrcDesc->Sts[0].Reg.Data.acpi == PCH_TCO_BASE + R_PCH_TCO2_STS) &&
+ (SrcDesc->Sts[0].Bit == N_PCH_TCO2_STS_INTRD_DET)
+ )
+ ) {
+ ///
+ /// This is the Y2K rollover bit and requires special handling
+ ///
+ PchSmmClearSourceAndBlock (SrcDesc);
+ } else {
+ PchSmmClearSource (SrcDesc);
+ }
+ ///
+ /// Any TCO-based status bits require special handling.
+ /// SMI_STS.TCO_STS must be cleared in addition to the status bit in the TCO registers
+ ///
+ PchSmmClearSource (&TCO_STS);
+}
+
+/**
+ Fix the base address of the source regs and status regs.
+ Since Base should get from register filled by platform modules already.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+PchSmmIchnFixSourceBase (
+ VOID
+ )
+{
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ ///
+ /// We need to fix the IoTrap item's RCRB base,
+ ///
+ if (PchSeries == PchLp) {
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap3].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_3);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap3].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap2].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_2);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap2].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap1].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_1);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap1].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap0].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_0);
+ ICHN_LP_SOURCE_DESCS[IchnIoTrap0].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ } else if (PchSeries == PchH) {
+ ICHN_H_SOURCE_DESCS[IchnIoTrap3].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_3);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap3].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap2].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_2);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap2].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap1].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_1);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap1].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap0].En[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_IO_TRAP_0);
+ ICHN_H_SOURCE_DESCS[IchnIoTrap0].Sts[0].Reg.Data.mem = (MEM_ADDR) (PCH_RCRB_BASE + R_PCH_RCRB_TRSR);
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
new file mode 100644
index 0000000..ee554f7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPeriodicTimer.c
@@ -0,0 +1,519 @@
+/** @file
+ File to contain all the hardware specific stuff for the Periodical Timer dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+typedef enum {
+ PERIODIC_TIMER= 0,
+ SWSMI_TIMER,
+ NUM_TIMERS
+} SUPPORTED_TIMER;
+
+typedef struct _TIMER_INTERVAL {
+ UINT64 Interval;
+ UINT8 AssociatedTimer;
+} TIMER_INTERVAL;
+
+#define NUM_INTERVALS 8
+
+//
+// Time constants, in 100 nano-second units
+//
+#define TIME_64s 640000000 ///< 64 s
+#define TIME_32s 320000000 ///< 32 s
+#define TIME_16s 160000000 ///< 16 s
+#define TIME_8s 80000000 ///< 8 s
+#define TIME_64ms 640000 ///< 64 ms
+#define TIME_32ms 320000 ///< 32 ms
+#define TIME_16ms 160000 ///< 16 ms
+#define TIME_1_5ms 15000 ///< 1.5 ms
+
+typedef enum {
+ INDEX_TIME_64s = 0,
+ INDEX_TIME_32s,
+ INDEX_TIME_16s,
+ INDEX_TIME_8s,
+ INDEX_TIME_64ms,
+ INDEX_TIME_32ms,
+ INDEX_TIME_16ms,
+ INDEX_TIME_1_5ms,
+ INDEX_TIME_MAX
+} TIMER_INTERVAL_INDEX;
+
+static TIMER_INTERVAL mSmmPeriodicTimerIntervals[NUM_INTERVALS] = {
+ {
+ TIME_64s,
+ PERIODIC_TIMER
+ },
+ {
+ TIME_32s,
+ PERIODIC_TIMER
+ },
+ {
+ TIME_16s,
+ PERIODIC_TIMER
+ },
+ {
+ TIME_8s,
+ PERIODIC_TIMER
+ },
+ {
+ TIME_64ms,
+ SWSMI_TIMER
+ },
+ {
+ TIME_32ms,
+ SWSMI_TIMER
+ },
+ {
+ TIME_16ms,
+ SWSMI_TIMER
+ },
+ {
+ TIME_1_5ms,
+ SWSMI_TIMER
+ },
+};
+
+typedef struct _TIMER_INFO {
+ UINTN NumChildren; ///< number of children using this timer
+ UINT64 MinReqInterval; ///< minimum interval required by children
+ UINTN CurrentSetting; ///< interval this timer is set at right now (index into interval table)
+} TIMER_INFO;
+
+TIMER_INFO mTimers[NUM_TIMERS];
+
+PCH_SMM_SOURCE_DESC mTIMER_SOURCE_DESCS[NUM_TIMERS] = {
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_PERIODIC
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_PERIODIC
+ }
+ }
+ },
+ {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_SWSMI_TMR
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_SWSMI_TMR
+ }
+ }
+ }
+};
+
+VOID
+PchSmmPeriodicTimerProgramTimers (
+ VOID
+ );
+
+/**
+ Convert the dispatch context to the timer interval, this function will assert if then either:
+ (1) The context contains an invalid interval
+ (2) The timer interval table is corrupt
+
+ @param[in] DispatchContext The pointer to the Dispatch Context
+
+ @retval TIMER_INTERVAL The timer interval of input dispatch context
+**/
+TIMER_INTERVAL *
+ContextToTimerInterval (
+ IN PCH_SMM_CONTEXT *DispatchContext
+ )
+{
+ UINTN loopvar;
+
+ ///
+ /// Determine which timer this child is using
+ ///
+ for (loopvar = 0; loopvar < NUM_INTERVALS; loopvar++) {
+ if (((DispatchContext->PeriodicTimer.SmiTickInterval == 0) &&
+ (DispatchContext->PeriodicTimer.Period >= mSmmPeriodicTimerIntervals[loopvar].Interval)) ||
+ (DispatchContext->PeriodicTimer.SmiTickInterval == mSmmPeriodicTimerIntervals[loopvar].Interval)) {
+ return &mSmmPeriodicTimerIntervals[loopvar];
+ }
+ }
+ ///
+ /// If this assertion fires, then either:
+ /// (1) the context contains an invalid interval
+ /// (2) the timer interval table is corrupt
+ ///
+ ASSERT (FALSE);
+
+ return NULL;
+}
+
+/**
+ Figure out which timer the child is requesting and
+ send back the source description
+
+ @param[in] DispatchContext The pointer to the Dispatch Context instances
+ @param[out] SrcDesc The pointer to the source description
+
+ @retval None
+**/
+VOID
+MapPeriodicTimerToSrcDesc (
+ IN PCH_SMM_CONTEXT *DispatchContext,
+ OUT PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ TIMER_INTERVAL *TimerInterval;
+
+ ///
+ /// Figure out which timer the child is requesting and
+ /// send back the source description
+ ///
+ TimerInterval = ContextToTimerInterval (DispatchContext);
+ if (TimerInterval == NULL) {
+ return;
+ }
+
+ CopyMem (
+ (VOID *) SrcDesc,
+ (VOID *) (&mTIMER_SOURCE_DESCS[TimerInterval->AssociatedTimer]),
+ sizeof (PCH_SMM_SOURCE_DESC)
+ );
+
+ ///
+ /// Program the value of the interval into hardware
+ ///
+ PchSmmPeriodicTimerProgramTimers ();
+}
+
+/**
+ Update the elapsed time from the Interval data of DATABASE_RECORD
+
+ @param[in] Record The pointer to the DATABASE_RECORD.
+ @param[out] HwContext The Context to be updated.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PeriodicTimerGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *HwContext
+ )
+{
+ TIMER_INTERVAL *TimerInterval;
+
+ ASSERT (Record->ProtocolType == PeriodicTimerType);
+
+ TimerInterval = ContextToTimerInterval (&Record->ChildContext);
+ if (TimerInterval == NULL) {
+ return;
+ }
+ ///
+ /// Ignore the hardware context. It's not required for this protocol.
+ /// Instead, just increment the child's context.
+ /// Update the elapsed time w/ the data from our tables
+ ///
+ Record->ChildContext.PeriodicTimer.ElapsedTime += TimerInterval->Interval;
+ *HwContext = Record->ChildContext;
+}
+
+/**
+ Check whether Periodic Timer of two contexts match
+
+ @param[in] Context1 Context 1 that includes Periodic Timer 1
+ @param[in] Context2 Context 2 that includes Periodic Timer 2
+
+ @retval FALSE Periodic Timer match
+ @retval TRUE Periodic Timer don't match
+**/
+BOOLEAN
+EFIAPI
+PeriodicTimerCmpContext (
+ IN PCH_SMM_CONTEXT *HwContext,
+ IN PCH_SMM_CONTEXT *ChildContext
+ )
+{
+
+ if (ChildContext->PeriodicTimer.ElapsedTime >= ChildContext->PeriodicTimer.Period) {
+ ///
+ /// This child should be dispatched
+ /// Need reset ElapsedTime, or SMI handler will be invoked during SmiTickInterval instead of Period.
+ ///
+ ChildContext->PeriodicTimer.ElapsedTime = 0;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Program Smm Periodic Timer
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+PchSmmPeriodicTimerProgramTimers (
+ VOID
+ )
+{
+ UINT16 GenPmCon1;
+ UINT8 GenPmCon3;
+ SUPPORTED_TIMER Timer;
+ DATABASE_RECORD *RecordInDb;
+ LIST_ENTRY *LinkInDb;
+ UINTN PciD31F0RegBase;
+ TIMER_INTERVAL *TimerInterval;
+
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ ///
+ /// Find the minimum required interval for each timer
+ ///
+ for (Timer = 0; Timer < NUM_TIMERS; Timer++) {
+ mTimers[Timer].MinReqInterval = ~ (UINT64) 0x0;
+ mTimers[Timer].NumChildren = 0;
+ }
+
+ LinkInDb = GetFirstNode (&mPrivateData.CallbackDataBase);
+ while (!IsNull (&mPrivateData.CallbackDataBase, LinkInDb)) {
+ RecordInDb = DATABASE_RECORD_FROM_LINK (LinkInDb);
+ if (RecordInDb->ProtocolType == PeriodicTimerType) {
+ ///
+ /// This child is registerd with the PeriodicTimer protocol
+ ///
+ TimerInterval = ContextToTimerInterval (&RecordInDb->ChildContext);
+ if (TimerInterval == NULL) {
+ return;
+ }
+
+ Timer = TimerInterval->AssociatedTimer;
+ if (Timer < 0 || Timer >= NUM_TIMERS) {
+ ASSERT (FALSE);
+ EFI_DEADLOOP ();
+ }
+
+ if (mTimers[Timer].MinReqInterval > RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval) {
+ mTimers[Timer].MinReqInterval = RecordInDb->ChildContext.PeriodicTimer.SmiTickInterval;
+ }
+
+ mTimers[Timer].NumChildren++;
+ }
+
+ LinkInDb = GetNextNode (&mPrivateData.CallbackDataBase, &RecordInDb->Link);
+ }
+ ///
+ /// Program the hardware
+ ///
+ if (mTimers[PERIODIC_TIMER].NumChildren > 0) {
+ GenPmCon1 = MmioRead16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1);
+
+ GenPmCon1 &= ~B_PCH_LPC_GEN_PMCON_PER_SMI_SEL;
+ switch (mTimers[PERIODIC_TIMER].MinReqInterval) {
+ case TIME_64s:
+ GenPmCon1 |= V_PCH_LPC_GEN_PMCON_PER_SMI_64S;
+ mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_64s;
+ break;
+
+ case TIME_32s:
+ GenPmCon1 |= V_PCH_LPC_GEN_PMCON_PER_SMI_32S;
+ mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_32s;
+ break;
+
+ case TIME_16s:
+ GenPmCon1 |= V_PCH_LPC_GEN_PMCON_PER_SMI_16S;
+ mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_16s;
+ break;
+
+ case TIME_8s:
+ GenPmCon1 |= V_PCH_LPC_GEN_PMCON_PER_SMI_8S;
+ mTimers[PERIODIC_TIMER].CurrentSetting = INDEX_TIME_8s;
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+
+ MmioWrite16 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_1, GenPmCon1);
+
+ ///
+ /// Restart the timer here, just need to clear the SMI
+ ///
+ PchSmmClearSource (&mTIMER_SOURCE_DESCS[PERIODIC_TIMER]);
+ } else {
+ PchSmmDisableSource (&mTIMER_SOURCE_DESCS[PERIODIC_TIMER]);
+ }
+
+ if (mTimers[SWSMI_TIMER].NumChildren > 0) {
+ ///
+ /// ICH9, ICH10 and PCH share the same bit positions for SW SMI Rate settings
+ ///
+ GenPmCon3 = MmioRead8 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3);
+ GenPmCon3 &= ~B_PCH_LPC_GEN_PMCON_SWSMI_RTSL;
+ switch (mTimers[SWSMI_TIMER].MinReqInterval) {
+ case TIME_64ms:
+ GenPmCon3 |= V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_64MS;
+ mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_64ms;
+ break;
+
+ case TIME_32ms:
+ GenPmCon3 |= V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_32MS;
+ mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_32ms;
+ break;
+
+ case TIME_16ms:
+ GenPmCon3 |= V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_16MS;
+ mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_16ms;
+ break;
+
+ case TIME_1_5ms:
+ GenPmCon3 |= V_PCH_LPC_GEN_PMCON_SWSMI_RTSL_1_5MS;
+ mTimers[SWSMI_TIMER].CurrentSetting = INDEX_TIME_1_5ms;
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+ ///
+ /// SWSMI_RATE_SEL BIT (D31:F0:A4h[7:6]) bits are in RTC well
+ ///
+ MmioWrite8 (PciD31F0RegBase + R_PCH_LPC_GEN_PMCON_3, GenPmCon3);
+
+ ///
+ /// Restart the timer here, need to disable, clear, then enable to restart this timer
+ ///
+ PchSmmDisableSource (&mTIMER_SOURCE_DESCS[SWSMI_TIMER]);
+ PchSmmClearSource (&mTIMER_SOURCE_DESCS[SWSMI_TIMER]);
+ PchSmmEnableSource (&mTIMER_SOURCE_DESCS[SWSMI_TIMER]);
+ } else {
+ PchSmmDisableSource (&mTIMER_SOURCE_DESCS[SWSMI_TIMER]);
+ }
+}
+
+/**
+ This services returns the next SMI tick period that is supported by the chipset.
+ The order returned is from longest to shortest interval period.
+
+ @param[in] This Pointer to the EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL instance.
+ @param[in, out] SmiTickInterval Pointer to pointer of the next shorter SMI interval period that is supported by the child.
+
+ @retval EFI_SUCCESS The service returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter SmiTickInterval is invalid.
+**/
+EFI_STATUS
+PchSmmPeriodicTimerDispatchGetNextShorterInterval (
+ IN EFI_SMM_PERIODIC_TIMER_DISPATCH_PROTOCOL *This,
+ IN OUT UINT64 **SmiTickInterval
+ )
+{
+ TIMER_INTERVAL *IntervalPointer;
+
+ ASSERT (SmiTickInterval != NULL);
+
+ IntervalPointer = (TIMER_INTERVAL *) *SmiTickInterval;
+
+ if (IntervalPointer == NULL) {
+ ///
+ /// The first time child requesting an interval
+ ///
+ IntervalPointer = &mSmmPeriodicTimerIntervals[0];
+ } else if (IntervalPointer == &mSmmPeriodicTimerIntervals[NUM_INTERVALS - 1]) {
+ ///
+ /// At end of the list
+ ///
+ IntervalPointer = NULL;
+ } else {
+ if ((IntervalPointer >= &mSmmPeriodicTimerIntervals[0]) &&
+ (IntervalPointer < &mSmmPeriodicTimerIntervals[NUM_INTERVALS - 1])
+ ) {
+ ///
+ /// Get the next interval in the list
+ ///
+ IntervalPointer++;
+ } else {
+ ///
+ /// Input is out of range
+ ///
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ if (IntervalPointer != NULL) {
+ *SmiTickInterval = &IntervalPointer->Interval;
+ } else {
+ *SmiTickInterval = NULL;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is responsible for calculating and enabling any timers that are required
+ to dispatch messages to children. The SrcDesc argument isn't acutally used.
+
+ @param[in] SrcDesc Pointer to the PCH_SMM_SOURCE_DESC instance.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+PchSmmPeriodicTimerClearSource (
+ IN PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ PchSmmPeriodicTimerProgramTimers ();
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPowerButton.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPowerButton.c
new file mode 100644
index 0000000..e172808
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmPowerButton.c
@@ -0,0 +1,104 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm Power Button dispatch protocol.
+
+@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 "Token.h"
+#include "PchSmmHelpers.h"
+
+const PCH_SMM_SOURCE_DESC POWER_BUTTON_SOURCE_DESC = {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_EN
+ },
+ S_PCH_ACPI_PM1_EN,
+ N_PCH_ACPI_PM1_EN_PWRBTN
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_ACPI_PM1_STS
+ },
+ S_PCH_ACPI_PM1_STS,
+ N_PCH_ACPI_PM1_STS_PWRBTN
+ }
+ }
+};
+
+/**
+ Get the power button status.
+
+ @param[in] Record The pointer to the DATABASE_RECORD.
+ @param[out] Context Calling context from the hardware, will be updated with the current power button status.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PowerButtonGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ )
+{
+ UINT16 GenPmCon1;
+
+ GenPmCon1 = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_GEN_PMCON_1)
+ );
+
+ if ((GenPmCon1 & B_PCH_LPC_GEN_PMCON_PWRBTN_LVL) != 0) {
+ Context->PowerButton.Phase = PowerButtonExit;
+ } else {
+ Context->PowerButton.Phase = PowerButtonEntry;
+ }
+
+// AMI_OVERRIDE, EIP145008, forced PowerButton.Phase as PowerButtonEntry.>>>
+#if defined FORCE_PWB_PHASE_AS_ENTRY && FORCE_PWB_PHASE_AS_ENTRY == 1
+ Context->PowerButton.Phase = PowerButtonEntry;
+#endif
+// AMI_OVERRIDE, EIP145008, forced PowerButton.Phase as PowerButtonEntry.<<<
+}
+
+/**
+ Check whether Power Button status of two contexts match
+
+ @param[in] Context1 Context 1 that includes Power Button status 1
+ @param[in] Context2 Context 2 that includes Power Button status 2
+
+ @retval FALSE Power Button status match
+ @retval TRUE Power Button status don't match
+**/
+BOOLEAN
+EFIAPI
+PowerButtonCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ )
+{
+ return (BOOLEAN) (Context1->PowerButton.Phase == Context2->PowerButton.Phase);
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c
new file mode 100644
index 0000000..9a20df3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSw.c
@@ -0,0 +1,87 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm Sw dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+const PCH_SMM_SOURCE_DESC SW_SOURCE_DESC = {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_APMC
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_APM
+ }
+ }
+};
+
+/**
+ Get the Software Smi value
+
+ @param[in] Record No use
+ @param[out] Context The context that includes Software Smi value to be filled
+
+ @retval None
+**/
+VOID
+EFIAPI
+SwGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ )
+{
+ UINT8 ApmCnt;
+
+ ApmCnt = IoRead8 ((UINTN) R_PCH_APM_CNT);
+
+ Context->Sw.SwSmiInputValue = ApmCnt;
+}
+
+/**
+ Check whether software SMI value of two contexts match
+
+ @param[in] Context1 Context 1 that includes software SMI value 1
+ @param[in] Context2 Context 2 that includes software SMI value 2
+
+ @retval FALSE Software SMI value match
+ @retval TRUE Software SMI value don't match
+**/
+BOOLEAN
+EFIAPI
+SwCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ )
+{
+ return (BOOLEAN) (Context1->Sw.SwSmiInputValue == Context2->Sw.SwSmiInputValue);
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c
new file mode 100644
index 0000000..3f7e3e2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmSx.c
@@ -0,0 +1,975 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+extern EFI_PHYSICAL_ADDRESS mResvMmioBaseAddr;
+///
+/// Maximum loop time for GbE status check
+///
+#define GBE_MAX_LOOP_TIME 4000
+
+const PCH_SMM_SOURCE_DESC SX_SOURCE_DESC = {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_ON_SLP_EN
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_ON_SLP_EN
+ }
+ }
+};
+
+/**
+ Get the Sleep type
+
+ @param[in] Record No use
+ @param[out] Context The context that includes SLP_TYP bits to be filled
+
+ @retval None
+**/
+VOID
+EFIAPI
+SxGetContext (
+ IN DATABASE_RECORD *Record,
+ OUT PCH_SMM_CONTEXT *Context
+ )
+{
+ UINT32 Pm1Cnt;
+
+ Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT));
+
+ ///
+ /// By design, the context phase will always be ENTRY
+ ///
+ Context->Sx.Phase = SxEntry;
+
+ ///
+ /// Map the PM1_CNT register's SLP_TYP bits to the context type
+ ///
+ switch (Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) {
+ case V_PCH_ACPI_PM1_CNT_S0:
+ Context->Sx.Type = SxS0;
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S1:
+ Context->Sx.Type = SxS1;
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S3:
+ Context->Sx.Type = SxS3;
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S4:
+ Context->Sx.Type = SxS4;
+ break;
+
+ case V_PCH_ACPI_PM1_CNT_S5:
+ Context->Sx.Type = SxS5;
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+}
+
+/**
+ Check whether sleep type of two contexts match
+
+ @param[in] Context1 Context 1 that includes sleep type 1
+ @param[in] Context2 Context 2 that includes sleep type 2
+
+ @retval FALSE Sleep types match
+ @retval TRUE Sleep types don't match
+**/
+BOOLEAN
+EFIAPI
+SxCmpContext (
+ IN PCH_SMM_CONTEXT *Context1,
+ IN PCH_SMM_CONTEXT *Context2
+ )
+{
+ return (BOOLEAN) (Context1->Sx.Type == Context2->Sx.Type);
+}
+
+/**
+ Check ready flag to see if writing to MDIC is done.
+
+ @param[in] GbEBar GbE Memory Base Address Register
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_TIMEOUT Checking flag time out.
+**/
+EFI_STATUS
+CheckReadyFlag (
+ UINT32 GbEBar
+ )
+{
+ UINT32 ReadyFlag;
+ UINT32 LoopTime;
+
+ ReadyFlag = 0;
+
+ for (LoopTime = 0; LoopTime < GBE_MAX_LOOP_TIME; LoopTime++) {
+ ReadyFlag = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR3) & B_PCH_MBARA_GBECSR3_RB;
+
+ if (ReadyFlag) {
+ break;
+ }
+
+ PchPmTimerStall (10);
+ }
+
+ if (LoopTime >= GBE_MAX_LOOP_TIME) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ PCH BIOS Spec Rev 0.5.0 Section 10.5
+ Additional Internal GbE Controller special cases WOL Support
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+GbES02SxWorkaround (
+ VOID
+ )
+{
+ UINTN PciD25F0RegBase;
+ UINTN PciD31F0RegBase;
+ UINT32 GbEBar;
+ UINT32 GbEBarB;
+ UINT16 CmdReg;
+ UINT32 RAL0;
+ UINT32 RAH0;
+ UINT32 PhyCtrl;
+ UINT32 ExtCnfCtrl;
+ UINT32 Buffer;
+ UINT32 LoopTime;
+ UINT32 RootComplexBar;
+ UINT32 PchGpioBase;
+ EFI_STATUS Status;
+
+ PciD25F0RegBase = MmPciAddress (
+ 0,
+ PCI_BUS_NUMBER_PCH_LAN,
+ PCI_DEVICE_NUMBER_PCH_LAN,
+ PCI_FUNCTION_NUMBER_PCH_LAN,
+ 0
+ );
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ RootComplexBar = PCH_RCRB_BASE;
+ PchGpioBase = (MmioRead32 (PciD31F0RegBase + R_PCH_LPC_GPIO_BASE)) &~BIT0;
+ GbEBar = 0;
+ GbEBarB = 0;
+ CmdReg = 0;
+ Buffer = 0;
+
+ if (((MmioRead16 (RootComplexBar + R_PCH_RCRB_BUC)) & BIT5) == 0) {
+ ///
+ /// System BIOS requires to program the registers listed below for internal GbE to function upon S0 to S3,4,5 transition
+ /// (When ME off and GbE device in D0)
+ ///
+ /// Note: Time out should be applied for MBARA + Offset 20h[28] verification to avoid non respond loop. Upon time out,
+ /// system BIOS is required to clear MBARA + Offset F00h [5] = 0b before exiting the WA.
+ ///
+ /// Check if GbE device is in D0 state
+ ///
+ if ((MmioRead16 (PciD25F0RegBase + R_PCH_LAN_PMCS) & (UINT16) B_PCH_LAN_PMCS_PS) == (UINT16) V_PCH_LAN_PMCS_PS0) {
+ GbEBar = MmioRead32 (PciD25F0RegBase + R_PCH_LAN_MEM_BASE_A);
+ ///
+ /// Step 1
+ /// If MBARA + Offset 5800h [0] = 1b then proceed the steps below
+ ///
+ if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR9) & B_PCH_MBARA_GBECSR9_APME) {
+ ///
+ /// Step 2
+ /// System BIOS perform read to MBARA + Offset 5400h [31:0], MBARA + Offset 5404h [31:0]
+ /// and MBARA + Offset F00h [31:0]
+ ///
+ RAL0 = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR7);
+ RAH0 = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR8);
+ ExtCnfCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR5);
+ ///
+ /// Step 3
+ /// Ensure that MBARA + Offset F00h [5] = 1b
+ /// a. Set MBARA + Offset F00h [31:0] value with the value read in step 2 or with 0x20 (set bit 5)
+ /// b. Read MBARA + Offset F00h
+ /// c. If MBARA + Offset F00h [5] = 1b (true) continue else wait X Sec and go back to step 3.b for Y times
+ /// (X*Y totals to ~200mSec) if false - exit flow by jumping to step 32.
+ ///
+ MmioWrite32 (GbEBar + R_PCH_MBARA_GBECSR5, ExtCnfCtrl | B_PCH_MBARA_GBECSR5_SWFLAG);
+
+ for (LoopTime = 0; LoopTime < GBE_MAX_LOOP_TIME; LoopTime++) {
+ ExtCnfCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR5);
+
+ if (ExtCnfCtrl & B_PCH_MBARA_GBECSR5_SWFLAG) {
+ break;
+ }
+
+ PchPmTimerStall (50);
+ }
+
+ if (LoopTime >= GBE_MAX_LOOP_TIME) {
+ goto ExitGbEWa;
+ }
+ ///
+ /// Step 4
+ /// If MBARA + Offset 5B54h [15] = 1b then jump to Step 10
+ ///
+ if ((MmioRead32 (GbEBar + 0x5B54) & BIT15) != BIT15) {
+ ///
+ /// Step 5
+ /// If MBARA + Offset F10h [2] = 1b, then set MBARA + Offset F10h[1] = 1b. Else clear MBARA + Offset F10h[1] = 0b
+ ///
+ if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_LPLUND) {
+ MmioOr32 (GbEBar + R_PCH_MBARA_GBECSR6, (UINT32) B_PCH_MBARA_GBECSR6_LPLUD);
+ } else {
+ MmioAnd32 (GbEBar + R_PCH_MBARA_GBECSR6, (UINT32)~B_PCH_MBARA_GBECSR6_LPLUD);
+ }
+ ///
+ /// Step 6
+ /// Set MBARA + Offset 20h = 0x043f0000. Verify MBARA + Offset 20h[28] = 1b
+ ///
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x043f0000);
+
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+ ///
+ /// Step 7
+ /// Wait 4 mSec
+ ///
+ PchPmTimerStall (4 * 1000);
+ ///
+ /// Step 8
+ /// Set MBARA + Offset 20h = 0x04390000 or with 0x400 or with 0x40 if MBARA + Offset F10h [3] = 1b
+ /// or with 0x04 if MBARA + Offset F10h [2] = 1b
+ ///
+ Buffer = 0x04390000 | 0x400;
+ if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_GbE_DIS) {
+ Buffer |= 0x40;
+ }
+
+ if (MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6) & B_PCH_MBARA_GBECSR6_LPLUND) {
+ Buffer |= 0x04;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), Buffer);
+ ///
+ /// Step 9
+ /// Verify MBARA + Offset 20h[28] = 1b
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+ }
+ ///
+ /// Step 10
+ /// Set MBARA + Offset 20h = 0x043f6400
+ ///
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x043f6400);
+ ///
+ /// Step 11
+ /// Wait 4 mSec
+ ///
+ PchPmTimerStall (4 * 1000);
+ ///
+ /// Step 12
+ /// Set MBARA + Offset F10h [6] = 1b (read modify write)
+ ///
+ PhyCtrl = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR6);
+ MmioWrite32 (GbEBar + R_PCH_MBARA_GBECSR6, PhyCtrl | B_PCH_MBARA_GBECSR6_GGD);
+ ///
+ /// Step 13
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310010
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310010);
+ ///
+ /// Step 14
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with
+ /// the least significant word of MBARA + offset 5400 that read in step 2
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAL0 & 0x0000FFFF)));
+ ///
+ /// Step 15
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310011
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310011);
+ ///
+ /// Step 16
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with
+ /// the most significant word of MBARA + offset 5400 that read in step 2
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAL0 >> 16)));
+ ///
+ /// Step 17
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310012
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310012);
+ ///
+ /// Step 18
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4320000 or with
+ /// the least significant word of MBARA + offset 5404 that read in step 2
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), (0x4320000 | (RAH0 & B_PCH_MBARA_GBECSR8_RAH)));
+ ///
+ /// Step 19
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310013
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310013);
+ ///
+ /// Step 20
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4328000
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4328000);
+ ///
+ /// Step 21
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310001
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310001);
+ ///
+ /// Step 22
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x8320000
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x8320000);
+ ///
+ /// Step 23
+ /// Verify MBARA + Offset 20h[28] = 1b, TEMP[15:0] = MBARA + Offset 20h [15:0]
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ Buffer = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR3) & B_PCH_MBARA_GBECSR3_DATA;
+ ///
+ /// Step 24
+ /// Set MBARA + Offset 20h = 0x4320000 or TEMP[15:0] or 0x0001
+ ///
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4320000 | Buffer | 0x0001);
+ ///
+ /// Step 25
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x43f6460
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x43f6460);
+ ///
+ /// Step 26
+ /// Wait 4 mSec
+ ///
+ PchPmTimerStall (4 * 1000);
+ ///
+ /// Step 27
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x4310042
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310042);
+ ///
+ /// Step 28
+ /// Verify MBARA + Offset 20h[28] = 1b.
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x43F6020);
+
+ ///
+ /// Step 29
+ /// Wait 4 mSec
+ ///
+ PchPmTimerStall (4 * 1000);
+
+ ///
+ /// Step 30
+ /// Verify MBARA + Offset 20h[28] = 1b, set MBARA + Offset 20h = 0x8310000
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x8310000);
+ ///
+ /// Step 31
+ /// Verify MBARA + Offset 20h[28] = 1b, TEMP[15:0] = MBARA + 20[15:0]
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ Buffer = MmioRead32 (GbEBar + R_PCH_MBARA_GBECSR3) & 0x0000FFFF;
+
+ ///
+ /// Step 32
+ /// Verify MBARA + 20h[28] = 1b, set MBARA + 20h = 4310000h or with the TEMP[15:0] or with 10h
+ ///
+ Status = CheckReadyFlag (GbEBar);
+ if (EFI_ERROR (Status)) {
+ goto ExitGbEWa;
+ }
+
+ExitGbEWa:
+
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR3), 0x4310000 | Buffer | 0x10);
+ ///
+ /// Step 33
+ /// Verify MBARA + Offset 20h[28] = 1b
+ ///
+ Status = CheckReadyFlag (GbEBar);
+
+ ///
+ /// Step 34
+ /// Clear MBARA + Offset F00h [5] = 0b (read modify write)
+ ///
+ MmioWrite32 ((GbEBar + R_PCH_MBARA_GBECSR5), (ExtCnfCtrl & (UINT32) (~BIT5)));
+
+ }
+ }
+ }
+}
+
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+} USB_CONTROLLER;
+
+/**
+ PCH BIOS Spec Rev 0.5.0, Section 12.10.1
+ Additional Programming Requirements prior to enter
+ S4/S5
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+UsbS02SxWorkaround (
+ VOID
+ )
+{
+ UINT8 Index;
+ UINTN EhciPciRegBase;
+ UINT32 UsbBar;
+ UINT16 CmdReg;
+ UINT16 PowerState;
+ 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
+ }
+ };
+
+ ///
+ /// System BIOS must execute the following steps prior to enter S4/S5.
+ ///
+ for (Index = 0; Index < GetPchEhciMaxControllerNum (); Index++) {
+ ///
+ /// Step 1
+ /// Read "Memory Base Address (MEM_BASE) Register" of D26/D29:F0
+ ///
+ EhciPciRegBase = MmPciAddress (0, 0, EhciControllersMap[Index].Device, EhciControllersMap[Index].Function, 0);
+ UsbBar = MmioRead32 (EhciPciRegBase + R_PCH_EHCI_MEM_BASE);
+ CmdReg = MmioRead16 (EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER);
+ PowerState = MmioRead16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS);
+
+ if (UsbBar != 0xFFFFFFFF) {
+ ///
+ /// Check if the Ehci device is in D3 power state
+ ///
+ if ((PowerState & B_PCH_EHCI_PWR_CNTL_STS_PWR_STS) == V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3) {
+ ///
+ /// Step 2
+ /// Set "Power State" bit of PWR_CNTL_STS register, D26/D29:F0:54h [1:0] = 0h
+ ///
+ MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS, (PowerState &~B_PCH_EHCI_PWR_CNTL_STS_PWR_STS));
+ ///
+ /// Step 3
+ /// Write back the value from step 1 to the "Memory Base Address (MEM_BASE) Register" of D26/D29:F0
+ ///
+ MmioWrite32 (EhciPciRegBase + R_PCH_EHCI_MEM_BASE, UsbBar);
+ ///
+ /// Step 4
+ /// Enable "Memory Space Enable (MSE)" bit, set D26/D29:F0:04h [1] = 1b.
+ ///
+ MmioOr16 (
+ EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER,
+ (UINT16) (B_PCH_EHCI_COMMAND_MSE)
+ );
+ }
+ ///
+ /// Step 5
+ /// Clear "Asynchronous Schedule Enable" and "Periodic Schedule Enable" bits, if "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 1b.
+ /// Proceed to steps below if "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 0b.
+ ///
+ if (!(MmioRead32 (UsbBar + R_PCH_EHCI_USB2CMD) & B_PCH_EHCI_USB2CMD_RS)) {
+ MmioAnd32 (UsbBar + R_PCH_EHCI_USB2CMD, (UINT32)~(B_PCH_EHCI_USB2CMD_ASE | B_PCH_EHCI_USB2CMD_PSE));
+ MmioOr32 (UsbBar + R_PCH_EHCI_USB2CMD, B_PCH_EHCI_USB2CMD_RS);
+ }
+ ///
+ /// Step 6
+ /// If "Port Enabled/Disabled" bit of Port N Status and Control (PORTSC) Register is set, MEM_BASE + 64h [2] = 1b,
+ /// proceed steps below else continue with S4/S5.
+ ///
+ if ((MmioRead32 (UsbBar + R_PCH_EHCI_PORTSC0) & R_PCH_EHCI_PORTSC0_PORT_EN_DIS)) {
+ ///
+ /// Step 7
+ /// Ensure that "Suspend" bit of Port N Status and Control (PORTSC) Register is set, MEM_BASE + 64h [7] = 1b.
+ ///
+ if (!(MmioRead32 (UsbBar + R_PCH_EHCI_PORTSC0) & R_PCH_EHCI_PORTSC0_SUSPEND)) {
+ MmioOr32 (UsbBar + R_PCH_EHCI_PORTSC0, R_PCH_EHCI_PORTSC0_SUSPEND);
+ }
+ ///
+ /// Step 8
+ /// Set delay of 25ms
+ ///
+ PchPmTimerStall (25 * 1000);
+ ///
+ /// Step 9
+ /// Clear "Run/Stop (RS)" bit, MEM_BASE + offset 20h [0] = 0b.
+ ///
+ MmioAnd32 (UsbBar + R_PCH_EHCI_USB2CMD, (UINT32)~(B_PCH_EHCI_USB2CMD_RS));
+ }
+ ///
+ /// If the EHCI device is in D3 power state before executing this WA
+ ///
+ if ((PowerState & B_PCH_EHCI_PWR_CNTL_STS_PWR_STS) == V_PCH_EHCI_PWR_CNTL_STS_PWR_STS_D3) {
+ ///
+ /// Restore PCI Command Register
+ ///
+ MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_COMMAND_REGISTER, CmdReg);
+ ///
+ /// Set "Power State" bit of PWR_CNTL_STS register to D3 state, D26/D29:F0:54h [1:0] = 3h
+ ///
+ MmioWrite16 (EhciPciRegBase + R_PCH_EHCI_PWR_CNTL_STS, PowerState);
+ }
+ ///
+ /// Step 10
+ /// Continue with S4/S5
+ ///
+ }
+ }
+}
+
+/**
+ Additional xHCI Controller Configurations Prior to Entering S3/S4/S5
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+XhciSxWorkaround (
+ VOID
+ )
+{
+ UINT32 RootComplexBar;
+ UINTN XhciPciMmBase;
+ UINT8 OrgCmdByte;
+ UINT32 OrgMmioAddr;
+ UINT32 OrgMmioHAddr;
+ UINT8 OrgPwrSts;
+ PCH_SERIES PchSeries;
+ UINT32 XhciMmioBase;
+ UINT32 PortScOffset[4];
+ UINT32 Data32;
+ UINT32 Index;
+ UINT32 ResetMask;
+
+ PchSeries = GetPchSeries();
+
+ RootComplexBar = PCH_RCRB_BASE;
+ ///
+ /// Check if XHCI controller is enabled
+ ///
+ if ((MmioRead32 (RootComplexBar + R_PCH_RCRB_FUNC_DIS) & (UINT32) B_PCH_RCRB_FUNC_DIS_XHCI) != 0) {
+ return;
+ }
+ XhciPciMmBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ 0
+ );
+
+ //
+ // Save Cmd and XhciBar and PwrSts registers
+ //
+ OrgCmdByte = MmioRead8 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER);
+ OrgMmioAddr = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE) & 0xFFFF0000;
+ OrgMmioHAddr = MmioRead32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE + 4);
+ OrgPwrSts = MmioRead8 (XhciPciMmBase + R_PCH_XHCI_PWR_CNTL_STS);
+ //
+ // Bring device back to D0
+ //
+ MmioAnd8 (XhciPciMmBase + R_PCH_XHCI_PWR_CNTL_STS, (UINT8)~(B_PCH_XHCI_PWR_CNTL_STS_PWR_STS));
+ //
+ // Use the reserved MMIO
+ // Clear MSE before changing MMIO address
+ //
+ MmioAnd8 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER, (UINT8)~(B_PCH_XHCI_COMMAND_BME | B_PCH_XHCI_COMMAND_MSE));
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE, (UINT32)mResvMmioBaseAddr);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE + 4, 0);
+ XhciMmioBase = (UINT32)mResvMmioBaseAddr;
+ //
+ // Set MSE
+ //
+ MmioOr8 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER, (B_PCH_XHCI_COMMAND_BME | B_PCH_XHCI_COMMAND_MSE));
+
+ //
+ // XHC W/A for LPT-LP
+ // Clear PCI CFG offset 0xB0[14:13] for LPT-LP
+ // Clear MMIO Offset 0x816C[14]
+ // Clear MMIO Offset 0x816C[2]
+ // Wait until all SS ports are out of polling
+ // For each SS port which is disconnected (i.e. PORTS.PLS=5h) and CSC=0
+ // Issue Warm Port Reset
+ // Wait 101ms
+ // Write '1' to all Port Change Status bits if reset
+ // Set MMIO Offset 0x80E0[15]
+ //
+ // For PCH H and LP
+ // Clear MMIO Offset 0x8154[31]
+ //
+ if (PchSeries == PchLp) {
+ //
+ // Clear PCI CFG offset 0xB0[14:13] for LPT-LP
+ //
+ MmioAnd32 (XhciPciMmBase + 0xB0, (UINT32)~(BIT14 | BIT13));
+ //
+ // Clear MMIO Offset 0x816C[14]
+ // Clear MMIO Offset 0x816C[2]
+ //
+ MmioAnd32 (XhciMmioBase + 0x816C, (UINT32)~(BIT14 | BIT2));
+
+ PortScOffset[0] = R_PCH_LP_XHCI_PORTSC1USB3;
+ PortScOffset[1] = R_PCH_LP_XHCI_PORTSC2USB3;
+ PortScOffset[2] = R_PCH_LP_XHCI_PORTSC3USB3;
+ PortScOffset[3] = R_PCH_LP_XHCI_PORTSC4USB3;
+ //
+ // Wait until all ports are out of polling (PP=1, PLS=7)
+ //
+ for (Index = 0; Index < 4; Index++) {
+ Data32 = MmioRead32 (XhciMmioBase + PortScOffset[Index]);
+ //
+ // Check if PLS = 7, and PP = 1
+ //
+ while ((Data32 & B_PCH_XHCI_PORTSCXUSB3_PLS) == V_PCH_XHCI_PORTSCXUSB3_PLS_POLLING)
+ {
+ PchPmTimerStall (10);
+ Data32 = MmioRead32 (XhciMmioBase + PortScOffset[Index]);
+ }
+ }
+ ResetMask = 0;
+ for (Index = 0; Index < 4; Index++) {
+ Data32 = MmioRead32 (XhciMmioBase + PortScOffset[Index]);
+ //
+ // If Port X is Disconnected (i.e. PORTS.PLS=5h) AND PORTSC{X}.CSC=0
+ // Check if PLS = 5, CSC = 0, and PP = 1
+ //
+ if (((Data32 & B_PCH_XHCI_PORTSCXUSB3_PLS) == V_PCH_XHCI_PORTSCXUSB3_PLS_RXDETECT) &&
+ ((Data32 & B_PCH_XHCI_PORTSCXUSB3_CSC) == 0))
+ {
+ //
+ // Issue Warm Port Reset
+ //
+ ResetMask |= (1 << Index);
+ Data32 &= (UINT32)~(B_PCH_XHCI_PORTSCXUSB3_PED);
+ Data32 |= B_PCH_XHCI_PORTSCXUSB3_WPR;
+ MmioWrite32 (XhciMmioBase + PortScOffset[Index], Data32);
+ }
+ }
+
+ if (ResetMask != 0) {
+ //
+ // Wait 101ms to ensure reset completed
+ //
+ PchPmTimerStall (101 * 1000);
+
+ for (Index = 0; Index < 4; ++Index) {
+ if (ResetMask & (1 << Index)) {
+ Data32 = MmioRead32 (XhciMmioBase + PortScOffset[Index]);
+ Data32 &= (UINT32)~(B_PCH_XHCI_PORTSCXUSB3_PED);
+ //
+ // Write '1' to All Port Change Status
+ //
+ Data32 |= (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);
+ MmioWrite32 (XhciMmioBase + PortScOffset[Index], Data32);
+ }
+ }
+ }
+
+ //
+ // Set MMIO Offset 0x80E0[15]
+ //
+ MmioOr32 (XhciMmioBase + 0x80E0, BIT15);
+ }
+ //
+ // Clear MMIO Offset 0x8154[31]
+ //
+ MmioAnd32 (XhciMmioBase + 0x8154, (UINT32)~BIT31);
+
+ //
+ // Restore Cmd and XhciBar and PwrSts registers
+ //
+ MmioAnd8 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER, (UINT8)~(B_PCH_XHCI_COMMAND_BME | B_PCH_XHCI_COMMAND_MSE));
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE + 4, OrgMmioHAddr);
+ MmioWrite32 (XhciPciMmBase + R_PCH_XHCI_MEM_BASE, OrgMmioAddr);
+ MmioWrite8 (XhciPciMmBase + R_PCH_XHCI_COMMAND_REGISTER, OrgCmdByte);
+
+ ///
+ /// Set D3hot state - 11b
+ ///
+ MmioOr16 ((XhciPciMmBase + R_PCH_XHCI_PWR_CNTL_STS), (UINT16) 0x3);
+
+ ///
+ /// Set "PME Enable" bit of PWR_CNTL_STS register, D20:F0:74h[8] = 1h
+ ///
+ MmioOr16 ((XhciPciMmBase + R_PCH_XHCI_PWR_CNTL_STS), (UINT16) (B_PCH_XHCI_PWR_CNTL_STS_PME_EN));
+
+}
+
+/**
+ When we get an SMI that indicates that we are transitioning to a sleep state,
+ we need to actually transition to that state. We do this by disabling the
+ "SMI on sleep enable" feature, which generates an SMI when the operating system
+ tries to put the system to sleep, and then physically putting the system to sleep.
+
+ @param[in] None
+
+ @retval None.
+**/
+VOID
+PchSmmSxGoToSleep (
+ VOID
+ )
+{
+ UINT32 Pm1Cnt;
+ UINT32 RootComplexBar;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ RootComplexBar = PCH_RCRB_BASE;
+
+ ///
+ /// Flush cache into memory before we go to sleep. It is necessary for S3 sleep
+ /// because we may update memory in SMM Sx sleep handlers -- the updates are in cache now
+ ///
+ AsmWbinvd ();
+
+ ///
+ /// Disable SMIs
+ ///
+ PchSmmClearSource (&SX_SOURCE_DESC);
+ PchSmmDisableSource (&SX_SOURCE_DESC);
+
+ ///
+ /// Get Power Management 1 Control Register Value
+ ///
+ Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT));
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 12.10.1
+ /// Additional Programming Requirements prior to enter S4/S5
+ ///
+ if (((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4) ||
+ ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S5)) {
+ UsbS02SxWorkaround ();
+ }
+
+ if (((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) ||
+ ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S4) ||
+ ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S5)) {
+ XhciSxWorkaround ();
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 10.6
+ /// Additional Internal GbE Controller special cases WOL Support
+ ///
+ GbES02SxWorkaround ();
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 10.6 Additional GbE based wake events
+ /// The GPIO[27] is used as a wake pin when the GbE controller is enabled.
+ /// The System BIOS should enable this as wake event by setting the GPIO[27]
+ /// Enable bit (GP27_EN PMBASE + 2Ch[3]). Unlike other wake events the System
+ /// BIOS does not need to clear the corresponding GPIO[27] Status bit
+ /// (GP27_STS PMBASE + 24h[3]) as the bit will be cleared by the hardware.
+ ///
+ /// RCBA + 0x3334 [0] will be 1b while PchDeepSx is enabled and GP27 is
+ /// reuqired to wake up the system from PchDeepSx.
+ ///
+ if ((MmioRead32 (RootComplexBar + 0x3334) & (UINT32) BIT0) != 0) {
+ if (PchSeries == PchLp) {
+ IoOr32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0_EN_127_96), (UINT32) B_PCH_ACPI_GPE0_EN_127_96_GP27);
+ } else if (PchSeries == PchH) {
+ IoOr32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0b_EN), (UINT32) B_PCH_ACPI_GPE0b_EN_GP27);
+ }
+ }
+ }
+
+ ///
+ /// Record S3 suspend performance data
+ ///
+ if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S3) {
+ ///
+ /// Report status code before goto S3 sleep
+ ///
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PROGRESS_CODE_S3_SUSPEND_END);
+
+ ///
+ /// Flush cache into memory before we go to sleep.
+ ///
+ AsmWbinvd ();
+ }
+
+ ///
+ /// Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep
+ ///
+ Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SLP_EN;
+
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT), Pm1Cnt);
+
+ ///
+ /// Should only proceed if wake event is generated.
+ ///
+ if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SLP_TYP) == V_PCH_ACPI_PM1_CNT_S1) {
+ while (((IoRead16 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS))) & B_PCH_ACPI_PM1_STS_WAK) == 0x0);
+ } else {
+ EFI_DEADLOOP ();
+ }
+ ///
+ /// The system just went to sleep. If the sleep state was S1, then code execution will resume
+ /// here when the system wakes up.
+ ///
+ Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT));
+
+ if ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SCI_EN) == 0) {
+ ///
+ /// An ACPI OS isn't present, clear the sleep information
+ ///
+ Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SLP_TYP;
+ Pm1Cnt |= V_PCH_ACPI_PM1_CNT_S0;
+
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT), Pm1Cnt);
+ }
+
+ PchSmmClearSource (&SX_SOURCE_DESC);
+ PchSmmEnableSource (&SX_SOURCE_DESC);
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c
new file mode 100644
index 0000000..8f24ff5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchSmmUsb.c
@@ -0,0 +1,300 @@
+/** @file
+ File to contain all the hardware specific stuff for the Smm USB dispatch protocol.
+
+@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 "PchSmmHelpers.h"
+
+PCH_SMM_SOURCE_DESC mUSB2_WAKE = {
+ PCH_SMM_SCI_EN_DEPENDENT,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_INTEL_USB2
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_INTEL_USB2
+ }
+ }
+};
+
+PCH_SMM_SOURCE_DESC mUSB1_LEGACY = {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_LEGACY_USB
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_LEGACY_USB
+ }
+ }
+};
+
+PCH_SMM_SOURCE_DESC mUSB2_LEGACY = {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_LEGACY_USB2
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_LEGACY_USB2
+ }
+ }
+};
+
+PCH_SMM_SOURCE_DESC mUSB3_LEGACY = {
+ PCH_SMM_NO_FLAGS,
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_EN
+ },
+ S_PCH_SMI_EN,
+ N_PCH_SMI_EN_LEGACY_USB3
+ },
+ NULL_BIT_DESC_INITIALIZER
+ },
+ {
+ {
+ {
+ ACPI_ADDR_TYPE,
+ R_PCH_SMI_STS
+ },
+ S_PCH_SMI_STS,
+ N_PCH_SMI_STS_LEGACY_USB3
+ }
+ }
+};
+
+typedef enum {
+ PchUsbControllerLpc0 = 0,
+ PchUsbControllerEhci1,
+ PchUsbControllerEhci2,
+ PchUsbControllerXhci,
+ PchUsbControllerTypeMax
+} PCH_USB_CONTROLLER_TYPE;
+
+typedef struct {
+ UINT8 Function;
+ UINT8 Device;
+ PCH_USB_CONTROLLER_TYPE UsbConType;
+} USB_CONTROLLER;
+
+USB_CONTROLLER mUsbControllersMap[] = {
+ {
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PchUsbControllerLpc0
+ },
+ {
+ PCI_FUNCTION_NUMBER_PCH_EHCI,
+ PCI_DEVICE_NUMBER_PCH_USB,
+ PchUsbControllerEhci1
+ },
+ {
+ PCI_FUNCTION_NUMBER_PCH_EHCI2,
+ PCI_DEVICE_NUMBER_PCH_USB_EXT,
+ PchUsbControllerEhci2
+ },
+ {
+ PCI_FUNCTION_NUMBER_PCH_XHCI,
+ PCI_DEVICE_NUMBER_PCH_XHCI,
+ PchUsbControllerXhci
+ }
+};
+
+/**
+ Find the handle that best matches the input Device Path and return the USB controller type
+
+ @param[in] DevicePath Pointer to the device Path table
+ @param[out] Controller Returned with the USB controller type of the input device path
+
+ @retval EFI_SUCCESS Find the handle that best matches the input Device Path
+ @exception EFI_UNSUPPORTED Invalid device Path table or can't find any match USB device path
+ PCH_USB_CONTROLLER_TYPE The USB controller type of the input
+ device path
+**/
+EFI_STATUS
+DevicePathToSupportedController (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT PCH_USB_CONTROLLER_TYPE *Controller
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DeviceHandle;
+ ACPI_HID_DEVICE_PATH *AcpiNode;
+ PCI_DEVICE_PATH *PciNode;
+ EFI_DEVICE_PATH_PROTOCOL *RemaingDevicePath;
+ UINT8 UsbIndex;
+ ///
+ /// Find the handle that best matches the Device Path. If it is only a
+ /// partial match the remaining part of the device path is returned in
+ /// RemainingDevicePath.
+ ///
+ RemaingDevicePath = DevicePath;
+ Status = gBS->LocateDevicePath (
+ &gEfiPciRootBridgeIoProtocolGuid,
+ &DevicePath,
+ &DeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DevicePath = RemaingDevicePath;
+
+ ///
+ /// Get first node: Acpi Node
+ ///
+ AcpiNode = (ACPI_HID_DEVICE_PATH *) RemaingDevicePath;
+
+ if (AcpiNode->Header.Type != ACPI_DEVICE_PATH ||
+ AcpiNode->Header.SubType != ACPI_DP ||
+ DevicePathNodeLength (&AcpiNode->Header) != sizeof (ACPI_HID_DEVICE_PATH) ||
+ AcpiNode->HID != EISA_PNP_ID (0x0A03) ||
+ AcpiNode->UID != 0
+ ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ ///
+ /// Get the next node: Pci Node
+ ///
+ RemaingDevicePath = NextDevicePathNode (RemaingDevicePath);
+ PciNode = (PCI_DEVICE_PATH *) RemaingDevicePath;
+ if (PciNode->Header.Type != HARDWARE_DEVICE_PATH ||
+ PciNode->Header.SubType != HW_PCI_DP ||
+ DevicePathNodeLength (&PciNode->Header) != sizeof (PCI_DEVICE_PATH)
+ ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for (UsbIndex = 0; UsbIndex < sizeof (mUsbControllersMap) / sizeof (USB_CONTROLLER); UsbIndex++) {
+ if ((PciNode->Device == mUsbControllersMap[UsbIndex].Device) &&
+ (PciNode->Function == mUsbControllersMap[UsbIndex].Function)) {
+ *Controller = mUsbControllersMap[UsbIndex].UsbConType;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+ }
+}
+
+/**
+ Maps a USB context to a source description.
+
+ @param[in] Context The context we need to map. Type must be USB.
+ @param[in] SrcDesc The source description that corresponds to the given context.
+
+ @retval None.
+**/
+VOID
+MapUsbToSrcDesc (
+ IN PCH_SMM_CONTEXT *Context,
+ OUT PCH_SMM_SOURCE_DESC *SrcDesc
+ )
+{
+ PCH_USB_CONTROLLER_TYPE Controller;
+ EFI_STATUS Status;
+
+ Status = DevicePathToSupportedController (Context->Usb.Device, &Controller);
+ ///
+ /// Either the device path passed in by the child is incorrect or
+ /// the ones stored here internally are incorrect.
+ ///
+ ASSERT_EFI_ERROR (Status);
+
+ switch (Context->Usb.Type) {
+ case UsbLegacy:
+ switch (Controller) {
+ case PchUsbControllerLpc0:
+ CopyMem ((VOID *) SrcDesc, (VOID *) (&mUSB1_LEGACY), sizeof (PCH_SMM_SOURCE_DESC));
+ break;
+
+ case PchUsbControllerEhci1:
+ case PchUsbControllerEhci2:
+ CopyMem ((VOID *) SrcDesc, (VOID *) (&mUSB2_LEGACY), sizeof (PCH_SMM_SOURCE_DESC));
+ break;
+
+ case PchUsbControllerXhci:
+ CopyMem ((VOID *) SrcDesc, (VOID *) (&mUSB3_LEGACY), sizeof (PCH_SMM_SOURCE_DESC));
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+ break;
+
+ case UsbWake:
+ switch (Controller) {
+ case PchUsbControllerEhci1:
+ case PchUsbControllerEhci2:
+ CopyMem ((VOID *) SrcDesc, (VOID *) (&mUSB2_WAKE), sizeof (PCH_SMM_SOURCE_DESC));
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+ break;
+
+ default:
+ ASSERT (FALSE);
+ break;
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.c b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.c
new file mode 100644
index 0000000..f6513a7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.c
@@ -0,0 +1,820 @@
+/** @file
+ This driver is responsible for the registration of child drivers
+ and the abstraction of the PCH SMI sources.
+
+@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 "PchSmmHelpers.h"
+
+//
+// Help handle porting bit shifts to IA-64.
+//
+#define BIT_ZERO 0x00000001
+
+/**
+ Publish SMI Dispatch protocols.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+PchSmmPublishDispatchProtocols (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Install protocol interfaces.
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPrivateData.InstallMultProtHandle,
+ &gEfiSmmGpiDispatchProtocolGuid,
+ &mPrivateData.Protocols[GpiType].Protocols.Gpi,
+ &gEfiSmmSxDispatchProtocolGuid,
+ &mPrivateData.Protocols[SxType].Protocols.Sx,
+ &gEfiSmmSwDispatchProtocolGuid,
+ &mPrivateData.Protocols[SwType].Protocols.Sw,
+ &gEfiSmmIchnDispatchProtocolGuid,
+ &mPrivateData.Protocols[IchnType].Protocols.Ichn,
+ &gEfiSmmIchnDispatchExProtocolGuid,
+ &mPrivateData.Protocols[IchnExType].Protocols.IchnEx,
+ &gEfiSmmPowerButtonDispatchProtocolGuid,
+ &mPrivateData.Protocols[PowerButtonType].Protocols.PowerButton,
+ &gEfiSmmPeriodicTimerDispatchProtocolGuid,
+ &mPrivateData.Protocols[PeriodicTimerType].Protocols.PeriodicTimer,
+ &gEfiSmmUsbDispatchProtocolGuid,
+ &mPrivateData.Protocols[UsbType].Protocols.Usb,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Initialize bits that aren't necessarily related to an SMI source.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SMI source initialization completed.
+ @retval Asserts Global Smi Bit is not enabled successfully.
+**/
+EFI_STATUS
+PchSmmInitHardware (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Clear all SMIs
+ ///
+ PchSmmClearSmi ();
+
+ Status = PchSmmEnableGlobalSmiBit ();
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Be *really* sure to clear all SMIs
+ ///
+ PchSmmClearSmi ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enables the PCH to generate SMIs. Note that no SMIs will be generated
+ if no SMI sources are enabled. Conversely, no enabled SMI source will
+ generate SMIs if SMIs are not globally enabled. This is the main
+ switchbox for SMI generation.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS Enable Global Smi Bit completed
+**/
+EFI_STATUS
+PchSmmEnableGlobalSmiBit (
+ VOID
+ )
+{
+ UINT32 SmiEn;
+
+ SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_EN));
+
+ ///
+ /// Set the "global smi enable" bit
+ ///
+ SmiEn |= B_PCH_SMI_EN_GBL_SMI;
+
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_EN), SmiEn);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Clears the SMI after all SMI source have been processed.
+ Note that this function will not work correctly (as it is
+ written) unless all SMI sources have been processed.
+ A revision of this function could manually clear all SMI
+ status bits to guarantee success.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS Clears the SMIs completed
+ @retval Asserts EOS was not set to a 1
+**/
+EFI_STATUS
+PchSmmClearSmi (
+ VOID
+ )
+{
+ BOOLEAN EosSet;
+ BOOLEAN SciEn;
+ UINT32 Pm1Cnt;
+ UINT16 Pm1Sts;
+ UINT32 Gpe0Sts;
+ UINT32 Gpe0aStsLow;
+ UINT32 Gpe0bStsHigh;
+ UINT32 SmiSts;
+ UINT32 AltGpiSmiSts;
+ UINT16 DevActSts;
+ UINT16 Tco1Sts;
+ UINT16 Tco2Sts;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ Gpe0Sts = 0;
+ Gpe0aStsLow = 0;
+ Gpe0bStsHigh = 0;
+ AltGpiSmiSts = 0;
+ ///
+ /// Determine whether an ACPI OS is present (via the SCI_EN bit)
+ ///
+ Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT));
+ SciEn = (BOOLEAN) ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SCI_EN) == B_PCH_ACPI_PM1_CNT_SCI_EN);
+ if (!SciEn) {
+ ///
+ /// Clear any SMIs that double as SCIs (when SCI_EN==0)
+ ///
+ Pm1Sts = IoRead16 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS));
+ if (PchSeries == PchLp) {
+ Gpe0Sts = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0_STS_127_96));
+ } else if (PchSeries == PchH) {
+ Gpe0aStsLow = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS));
+ Gpe0bStsHigh = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0b_STS));
+ }
+
+ Pm1Sts |=
+ (
+ B_PCH_ACPI_PM1_STS_WAK |
+ B_PCH_ACPI_PM1_STS_PRBTNOR |
+ B_PCH_ACPI_PM1_STS_RTC |
+ B_PCH_ACPI_PM1_STS_PWRBTN |
+ B_PCH_ACPI_PM1_STS_GBL |
+ B_PCH_ACPI_PM1_STS_TMROF
+ );
+
+ if (PchSeries == PchLp) {
+ Gpe0Sts |=
+ (
+ B_PCH_ACPI_GPE0_STS_127_96_PME_B0 |
+ B_PCH_ACPI_GPE0_STS_127_96_PME |
+ B_PCH_ACPI_GPE0_STS_127_96_BATLOW |
+ B_PCH_ACPI_GPE0_STS_127_96_PCI_EXP |
+ B_PCH_ACPI_GPE0_STS_127_96_RI |
+ B_PCH_ACPI_GPE0_STS_127_96_SMB_WAK |
+ B_PCH_ACPI_GPE0_STS_127_96_TC0SCI |
+ B_PCH_ACPI_GPE0_STS_127_96_HOT_PLUG |
+ B_PCH_ACPI_GPE0_STS_127_96_BATLOW |
+ B_PCH_ACPI_GPE0_STS_127_96_GP27
+ );
+ } else if (PchSeries == PchH) {
+ Gpe0aStsLow |=
+ (
+ B_PCH_ACPI_GPE0a_STS_PME_B0 |
+ B_PCH_ACPI_GPE0a_STS_PME |
+ B_PCH_ACPI_GPE0a_STS_BATLOW |
+ B_PCH_ACPI_GPE0a_STS_PCI_EXP |
+ B_PCH_ACPI_GPE0a_STS_RI |
+ B_PCH_ACPI_GPE0a_STS_SMB_WAK |
+ B_PCH_ACPI_GPE0a_STS_TC0SCI |
+ B_PCH_ACPI_GPE0a_STS_HOT_PLUG |
+ B_PCH_ACPI_GPE0a_STS_BATLOW
+ );
+
+ Gpe0bStsHigh |= (B_PCH_ACPI_GPE0b_STS_GP27);
+ }
+
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_STS), (UINT16) Pm1Sts);
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0_STS_127_96), (UINT32) Gpe0Sts);
+ } else if (PchSeries == PchH) {
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS), (UINT32) Gpe0aStsLow);
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_GPE0b_STS), (UINT32) Gpe0bStsHigh);
+ }
+ }
+ ///
+ /// Clear all SMIs that are unaffected by SCI_EN
+ ///
+ if (PchSeries == PchLp) {
+ AltGpiSmiSts = IoRead32 ((UINTN) (mGpioBaseAddr + R_PCH_LPTLP_ALT_GP_SMI_STS));
+ } else if (PchSeries == PchH) {
+ AltGpiSmiSts = IoRead16 ((UINTN) (mAcpiBaseAddr + R_PCH_LPTH_ALT_GP_SMI_STS));
+ }
+ SmiSts = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_STS));
+ DevActSts = IoRead16 ((UINTN) (mAcpiBaseAddr + R_PCH_DEVACT_STS));
+ Tco1Sts = IoRead16 ((UINTN) (mAcpiBaseAddr + PCH_TCO_BASE + R_PCH_TCO1_STS));
+ Tco2Sts = IoRead16 ((UINTN) (mAcpiBaseAddr + PCH_TCO_BASE + R_PCH_TCO2_STS));
+
+ SmiSts |=
+ (
+ B_PCH_SMI_STS_SMBUS |
+ B_PCH_SMI_STS_PERIODIC |
+ B_PCH_SMI_STS_TCO |
+ B_PCH_SMI_STS_MCSMI |
+ B_PCH_SMI_STS_SWSMI_TMR |
+ B_PCH_SMI_STS_APM |
+ B_PCH_SMI_STS_ON_SLP_EN |
+ B_PCH_SMI_STS_BIOS
+ );
+ AltGpiSmiSts |= 0xFFFF;
+ DevActSts |=
+ (
+ B_PCH_DEVACT_STS_KBC |
+ B_PCH_DEVACT_STS_PIRQDH |
+ B_PCH_DEVACT_STS_PIRQCG |
+ B_PCH_DEVACT_STS_PIRQBF |
+ B_PCH_DEVACT_STS_PIRQAE
+ );
+ Tco1Sts |=
+ (
+ B_PCH_TCO1_STS_DMISERR |
+ B_PCH_TCO1_STS_DMISMI |
+ B_PCH_TCO1_STS_DMISCI |
+ B_PCH_TCO1_STS_BIOSWR |
+ B_PCH_TCO1_STS_NEWCENTURY |
+ B_PCH_TCO1_STS_TIMEOUT |
+ B_PCH_TCO1_STS_TCO_INT |
+ B_PCH_TCO1_STS_SW_TCO_SMI
+ );
+ if(PchSeries == PchLp){
+ IoWrite32 ((UINTN) (mGpioBaseAddr + R_PCH_LPTLP_ALT_GP_SMI_STS), AltGpiSmiSts);
+ } else if (PchSeries == PchH) {
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + R_PCH_LPTH_ALT_GP_SMI_STS), (UINT16)AltGpiSmiSts);
+ }
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + PCH_TCO_BASE + R_PCH_TCO1_STS), Tco1Sts);
+
+ Tco2Sts |= B_PCH_TCO2_STS_SECOND_TO;
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + PCH_TCO_BASE + R_PCH_TCO2_STS), Tco2Sts);
+
+ Tco2Sts |= (B_PCH_TCO2_STS_SMLINK_SLV_SMI | B_PCH_TCO2_STS_BOOT | B_PCH_TCO2_STS_INTRD_DET);
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + PCH_TCO_BASE + R_PCH_TCO2_STS), Tco2Sts);
+
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_STS), SmiSts);
+
+ IoWrite16 ((UINTN) (mAcpiBaseAddr + R_PCH_DEVACT_STS), DevActSts);
+
+ ///
+ /// Try to clear the EOS bit. ASSERT on an error
+ ///
+ EosSet = PchSmmSetAndCheckEos ();
+ ASSERT (EosSet);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the SMI EOS bit after all SMI source have been processed.
+
+ @param[in] None
+
+ @retval FALSE EOS was not set to a 1; this is an error
+ @retval TRUE EOS was correctly set to a 1
+**/
+BOOLEAN
+PchSmmSetAndCheckEos (
+ VOID
+ )
+{
+ UINT32 SmiEn;
+
+ SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_EN));
+
+ ///
+ /// Reset the PCH to generate subsequent SMIs
+ ///
+ SmiEn |= B_PCH_SMI_EN_EOS;
+
+ IoWrite32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_EN), SmiEn);
+
+ ///
+ /// Double check that the assert worked
+ ///
+ SmiEn = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_SMI_EN));
+
+ ///
+ /// Return TRUE if EOS is set correctly
+ ///
+ if ((SmiEn & B_PCH_SMI_EN_EOS) == 0) {
+ ///
+ /// EOS was not set to a 1; this is an error
+ ///
+ return FALSE;
+ } else {
+ ///
+ /// EOS was correctly set to a 1
+ ///
+ return TRUE;
+ }
+}
+
+/**
+ Determine whether an ACPI OS is present (via the SCI_EN bit)
+
+ @param[in] None
+
+ @retval TRUE ACPI OS is present
+ @retval FALSE ACPI OS is not present
+**/
+BOOLEAN
+PchSmmGetSciEn (
+ VOID
+ )
+{
+ BOOLEAN SciEn;
+ UINT32 Pm1Cnt;
+
+ ///
+ /// Determine whether an ACPI OS is present (via the SCI_EN bit)
+ ///
+ Pm1Cnt = IoRead32 ((UINTN) (mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT));
+ SciEn = (BOOLEAN) ((Pm1Cnt & B_PCH_ACPI_PM1_CNT_SCI_EN) == B_PCH_ACPI_PM1_CNT_SCI_EN);
+
+ return SciEn;
+}
+
+/**
+ Read a specifying bit with the register
+ These may or may not need to change w/ the PCH version; they're highly IA-32 dependent, though.
+
+ @param[in] BitDesc The struct that includes register address, size in byte and bit number
+
+ @retval TRUE The bit is enabled
+ @retval FALSE The bit is disabled
+**/
+BOOLEAN
+ReadBitDesc (
+ const PCH_SMM_BIT_DESC *BitDesc
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Register;
+ UINT32 PciBus;
+ UINT32 PciDev;
+ UINT32 PciFun;
+ UINT32 PciReg;
+ UINTN RegSize;
+ BOOLEAN BitWasOne;
+ UINTN ShiftCount;
+ UINTN RegisterOffset;
+ UINT32 BaseAddr;
+
+ ASSERT (BitDesc != NULL);
+ ASSERT (!IS_BIT_DESC_NULL (*BitDesc));
+
+ RegSize = 0;
+ Register = 0;
+ ShiftCount = 0;
+ BitWasOne = FALSE;
+
+ switch (BitDesc->Reg.Type) {
+
+ case ACPI_ADDR_TYPE:
+ case GPIO_ADDR_TYPE:
+ if(BitDesc->Reg.Type == ACPI_ADDR_TYPE){
+ RegisterOffset = BitDesc->Reg.Data.acpi;
+ BaseAddr = mAcpiBaseAddr;
+ } else {
+ RegisterOffset = BitDesc->Reg.Data.gpio;
+ BaseAddr = mGpioBaseAddr;
+ }
+ switch (BitDesc->SizeInBytes) {
+
+ case 0:
+ ///
+ /// Chances are that this field didn't get initialized.
+ /// Check your assignments to bit descriptions.
+ ///
+ ASSERT (FALSE);
+ break;
+
+ case 1:
+ RegSize = SMM_IO_UINT8;
+ break;
+
+ case 2:
+ RegSize = SMM_IO_UINT16;
+ break;
+
+ case 4:
+ RegSize = SMM_IO_UINT32;
+ break;
+
+ case 8:
+ RegSize = SMM_IO_UINT64;
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+ ///
+ /// Double check that we correctly read in the acpi base address
+ ///
+ ASSERT ((BaseAddr != 0x0) && ((BaseAddr & 0x1) != 0x1));
+
+ ShiftCount = BitDesc->Bit;
+ ///
+ /// As current CPU Smm Io can only support at most
+ /// 32-bit read/write,if Operation is 64 bit,
+ /// we do a 32 bit operation according to BitDesc->Bit
+ ///
+ if (RegSize == SMM_IO_UINT64) {
+ RegSize = SMM_IO_UINT32;
+ ///
+ /// If the operation is for high 32 bits
+ ///
+ if (BitDesc->Bit >= 32) {
+ RegisterOffset += 4;
+ ShiftCount -= 32;
+ }
+ }
+
+ Status = mSmst->SmmIo.Io.Read (
+ &mSmst->SmmIo,
+ RegSize,
+ BaseAddr + RegisterOffset,
+ 1,
+ &Register
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if ((Register & (LShiftU64 (BIT_ZERO, ShiftCount))) != 0) {
+ BitWasOne = TRUE;
+ } else {
+ BitWasOne = FALSE;
+ }
+ break;
+
+ case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+ ///
+ /// Read the register, and it with the bit to read
+ ///
+ switch (BitDesc->SizeInBytes) {
+ case 1:
+ Register = (UINT64) MmioRead8 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 2:
+ Register = (UINT64) MmioRead16 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 4:
+ Register = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 8:
+ Register = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+ *((UINT32 *) (&Register) + 1) = MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio + 4);
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+
+ Register = Register & (LShiftU64 (BIT0, BitDesc->Bit));
+ if (Register) {
+ BitWasOne = TRUE;
+ } else {
+ BitWasOne = FALSE;
+ }
+ break;
+
+ case PCIE_ADDR_TYPE:
+ PciBus = BitDesc->Reg.Data.pcie.Fields.Bus;
+ PciDev = BitDesc->Reg.Data.pcie.Fields.Dev;
+ PciFun = BitDesc->Reg.Data.pcie.Fields.Fnc;
+ PciReg = BitDesc->Reg.Data.pcie.Fields.Reg;
+ switch (BitDesc->SizeInBytes) {
+
+ case 0:
+ ///
+ /// Chances are that this field didn't get initialized.
+ /// Check your assignments to bit descriptions.
+ ///
+ ASSERT (FALSE);
+ break;
+
+ case 1:
+ Register = (UINT64) MmioRead8 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg));
+ break;
+
+ case 2:
+ Register = (UINT64) MmioRead16 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg));
+ break;
+
+ case 4:
+ Register = (UINT64) MmioRead32 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg));
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+
+ if ((Register & (LShiftU64 (BIT_ZERO, BitDesc->Bit))) != 0) {
+ BitWasOne = TRUE;
+ } else {
+ BitWasOne = FALSE;
+ }
+ break;
+
+ default:
+ ///
+ /// This address type is not yet implemented
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+
+ return BitWasOne;
+}
+
+/**
+ Write a specifying bit with the register
+
+ @param[in] BitDesc The struct that includes register address, size in byte and bit number
+ @param[in] ValueToWrite The value to be wrote
+ @param[in] WriteClear If the rest bits of the register is write clear
+
+ @retval None
+**/
+VOID
+WriteBitDesc (
+ const PCH_SMM_BIT_DESC *BitDesc,
+ const BOOLEAN ValueToWrite,
+ const BOOLEAN WriteClear
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Register;
+ UINT64 AndVal;
+ UINT64 OrVal;
+ UINT32 RegSize;
+ UINT32 PciBus;
+ UINT32 PciDev;
+ UINT32 PciFun;
+ UINT32 PciReg;
+ UINTN RegisterOffset;
+ UINT32 BaseAddr;
+
+ ASSERT (BitDesc != NULL);
+ ASSERT (!IS_BIT_DESC_NULL (*BitDesc));
+
+ RegSize = 0;
+ Register = 0;
+
+ if (WriteClear) {
+ AndVal = LShiftU64 (BIT_ZERO, BitDesc->Bit);
+ } else {
+ AndVal = ~(LShiftU64 (BIT_ZERO, BitDesc->Bit));
+ }
+
+ OrVal = (LShiftU64 ((UINT32) ValueToWrite, BitDesc->Bit));
+
+ switch (BitDesc->Reg.Type) {
+
+ case ACPI_ADDR_TYPE:
+ case GPIO_ADDR_TYPE:
+ if(BitDesc->Reg.Type == ACPI_ADDR_TYPE){
+ RegisterOffset = BitDesc->Reg.Data.acpi;
+ BaseAddr = mAcpiBaseAddr;
+ } else {
+ RegisterOffset = BitDesc->Reg.Data.gpio;
+ BaseAddr = mGpioBaseAddr;
+ }
+ switch (BitDesc->SizeInBytes) {
+
+ case 0:
+ ///
+ /// Chances are that this field didn't get initialized.
+ /// Check your assignments to bit descriptions.
+ ///
+ ASSERT (FALSE);
+ break;
+
+ case 1:
+ RegSize = SMM_IO_UINT8;
+ break;
+
+ case 2:
+ RegSize = SMM_IO_UINT16;
+ break;
+
+ case 4:
+ RegSize = SMM_IO_UINT32;
+ break;
+
+ case 8:
+ RegSize = SMM_IO_UINT64;
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+ ///
+ /// Double check that we correctly read in the acpi base address
+ ///
+ ASSERT ((BaseAddr != 0x0) && ((BaseAddr & 0x1) != 0x1));
+
+ ///
+ /// As current CPU Smm Io can only support at most
+ /// 32-bit read/write,if Operation is 64 bit,
+ /// we do a 32 bit operation according to BitDesc->Bit
+ ///
+ if (RegSize == SMM_IO_UINT64) {
+ RegSize = SMM_IO_UINT32;
+ ///
+ /// If the operation is for high 32 bits
+ ///
+ if (BitDesc->Bit >= 32) {
+ RegisterOffset += 4;
+
+ if (WriteClear) {
+ AndVal = LShiftU64 (BIT_ZERO, BitDesc->Bit - 32);
+ } else {
+ AndVal = ~(LShiftU64 (BIT_ZERO, BitDesc->Bit - 32));
+ }
+
+ OrVal = LShiftU64 ((UINT32) ValueToWrite, BitDesc->Bit - 32);
+ }
+ }
+
+ Status = mSmst->SmmIo.Io.Read (
+ &mSmst->SmmIo,
+ RegSize,
+ BaseAddr + RegisterOffset,
+ 1,
+ &Register
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Register &= AndVal;
+ Register |= OrVal;
+
+ Status = mSmst->SmmIo.Io.Write (
+ &mSmst->SmmIo,
+ RegSize,
+ BaseAddr + RegisterOffset,
+ 1,
+ &Register
+ );
+ ASSERT_EFI_ERROR (Status);
+ break;
+
+ case MEMORY_MAPPED_IO_ADDRESS_TYPE:
+ ///
+ /// Read the register, or it with the bit to set, then write it back.
+ ///
+ switch (BitDesc->SizeInBytes) {
+ case 1:
+ Register = (UINT64) MmioRead8 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 2:
+ Register = (UINT64) MmioRead16 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 4:
+ Register = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+ break;
+
+ case 8:
+ Register = (UINT64) MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio);
+ *((UINT32 *) (&Register) + 1) = MmioRead32 ((UINTN) BitDesc->Reg.Data.Mmio + 4);
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+
+ Register &= AndVal;
+ Register |= OrVal;
+ ///
+ /// Read the register, or it with the bit to set, then write it back.
+ ///
+ switch (BitDesc->SizeInBytes) {
+ case 1:
+ MmioWrite8 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT8) Register);
+ break;
+
+ case 2:
+ MmioWrite16 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT16) Register);
+ break;
+
+ case 4:
+ MmioWrite32 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT32) Register);
+ break;
+
+ case 8:
+ MmioWrite32 ((UINTN) BitDesc->Reg.Data.Mmio, (UINT32) Register);
+ MmioWrite32 ((UINTN) BitDesc->Reg.Data.Mmio + 4, *((UINT32 *) (&Register) + 1));
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+ break;
+
+ case PCIE_ADDR_TYPE:
+ PciBus = BitDesc->Reg.Data.pcie.Fields.Bus;
+ PciDev = BitDesc->Reg.Data.pcie.Fields.Dev;
+ PciFun = BitDesc->Reg.Data.pcie.Fields.Fnc;
+ PciReg = BitDesc->Reg.Data.pcie.Fields.Reg;
+ switch (BitDesc->SizeInBytes) {
+
+ case 0:
+ ///
+ /// Chances are that this field didn't get initialized -- check your assignments
+ /// to bit descriptions.
+ ///
+ ASSERT (FALSE);
+ break;
+
+ case 1:
+ MmioAndThenOr8 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg), (UINT8) AndVal, (UINT8) OrVal);
+ break;
+
+ case 2:
+ MmioAndThenOr16 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg), (UINT16) AndVal, (UINT16) OrVal);
+ break;
+
+ case 4:
+ MmioAndThenOr32 (MmPciAddress (0, PciBus, PciDev, PciFun, PciReg), (UINT32) AndVal, (UINT32) OrVal);
+ break;
+
+ default:
+ ///
+ /// Unsupported or invalid register size
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+ break;
+
+ default:
+ ///
+ /// This address type is not yet implemented
+ ///
+ ASSERT (FALSE);
+ break;
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.h b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.h
new file mode 100644
index 0000000..ead184c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/PchSmiDispatcher/Smm/PchxSmmHelpers.h
@@ -0,0 +1,128 @@
+/** @file
+ This driver is responsible for the registration of child drivers
+ and the abstraction of the PCH SMI sources.
+
+@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
+**/
+#ifndef _PCHX_SMM_HELPERS_H_
+#define _PCHX_SMM_HELPERS_H_
+
+#include "PchSmm.h"
+#include "PchPlatformLib.h"
+
+/**
+ Initialize bits that aren't necessarily related to an SMI source.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SMI source initialization completed.
+ @retval Asserts Global Smi Bit is not enabled successfully.
+**/
+EFI_STATUS
+PchSmmInitHardware (
+ VOID
+ );
+
+/**
+ Enables the PCH to generate SMIs. Note that no SMIs will be generated
+ if no SMI sources are enabled. Conversely, no enabled SMI source will
+ generate SMIs if SMIs are not globally enabled. This is the main
+ switchbox for SMI generation.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS Enable Global Smi Bit completed
+**/
+EFI_STATUS
+PchSmmEnableGlobalSmiBit (
+ VOID
+ );
+
+/**
+ Clears the SMI after all SMI source have been processed.
+ Note that this function will not work correctly (as it is
+ written) unless all SMI sources have been processed.
+ A revision of this function could manually clear all SMI
+ status bits to guarantee success.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS Clears the SMIs completed
+ @retval Asserts EOS was not set to a 1
+**/
+EFI_STATUS
+PchSmmClearSmi (
+ VOID
+ );
+
+/**
+ Set the SMI EOS bit after all SMI source have been processed.
+
+ @param[in] None
+
+ @retval FALSE EOS was not set to a 1; this is an error
+ @retval TRUE EOS was correctly set to a 1
+**/
+BOOLEAN
+PchSmmSetAndCheckEos (
+ VOID
+ );
+
+/**
+ Determine whether an ACPI OS is present (via the SCI_EN bit)
+
+ @param[in] None
+
+ @retval TRUE ACPI OS is present
+ @retval FALSE ACPI OS is not present
+**/
+BOOLEAN
+PchSmmGetSciEn (
+ VOID
+ );
+
+/**
+ Read a specifying bit with the register
+
+ @param[in] BitDesc The struct that includes register address, size in byte and bit number
+
+ @retval TRUE The bit is enabled
+ @retval FALSE The bit is disabled
+**/
+BOOLEAN
+ReadBitDesc (
+ const PCH_SMM_BIT_DESC *BitDesc
+ );
+
+/**
+ Write a specifying bit with the register
+
+ @param[in] BitDesc The struct that includes register address, size in byte and bit number
+ @param[in] ValueToWrite The value to be wrote
+ @param[in] WriteClear If the rest bits of the register is write clear
+
+ @retval None
+**/
+VOID
+WriteBitDesc (
+ const PCH_SMM_BIT_DESC *BitDesc,
+ const BOOLEAN ValueToWrite,
+ const BOOLEAN WriteClear
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c
new file mode 100644
index 0000000..720fcfc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.c
@@ -0,0 +1,388 @@
+/** @file
+ PCH Pcie SMM Driver Entry
+
+@copyright
+ Copyright (c) 2010 - 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 "PchPcieSmm.h"
+
+//
+// Global variables
+//
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+PCH_PCI_EXPRESS_CONFIG *mPciExpressConfig;
+PCH_PWR_OPT_CONFIG *mPchPwrOptConfig;
+UINT8 *mRevision;
+UINT8 mBusNumber;
+
+/**
+ Program Common Clock and ASPM of Downstream Devices
+
+ @param[in] Function Pcie Root Port Function Number
+
+ @retval EFI_SUCCESS Function complete successfully
+**/
+EFI_STATUS
+PchPcieSmi (
+ IN UINT8 Function
+ )
+{
+ UINT16 Data16;
+ UINT8 SecBus;
+ UINT8 SubBus;
+ BOOLEAN L1SubstatesSupported;
+ EFI_HANDLE Handle;
+ PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubVal;
+ UINT8 RootPortNumber;
+ UINT32 RootComplexBar;
+ UINTN PciD31F0RegBase;
+ BOOLEAN LtrSupported;
+ PCH_SERIES PchSeries;
+
+ Handle = NULL;
+ PchSeries = GetPchSeries();
+ LtrSupported = TRUE;
+ PciD31F0RegBase = MmPciAddress (
+ 0,
+ mBusNumber,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ RootComplexBar = MmioRead32 (PciD31F0RegBase + R_PCH_LPC_RCBA) & B_PCH_LPC_RCBA_BAR;
+ RootPortNumber = GetPchPcieRpNumber(RootComplexBar, Function);
+
+ if (RootPortNumber == 0xFF) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Check for presense detect state
+ ///
+ Data16 = MmioRead16 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, R_PCH_PCIE_SLSTS));
+ Data16 &= B_PCH_PCIE_SLSTS_PDS;
+ if (Data16) {
+ SecBus = MmioRead8 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, 0x19));
+ SubBus = MmioRead8 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, 0x1A));
+ PchPcieInitRootPortDownstreamDevices (0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, SecBus, SubBus, NULL);
+ MmioWrite8 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, 0x19), SecBus);
+ MmioWrite8 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, 0x1A), SubBus);
+ L1SubVal = PchPcieL1SubstatesL1_1_2;
+ if ((*mRevision) >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ L1SubVal = mPciExpressConfig->RootPort[RootPortNumber].L1Substates;
+ }
+ PcieSetPm (
+ 0,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ Function,
+ mPciExpressConfig->RootPort[RootPortNumber].Aspm,
+ mPciExpressConfig->NumOfDevAspmOverride,
+ mPciExpressConfig->DevAspmOverride,
+ mPciExpressConfig->TempRootPortBusNumMin,
+ mPciExpressConfig->TempRootPortBusNumMax,
+ mPchPwrOptConfig->NumOfDevLtrOverride,
+ mPchPwrOptConfig->DevLtrOverride,
+ &(mPchPwrOptConfig->PchPwrOptPcie[RootPortNumber]),
+ &L1SubstatesSupported,
+ L1SubVal,
+ *mRevision,
+ FALSE,
+ FALSE,
+ FALSE,
+ &LtrSupported
+ );
+
+ if(!LtrSupported && (PchSeries == PchLp)) {
+ MmioAndThenOr32 ( (RootComplexBar + 0x3320), 0, 0x00010003);
+ }
+ } else {
+ ///
+ /// Clear CCC and LTSP bits when PCIe Card hot unplugged
+ ///
+ MmioAnd32 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, R_PCH_PCIE_MPC2), (UINT32) ~BIT6);
+ MmioAnd16 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, Function, R_PCH_PCIE_LCTL), (UINT16) ~B_PCH_PCIE_LCTL_CCC);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ PCIE Hotplug SMI call back function for each Root port
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The DispatchContext fields are filled in by the dispatching driver
+ prior to invoke this dispatch function
+**/
+VOID
+EFIAPI
+PchPcieSmiHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT *DispatchContext
+ )
+{
+ PchPcieSmi ((UINT8) (DispatchContext->Type - IchnExPcie0Hotplug));
+ return;
+}
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The DispatchContext fields are filled in by the dispatching driver
+ prior to invoke this dispatch function
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT *DispatchContext
+ )
+{
+ return;
+}
+
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT8 Data8;
+ UINT32 Data32Or;
+ UINT32 Data32And;
+ UINTN RPBase;
+ EFI_HANDLE PcieHandle;
+ static CONST EFI_SMM_ICHN_EX_SMI_TYPE PchHPcieHandlerList[LPTH_PCIE_MAX_ROOT_PORTS * 2] = {
+ IchnExPcie0Hotplug,
+ IchnExPcie1Hotplug,
+ IchnExPcie2Hotplug,
+ IchnExPcie3Hotplug,
+ IchnExPcie4Hotplug,
+ IchnExPcie5Hotplug,
+ IchnExPcie6Hotplug,
+ IchnExPcie7Hotplug,
+ IchnExPcie0LinkActive,
+ IchnExPcie1LinkActive,
+ IchnExPcie2LinkActive,
+ IchnExPcie3LinkActive,
+ IchnExPcie4LinkActive,
+ IchnExPcie5LinkActive,
+ IchnExPcie6LinkActive,
+ IchnExPcie7LinkActive
+ };
+ static CONST EFI_SMM_ICHN_EX_SMI_TYPE PchLpPcieHandlerList[LPTLP_PCIE_MAX_ROOT_PORTS * 2] = {
+ IchnExPcie0Hotplug,
+ IchnExPcie1Hotplug,
+ IchnExPcie2Hotplug,
+ IchnExPcie3Hotplug,
+ IchnExPcie4Hotplug,
+ IchnExPcie5Hotplug,
+ IchnExPcie0LinkActive,
+ IchnExPcie1LinkActive,
+ IchnExPcie2LinkActive,
+ IchnExPcie3LinkActive,
+ IchnExPcie4LinkActive,
+ IchnExPcie5LinkActive
+ };
+ EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL *mIchnDispatch;
+ EFI_SMM_ICHN_DISPATCH_EX_CONTEXT PchPcieContext;
+ UINTN PortIndex;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverrideTbl;
+ UINT32 TableSize;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "InitializePchPcieSmm() Start\n"));
+
+ PchSeries = GetPchSeries();
+ DevLtrOverrideTbl = NULL;
+ ///
+ /// Locate SmmBase protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Locate the ICHnEx Dispatch protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmIchnDispatchExProtocolGuid, NULL, (VOID **) &mIchnDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->LocateProtocol (&gDxePchPlatformPolicyProtocolGuid, NULL, (VOID **) &PchPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (PCH_PCI_EXPRESS_CONFIG),
+ (VOID **) &mPciExpressConfig
+ );
+ ASSERT_EFI_ERROR (Status);
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (PCH_PWR_OPT_CONFIG),
+ (VOID **) &mPchPwrOptConfig
+ );
+ ASSERT_EFI_ERROR (Status);
+ mPciExpressConfig->NumOfDevAspmOverride = PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride;
+ TableSize = PchPlatformPolicy->PciExpressConfig->NumOfDevAspmOverride * sizeof (PCH_PCIE_DEVICE_ASPM_OVERRIDE);
+
+ ///
+ /// Allocate and copy ASPM override table to SMM memory
+ ///
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ TableSize,
+ (VOID **) &mPciExpressConfig->DevAspmOverride
+ );
+ ASSERT_EFI_ERROR (Status);
+ CopyMem (mPciExpressConfig->DevAspmOverride, PchPlatformPolicy->PciExpressConfig->DevAspmOverride, TableSize);
+
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (PchPlatformPolicy->Revision),
+ &mRevision
+ );
+ ASSERT_EFI_ERROR (Status);
+ *mRevision = PchPlatformPolicy->Revision;
+ mBusNumber = PchPlatformPolicy->BusNumber;
+ ///
+ /// Allocate and copy LTR override table to SMM memory
+ ///
+ mPchPwrOptConfig->NumOfDevLtrOverride = PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride;
+ DevLtrOverrideTbl = PchPlatformPolicy->PwrOptConfig->DevLtrOverride;
+ if ((DevLtrOverrideTbl != NULL) && (PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride != 0)) {
+ TableSize = PchPlatformPolicy->PwrOptConfig->NumOfDevLtrOverride * sizeof (PCH_PCIE_DEVICE_LTR_OVERRIDE);
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ TableSize,
+ (VOID **) &mPchPwrOptConfig->DevLtrOverride
+ );
+ ASSERT_EFI_ERROR (Status);
+ CopyMem (mPchPwrOptConfig->DevLtrOverride, DevLtrOverrideTbl, TableSize);
+ }
+
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ mPciExpressConfig->RootPort[PortIndex].Aspm = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].Aspm;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2) {
+ mPciExpressConfig->RootPort[PortIndex].L1Substates = PchPlatformPolicy->PciExpressConfig->RootPort[PortIndex].L1Substates;
+ }
+ mPchPwrOptConfig->PchPwrOptPcie[PortIndex].LtrEnable = PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex].LtrEnable;
+ mPchPwrOptConfig->PchPwrOptPcie[PortIndex].ObffEnable = PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex].ObffEnable;
+ if (PchPlatformPolicy->Revision >= DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7) {
+ mPchPwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency = PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency;
+ mPchPwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency = PchPlatformPolicy->PwrOptConfig->PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency;
+ }
+ }
+ ///
+ /// Locate the S3 resume scripting protocol
+ ///
+ INITIALIZE_SCRIPT (ImageHandle, SystemTable);
+
+ //
+ // Throught all PCIE root port function and register the SMI Handler for enabled ports.
+ //
+ for (Index = 0; Index < GetPchMaxPciePortNum (); Index++) {
+ RPBase = MmPciAddress (
+ 0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS,
+ Index,
+ 0
+ );
+ //
+ // Skip the root port function which is not enabled
+ //
+ if (MmioRead32 (RPBase) == 0xFFFFFFFF) {
+ continue;
+ }
+
+ Data8 = MmioRead8 (RPBase + R_PCH_PCIE_SLCAP);
+ if (Data8 & B_PCH_PCIE_SLCAP_HPC) {
+ switch (PchSeries) {
+ case PchLp:
+ PchPcieContext.Type = PchLpPcieHandlerList[Index];
+ break;
+
+ case PchH:
+ PchPcieContext.Type = PchHPcieHandlerList[Index];
+ break;
+ default:
+ break;
+ }
+ PcieHandle = NULL;
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ PchPcieSmiHandlerFunction,
+ &PchPcieContext,
+ &PcieHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ switch (PchSeries) {
+ case PchLp:
+ PchPcieContext.Type = PchLpPcieHandlerList[Index + LPTLP_PCIE_MAX_ROOT_PORTS];
+ break;
+
+ case PchH:
+ PchPcieContext.Type = PchHPcieHandlerList[Index + LPTH_PCIE_MAX_ROOT_PORTS];
+ break;
+ default:
+ break;
+ }
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ PchPcieLinkActiveStateChange,
+ &PchPcieContext,
+ &PcieHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Data32Or = B_PCH_PCIE_MPC_HPME;
+ Data32And = (UINT32)~B_PCH_PCIE_MPC_HPME;
+ 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
+ );
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "InitializePchPcieSmm() End\n"));
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif
new file mode 100644
index 0000000..043b301
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchPcieSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Pcie\Smm"
+ RefName = "PchPcieSmm"
+[files]
+"PchPcieSmm.sdl"
+"PchPcieSmm.mak"
+"PchPcieSmm.h"
+"PchPcieSmm.c"
+"PchPcieSmm.dxs"
+"PchPcieSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs
new file mode 100644
index 0000000..878ce6b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.dxs
@@ -0,0 +1,52 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2010 - 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 (SmmIchnDispatchEx)
+#include EFI_PROTOCOL_DEPENDENCY (BootScriptSave)
+#include EFI_PROTOCOL_DEPENDENCY (PchInfo)
+#include EFI_PROTOCOL_DEPENDENCY (PchPlatformPolicy)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID AND
+#ifdef EFI_S3_RESUME
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID AND
+#endif
+ EFI_PCH_INFO_PROTOCOL_GUID AND
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID
+DEPENDENCY_END
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h
new file mode 100644
index 0000000..caa0f58
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.h
@@ -0,0 +1,99 @@
+/** @file
+ PCH Pcie SMM Driver Header
+
+@copyright
+ Copyright (c) 2010 - 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_PCIE_SMM_H
+#define _PCH_PCIE_SMM_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"
+#endif
+
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include EFI_PROTOCOL_CONSUMER (SmmIchnDispatchEx)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchPciExpressHelpersLib.h"
+//
+// Prototypes
+//
+
+/**
+ Program Common Clock and ASPM of Downstream Devices
+
+ @param[in] PciePortNum Pcie Root Port Number
+
+ @retval EFI_SUCCESS Function complete successfully
+**/
+EFI_STATUS
+PchPcieSmi (
+ IN UINT8 PciePortNum
+ );
+
+/**
+ PCIE Hotplug SMI call back function for each Root port
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The DispatchContext fields are filled in by the dispatching driver
+ prior to invoke this dispatch function
+**/
+VOID
+EFIAPI
+PchPcieSmiHandlerFunction (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT *DispatchContext
+ );
+
+/**
+ PCIE Link Active State Change Hotplug SMI call back function for all Root ports
+
+ @param[in] DispatchHandle Handle of this dispatch function
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The DispatchContext fields are filled in by the dispatching driver
+ prior to invoke this dispatch function
+**/
+VOID
+EFIAPI
+PchPcieLinkActiveStateChange (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT *DispatchContext
+ );
+
+/**
+ Register PCIE Hotplug SMI dispatch function to handle Hotplug enabling
+
+ @param[in] ImageHandle The image handle of this module
+ @param[in] SystemTable The EFI System Table
+
+ @retval EFI_SUCCESS The function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializePchPcieSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf
new file mode 100644
index 0000000..00ca70f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.inf
@@ -0,0 +1,86 @@
+## @file
+# Component description file for PchPcieSmm driver
+#
+#@copyright
+# Copyright (c) 2010 - 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 = PchPcieSmm
+FILE_GUID = acaeaa7a-c039-4424-88da-f42212ea0e55
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchPcieSmm.c
+ PchPcieSmm.h
+
+#
+# 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
+#
+# 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
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ PchPciExpressHelpersLib
+ EfiScriptLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchPcieSmm.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchPcieSmm
+ 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_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak
new file mode 100644
index 0000000..a2d4181
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.mak
@@ -0,0 +1,100 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchPcieSmm/PchPcieSmm.mak 2 2/24/12 2:14a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:14a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchPcieSmm/PchPcieSmm.mak $
+#
+# 2 2/24/12 2:14a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 8:57a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchPcieSmm Driver
+#---------------------------------------------------------------------------
+EDK : PchPcieSmm
+PchPcieSmm : $(BUILD_DIR)\PchPcieSmm.mak PchPcieSmmBin
+
+
+$(BUILD_DIR)\PchPcieSmm.mak : $(PchPcieSmm_DIR)\$(@B).cif $(PchPcieSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchPcieSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchPcieSmm_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(EDK_INCLUDES)
+
+PchPcieSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchPcieSmm"\
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+PchPcieSmm_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformSmmLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPciExpressHelpersDxeLib_LIB)\
+ $(EFISCRIPTLIB)\
+ $(EFIPROTOCOLLIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+PchPcieSmmBin: $(PchPcieSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchPcieSmm.mak all \
+ "MY_INCLUDES=$(PchPcieSmm_INCLUDES)" \
+ "MY_DEFINES=$(PchPcieSmm_DEFINES)" \
+ GUID=ACAEAA7A-C039-4424-88DA-F42212EA0E55\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchPcieSmm_DIR)\PchPcieSmm.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/Pcie/Smm/PchPcieSmm.sdl b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.sdl
new file mode 100644
index 0000000..1e1f223
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Pcie/Smm/PchPcieSmm.sdl
@@ -0,0 +1,69 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchPcieSmm/PchPcieSmm.sdl 1 2/08/12 8:57a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:57a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchPcieSmm/PchPcieSmm.sdl $
+#
+# 1 2/08/12 8:57a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchPcieSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchPcieSmm support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchPcieSmm_DIR"
+ Help = "PchPcieSmm file source directory"
+End
+
+MODULE
+ Help = "Includes PchPcieSmm.mak to Project"
+ File = "PchPcieSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchPcieSmm.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/Ppi/IntelPchPpiLib.cif b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.cif
new file mode 100644
index 0000000..3136c1b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.cif
@@ -0,0 +1,28 @@
+<component>
+ name = "IntelPchPpiLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Ppi\"
+ RefName = "IntelPchPpiLib"
+[files]
+"IntelPchPpiLib.inf"
+"IntelPchPpiLib.sdl"
+"IntelPchPpiLib.mak"
+"Spi\Spi.h"
+"Spi\Spi.c"
+"PchInit\PchInit.h"
+"PchInit\PchInit.c"
+"PchPeiInitDone\PchPeiInitDone.c"
+"PchPeiInitDone\PchPeiInitDone.h"
+"PchUsbPolicy\PchUsbPolicy.c"
+"PchUsbPolicy\PchUsbPolicy.h"
+"PchDmiTcVcMap\PchDmiTcVcMap.c"
+"PchDmiTcVcMap\PchDmiTcVcMap.h"
+"PchPlatformPolicy\PchPlatformPolicy.c"
+"PchPlatformPolicy\PchPlatformPolicy.h"
+"Wdt\Wdt.h"
+"Wdt\Wdt.c"
+"PchReset\PchReset.h"
+"PchReset\PchReset.c"
+"SmmControl\SmmControl.c"
+"SmmControl\SmmControl.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf
new file mode 100644
index 0000000..166d089
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.inf
@@ -0,0 +1,68 @@
+## @file
+# Component description file for the PCH Ppi library
+#
+#@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
+#
+
+[defines]
+BASE_NAME = $(PROJECT_PCH_FAMILY)PpiLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ Spi/Spi.h
+ Spi/Spi.c
+ PchInit/PchInit.h
+ PchInit/PchInit.c
+ PchUsbPolicy/PchUsbPolicy.h
+ PchUsbPolicy/PchUsbPolicy.c
+ PchDmiTcVcMap/PchDmiTcVcMap.h
+ PchDmiTcVcMap/PchDmiTcVcMap.c
+ PchPlatformPolicy/PchPlatformPolicy.h
+ PchPlatformPolicy/PchPlatformPolicy.c
+ Wdt/Wdt.h
+ Wdt/Wdt.c
+ PchReset/PchReset.h
+ PchReset/PchReset.c
+ PchPeiInitDone/PchPeiInitDone.h
+ PchPeiInitDone/PchPeiInitDone.c
+ SmmControl/SmmControl.h
+ SmmControl/SmmControl.c
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+#
+# 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
+
+[nmake.common]
+C_STD_INCLUDE=
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak
new file mode 100644
index 0000000..bd1e833
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.mak
@@ -0,0 +1,63 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IntelPchPpiLib/IntelPchPpiLib.mak 1 2/08/12 8:58a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:58a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelPchPpiLib/IntelPchPpiLib.mak $
+#
+# 1 2/08/12 8:58a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:IntelPchPpiLib
+all : IntelPchPpiLib
+
+$(IntelPchPpiLib_LIB) : IntelPchPpiLib
+
+IntelPchPpiLib : $(BUILD_DIR)\IntelPchPpiLib.mak IntelPchPpiLibBin
+
+$(BUILD_DIR)\IntelPchPpiLib.mak : $(IntelPchPpiLib_DIR)\$(@B).cif $(IntelPchPpiLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IntelPchPpiLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IntelPchPpiLib_INCLUDES =\
+ $(EDK_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+IntelPchPpiLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\IntelPchPpiLib.mak all\
+ "MY_INCLUDES=$(IntelPchPpiLib_INCLUDES)" \
+ TYPE=PEI_LIBRARY LIBRARIES= \
+ LIBRARY_NAME=$(IntelPchPpiLib_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/Ppi/IntelPchPpiLib.sdl b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.sdl
new file mode 100644
index 0000000..776a8cb
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/IntelPchPpiLib.sdl
@@ -0,0 +1,72 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IntelPchPpiLib/IntelPchPpiLib.sdl 1 2/08/12 8:58a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 8:58a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelPchPpiLib/IntelPchPpiLib.sdl $
+#
+# 1 2/08/12 8:58a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IntelPchPpiLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable IntelPchPpiLib support in Project"
+End
+
+PATH
+ Name = "IntelPchPpiLib_DIR"
+ Help = "IntelPchPpiLib file source directory"
+End
+
+MODULE
+ File = "IntelPchPpiLib.mak"
+ Help = "Includes IntelPchPpiLib.mak to Project"
+End
+
+ELINK
+ Name = "IntelPchPpiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IntelPchPpiLib.lib"
+ Parent = "IntelPchPpiLib_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/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c
new file mode 100644
index 0000000..f11b338
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.c
@@ -0,0 +1,43 @@
+/** @file
+ This file defines the DMI TC/VC mapping policy
+
+@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 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+//
+// Include the PPI header file
+//
+#include "PchDmiTcVcMap.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchDmiTcVcMapPpiGuid = PCH_DMI_TC_VC_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPchDmiTcVcMapPpiGuid, "PCH DMI TC VC Map PPI", "PCH DMI TC VC Mapping PPI"); \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h
new file mode 100644
index 0000000..7a2e555
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchDmiTcVcMap/PchDmiTcVcMap.h
@@ -0,0 +1,80 @@
+/** @file
+ This file defines the PCH DMI TC/VC mapping PPI
+
+@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 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
+**/
+#ifndef _PCH_DMI_TC_VC_MAP_H_
+#define _PCH_DMI_TC_VC_MAP_H_
+
+///
+/// Define the PCH DMI TC VC Mapping PPI GUID
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_DMI_TC_VC_PPI_GUID \
+ { \
+ 0xed097352, 0x9041, 0x445a, 0x80, 0xb6, 0xb2, 0x9d, 0x50, 0x9e, 0x88, 0x45 \
+ }
+#else
+#define PCH_DMI_TC_VC_PPI_GUID \
+ { \
+ 0xed097352, 0x9041, 0x445a, \
+ { \
+ 0x80, 0xb6, 0xb2, 0x9d, 0x50, 0x9e, 0x88, 0x45 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPchDmiTcVcMapPpiGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_DMI_TC_VC_PPI PCH_DMI_TC_VC_PPI;
+
+typedef enum {
+ DmiVcTypeVc0,
+ DmiVcTypeVc1,
+ DmiVcTypeVcp,
+ DmiVcTypeVcm,
+ DmiVcTypeMax
+} PCH_DMI_VC_TYPE;
+
+typedef struct {
+ PCH_DMI_VC_TYPE Vc; ///< The Virtual Channel to which the TC is mapped
+} PCH_DMI_TC_CONFIG;
+
+typedef struct {
+ BOOLEAN Enable; ///< 0: Disable; 1: Enable
+ UINT8 VcId; ///< Vc ID Encoding for the Virtual Channel
+} PCH_DMI_VC_CONFIG;
+
+#define DmiTcTypeMax 8
+
+///
+/// PCH_DMI_TC_VC_PPI Structure Definition
+/// Note: The default DMI TC/VC mapping will be used if it's not initialized
+///
+struct _PCH_DMI_TC_VC_PPI {
+ PCH_DMI_TC_CONFIG DmiTc[DmiTcTypeMax]; ///< Configures PCH DMI Traffic class mapping.
+ PCH_DMI_VC_CONFIG DmiVc[DmiVcTypeMax]; ///< Configures PCH DMI Virtual Channel setting.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.c
new file mode 100644
index 0000000..bb31fa3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.c
@@ -0,0 +1,43 @@
+/** @file
+ This file defines the PCH Init PPI
+
+@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
+**/
+
+//
+// Statements that include other files
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+//
+// Include the PPI header file
+//
+#include "PchInit.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchInitPpiGuid = PCH_INIT_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPchInitPpiGuid, "PCH Init PPI", "PCH Initialization PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.h
new file mode 100644
index 0000000..9021a28
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchInit/PchInit.h
@@ -0,0 +1,153 @@
+/** @file
+ This file defines the PCH Init PPI
+
+@copyright
+ Copyright (c) 2006 - 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
+**/
+#ifndef _PCH_INIT_H_
+#define _PCH_INIT_H_
+
+///
+/// Define the PCH Init PPI GUID
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_INIT_PPI_GUID \
+ { \
+ 0x908c7f8b, 0x5c48, 0x47fb, 0x83, 0x57, 0xf5, 0xfd, 0x4e, 0x23, 0x52, 0x76 \
+ }
+#else
+#define PCH_INIT_PPI_GUID \
+ { \
+ 0x908c7f8b, 0x5c48, 0x47fb, \
+ { \
+ 0x83, 0x57, 0xf5, 0xfd, 0x4e, 0x23, 0x52, 0x76 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPchInitPpiGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_INIT_PPI PCH_INIT_PPI;
+
+//
+// Data structure definitions
+//
+typedef enum _CPU_STRAP_OPERATION
+{
+ GetCpuStrapSetData,
+ SetCpuStrapSetData,
+ LockCpuStrapSetData
+} CPU_STRAP_OPERATION;
+
+/**
+ 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.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_USB_INIT) (
+ 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.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_DMI_TCVC_PROGPOLL) (
+ 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
+**/
+typedef
+VOID
+(EFIAPI *PCH_DMI_GEN2_PROG) (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ 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] CpuStrapSet Cpu Strap Set Data
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @exception EFI_UNSUPPORTED The function is not supported.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_CPU_STRAP_SET) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CPU_STRAP_OPERATION Operation,
+ IN OUT UINT16 *CpuStrapSet
+ );
+
+///
+/// PCH_INIT_PPI Structure Definition
+///
+struct _PCH_INIT_PPI {
+ ///
+ /// The function performs USB init in PEI phase. This could be used by USB recovery
+ /// or debug function that USB initialization needs to be done in PEI phase.
+ /// Note: Before executing this function, please be sure that PCH_PLATFORM_POLICY_PPI
+ /// and PCH_USB_POLICY_PPI have been installed.
+ ///
+ PCH_USB_INIT UsbInit;
+ ///
+ /// The function performing TC/VC mapping program, and poll all PCH Virtual Channel
+ /// until negotiation completion.
+ ///
+ PCH_DMI_TCVC_PROGPOLL DmiTcVcProgPoll;
+ ///
+ /// The function changes the PCH target link speed to DMI Gen 2
+ ///
+ PCH_DMI_GEN2_PROG DmiGen2Prog;
+ ///
+ /// The function provides a way to initialize PCH strap data before soft reset
+ /// while doing CPU Only Reset
+ ///
+ PCH_CPU_STRAP_SET CpuStrapSet;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c
new file mode 100644
index 0000000..b754481
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.c
@@ -0,0 +1,47 @@
+/** @file
+ To indicate PCH code finish PCH controller initialization
+ upon policy configuration
+
+@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 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
+**/
+
+//
+// Include the ppi header file
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGluePeim.h"
+#endif
+
+#include EFI_PPI_DEFINITION (PchPeiInitDone)
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchPeiInitDonePpiGuid = PCH_PEI_INIT_DONE_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING
+ (
+ &gPchPeiInitDonePpiGuid, "Pch PEI Init Done Ppi",
+ "This is a dummy PPI to ensure PCH PEI Init Done PPI is updated before RC modules"
+ );
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h
new file mode 100644
index 0000000..ee764cb
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPeiInitDone/PchPeiInitDone.h
@@ -0,0 +1,53 @@
+/** @file
+ PCH Init Done PPI
+
+@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 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
+**/
+
+#ifndef _PCH_PEI_INIT_DONE_PPI_H_
+#define _PCH_PEI_INIT_DONE_PPI_H_
+
+///
+/// GUID for the PCH PEI Init Done PPI
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_PEI_INIT_DONE_PPI_GUID \
+ { \
+ 0x1edcbdf9, 0xffc6, 0x4bd4, 0x94, 0xf6, 0x19, 0x5d, 0x1d, 0xe1, 0x70, 0x56 \
+ }
+#else
+#define PCH_PEI_INIT_DONE_PPI_GUID \
+ { \
+ 0x1edcbdf9, 0xffc6, 0x4bd4, \
+ { \
+ 0x94, 0xf6, 0x19, 0x5d, 0x1d, 0xe1, 0x70, 0x56 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPchPeiInitDonePpiGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_PEI_INIT_DONE_PPI PCH_PEI_INIT_DONE_PPI;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.c
new file mode 100644
index 0000000..206a26a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.c
@@ -0,0 +1,43 @@
+/** @file
+ PCH policy PPI produced by a platform driver specifying various
+ expected PCH settings. This PPI is consumed by the PCH PEI modules.
+
+@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 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGluePeim.h"
+#endif
+
+#include "PchPlatformPolicy.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchPlatformPolicyPpiGuid = PCH_PLATFORM_POLICY_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPchPlatformPolicyPpiGuid, "PchPlatformPolicy PPI", "Intel(R) DXE Phase PCH Platform Policy PPI"); \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.h
new file mode 100644
index 0000000..fbf4694
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchPlatformPolicy/PchPlatformPolicy.h
@@ -0,0 +1,263 @@
+/** @file
+ PCH policy PPI produced by a platform driver specifying various
+ expected PCH settings. This PPI is consumed by the PCH PEI modules.
+
+@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 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
+**/
+#ifndef PCH_PLATFORM_POLICY_H_
+#define PCH_PLATFORM_POLICY_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 "PchAccess.h"
+#include "PchUsbConfig.h"
+#endif
+///
+/// PCH policy provided by platform for PEI phase
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_PLATFORM_POLICY_PPI_GUID \
+ { \
+ 0x36f6ce3d, 0xb76e, 0x42c2, 0x9f, 0x96, 0x3e, 0x41, 0x84, 0xa3, 0x50, 0x66 \
+ }
+#else
+#define PCH_PLATFORM_POLICY_PPI_GUID \
+ { \
+ 0x36f6ce3d, 0xb76e, 0x42c2, \
+ { \
+ 0x9f, 0x96, 0x3e, 0x41, 0x84, 0xa3, 0x50, 0x66 \
+ } \
+ }
+#endif
+
+extern EFI_GUID gPchPlatformPolicyPpiGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_PLATFORM_POLICY_PPI PCH_PLATFORM_POLICY_PPI;
+
+///
+/// PPI revision number
+/// Any backwards compatible changes to this PPI will result in an update in the revision number
+/// Major changes will require publication of a new PPI
+///
+/// Revision 1: Original version
+///
+#define PCH_PLATFORM_POLICY_PPI_REVISION_1 1
+///
+/// Revision 2: Add UsbConfig
+///
+#define PCH_PLATFORM_POLICY_PPI_REVISION_2 2
+///
+/// Revision 3: Add Port30Settings in PCH_USB_CONFIG
+///
+#define PCH_PLATFORM_POLICY_PPI_REVISION_3 3
+///
+/// Revision 4: Add Sata RxEq Settings in PCH_SATA_TRACE_CONFIG
+/// Deprecate PortLength and PortTopology in PCH_SATA_TRACE_CONFIG
+///
+#define PCH_PLATFORM_POLICY_PPI_REVISION_4 4
+//
+// Generic definitions for device enabling/disabling used by PCH code.
+//
+#define PCH_DEVICE_ENABLE 1
+#define PCH_DEVICE_DISABLE 0
+
+//
+// ---------------------------- Gbe Config -----------------------------
+//
+typedef struct {
+ ///
+ /// Determines if enable GBE
+ /// When EnableGbe is changed (from disabled to enabled or from enabled to disabled),
+ /// it needs to set LAN Disable regsiter, which might be locked by FDSWL register.
+ /// So it's recommendated to issue a global reset when changing the status for PCH Internal LAN.
+ ///
+ UINT8 EnableGbe : 1;
+ UINT8 Rsvdbits : 7;
+} PCH_GBE_CONFIG;
+
+//
+// ---------------------------- Thermal Config -----------------------------
+//
+typedef struct {
+ UINT8 PmsyncEnable : 1;
+ UINT8 C0TransmitEnable : 1;
+ UINT8 PinSelection : 1; ///< GpioC 0:GPIO37; 1:GPIO4, GpioD 0:GPIO5; 1:GPIO0
+ UINT8 Rsvdbits : 5;
+} TS_GPIO_PIN_SETTING;
+
+typedef enum {
+ TsGpioC = 0,
+ TsGpioD,
+ MaxTsGpioPin
+} PCH_PMSYNC_GPIO_X_SELECTION;
+
+typedef struct {
+ UINT8 Enable : 1;
+ UINT8 Rsvdbits : 7;
+ TS_GPIO_PIN_SETTING TsGpioPinSetting[MaxTsGpioPin];
+} PCH_MEMORY_THROTTLING;
+
+typedef struct {
+ PCH_MEMORY_THROTTLING *MemoryThrottling;
+} PCH_THERMAL_MANAGEMENT;
+
+//
+// ---------------------------- HPET Config -----------------------------
+//
+typedef struct {
+ BOOLEAN Enable; ///< Determines if enable HPET function
+ UINT32 Base; ///< The HPET base address
+} PCH_HPET_CONFIG;
+
+//
+// ---------------------------- Reserved Page Config -----------------------------
+//
+typedef enum {
+ PchReservedPageToLpc, ///< Port 80h cycles are sent to LPC.
+ PchReservedPageToPcie ///< Port 80h cycles are sent to PCIe.
+} PCH_RESERVED_PAGE_ROUTE;
+
+//
+// ---------------------------- SATA Config -----------------------------
+//
+typedef enum {
+ PchSataModeIde = 0,
+ PchSataModeAhci = 1,
+ PchSataModeRaid = 2,
+ PchSataModeLoopbackTest = 3,
+ PchSataModeMax
+} PCH_SATA_MODE;
+
+typedef enum {
+ PchDirectConnect,
+ PchCableUp
+} PCH_SATA_TOPOLOGY;
+
+///
+/// This policy configures SATA RX Equalization for each Gen Speed.
+/// When enabled, BIOS will configure SATA RXEQ according to RxEq setting, else BIOS will use default setting.
+/// For which RxEq value to use, please refer to PCH EDS for more details.
+///
+typedef struct {
+ UINT8 RxEq;
+ UINT8 Enable;
+}PCH_SATA_GENSPEED;
+
+///
+/// This policy provides the SATA RX Equalization policy for each Gen Speed per port.
+/// GenSpeed[0] configures GEN1 RxEq, GenSpeed[1] configures GEN2 RxEq, and GenSpeed[2] configures GEN3 RxEq.
+///
+typedef struct {
+ PCH_SATA_GENSPEED GenSpeed[3];
+} PCH_SATA_PORT_RXEQ;
+
+typedef struct {
+ UINT16 PortLength[2]; ///< @deprecate
+ UINT8 TestMode : 1; ///< 0: Disable; 1: Allow entrance to the PCH SATA test modes
+ UINT8 RsvdBits : 7;
+ PCH_SATA_TOPOLOGY PortTopology[2]; ///< @deprecate
+ PCH_SATA_PORT_RXEQ PortRxEq[6]; ///< Configure SATA RX Equalization according to platform design
+} PCH_SATA_TRACE_CONFIG;
+
+typedef struct {
+ PCH_SATA_MODE SataMode; ///< Determines the system will be configured to which SATA mode
+ PCH_SATA_TRACE_CONFIG *SataTraceConfig; ///< Decide SATA trace related configurations.
+} PCH_SATA_CONTROL;
+
+//
+// ---------------------------- PCI Express Config -----------------------------
+//
+typedef enum {
+ PchPcieAuto,
+ PchPcieGen1,
+ PchPcieGen2
+} PCH_PCIE_SPEED;
+
+typedef struct {
+ PCH_PCIE_SPEED PcieSpeed[LPTH_PCIE_MAX_ROOT_PORTS]; ///< Determines each PCIE Port speed capability. 0: Auto; 1: Gen1; 2: Gen2.
+} PCH_PCIE_CONFIG;
+
+//
+// ---------------------------- IO APIC Config -----------------------------
+//
+typedef struct {
+ UINT8 IoApicId; ///< This member determines IOAPIC ID.
+ UINT8 ApicRangeSelect; ///< Define address bits 19:12 for the IOxAPIC range
+ UINT8 IoApicEntry24_39 :1; ///< 0: Disable; 1: Enable IOAPIC Entry 24-39
+ UINT8 RsvdBits :7;
+} PCH_IOAPIC_CONFIG;
+
+//
+// ---------------------------- PCH Platform Data -----------------------------
+//
+typedef struct {
+ UINT8 EcPresent : 1; ///< Reports if EC is present or not.
+ UINT8 SmmBwp : 1; ///< 0: Clear SMM_BWP bit; 1: Set SMM_BWP bit.
+ ///< The BIOS must set the SMM_BWP bit while PFAT (Platform Firmware Armoring Technology)
+ ///< support is enabled.
+ UINT8 Rsvdbits : 6;
+ UINT32 TempMemBaseAddr; ///< Temporary Memory Base Address for PCI devices to be
+ ///< used to initialize MMIO registers. Minimum size is
+ ///< 32KB bytes
+} PCH_PLATFORM_DATA;
+
+//
+// ------------ General PCH Platform Policy PPI definition ------------
+//
+struct _PCH_PLATFORM_POLICY_PPI {
+ ///
+ /// This member specifies the revision of the PCH policy PPI. This field is used to
+ /// indicate backwards compatible changes to the protocol. Platform code that produces
+ /// this PPI must fill with the correct revision value for the PCH reference code
+ /// to correctly interpret the content of the PPI fields.
+ ///
+ UINT8 Revision;
+ UINT8 BusNumber; ///< Bus Number of the PCH device.
+ UINT32 Rcba; ///< Root Complex Base Address.
+ UINT16 PmBase; ///< Power management I/O base address.
+ UINT16 GpioBase; ///< General purpose I/O base address.
+ PCH_GBE_CONFIG *GbeConfig; ///< Enable/Disable Gbe function.
+ PCH_THERMAL_MANAGEMENT *ThermalMgmt; ///< Enable the thermal management and pass the GPIO usage.
+ PCH_HPET_CONFIG *HpetConfig; ///< Enable HPET function and the pass HPET base address.
+ PCH_RESERVED_PAGE_ROUTE Port80Route; ///< Control where the Port 80h cycles are sent, 0: LPC; 1: PCI.
+ ///
+ /// SATA configuration that decides which Mode the SATA controller should operate in
+ /// and describes SATA Port 0, 1 Trace length and decides whether PCH SATA TEST mode
+ /// is enabled.
+ ///
+ PCH_SATA_CONTROL *SataConfig;
+ ///
+ /// PCIE configuration describes each PCIE Port speed capability.
+ /// 0: Auto; 1: Gen1; 2:Gen2
+ ///
+ PCH_PCIE_CONFIG *PcieConfig;
+ PCH_IOAPIC_CONFIG *IoApicConfig; ///< Determines IO APIC ID and IO APIC Range.
+ PCH_PLATFORM_DATA *PlatformData; ///< Decides platform data, like EcPresent.
+ ///
+ /// This member decides the USB config and is a common structure for Protocols also.
+ ///
+ PCH_USB_CONFIG *UsbConfig;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.c
new file mode 100644
index 0000000..2eba7db
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.c
@@ -0,0 +1,42 @@
+/** @file
+ This file defines the PCH Reset PPI
+
+@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 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
+**/
+
+//
+// Include the ppi header file
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+#include "PchReset.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchResetPpiGuid = PCH_RESET_PPI_GUID;
+EFI_GUID gPchResetCallbackPpiGuid = PCH_RESET_CALLBACK_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPchResetPpiGuid, "PCH RESET PPI", "Intel(R) PCH Reset PPI");
+EFI_GUID_STRING(&gPchResetCallbackPpiGuid, "PCH RESET CALLBACK PPI", "Intel(R) PCH Reset Callback PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.h
new file mode 100644
index 0000000..8f2c9bd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchReset/PchReset.h
@@ -0,0 +1,68 @@
+/** @file
+ PCH Reset PPI
+
+@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 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
+**/
+#ifndef _PEI_PCH_RESET_H_
+#define _PEI_PCH_RESET_H_
+
+#include <Protocol/PchReset/PchReset.h>
+
+///
+/// GUID for the PCH Reset PPI
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_RESET_PPI_GUID \
+ { \
+ 0x433e0f9f, 0x5ae, 0x410a, 0xa0, 0xc3, 0xbf, 0x29, 0x8e, 0xcb, 0x25, 0xac \
+ }
+
+#define PCH_RESET_CALLBACK_PPI_GUID \
+ { \
+ 0x17865dc0, 0xb8b, 0x4da8, 0x8b, 0x42, 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d \
+ }
+#else
+#define PCH_RESET_PPI_GUID \
+ { \
+ 0x433e0f9f, 0x5ae, 0x410a, \
+ { \
+ 0xa0, 0xc3, 0xbf, 0x29, 0x8e, 0xcb, 0x25, 0xac \
+ } \
+ }
+#define PCH_RESET_CALLBACK_PPI_GUID \
+ { \
+ 0x17865dc0, 0xb8b, 0x4da8, \
+ { \
+ 0x8b, 0x42, 0x7c, 0x46, 0xb8, 0x5c, 0xca, 0x4d \
+ } \
+ }
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPchResetPpiGuid;
+extern EFI_GUID gPchResetCallbackPpiGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef PCH_RESET_PROTOCOL PCH_RESET_PPI;
+
+typedef PCH_RESET_CALLBACK_PROTOCOL PCH_RESET_CALLBACK_PPI;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c b/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c
new file mode 100644
index 0000000..b798bff
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.c
@@ -0,0 +1,45 @@
+/** @file
+ PCH Usb policy PPI produced by a platform driver specifying
+ various expected PCH Usb settings. This PPI is consumed by the
+ PCH PEI drivers.
+
+@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 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+//
+// Include the PPI header file
+//
+#include "PchUsbPolicy.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPchUsbPolicyPpiGuid = PCH_USB_POLICY_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPchUsbPolicyPpiGuid, "PchUsbPolicy PPI", "Intel(R) PCH USB Policy PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h b/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h
new file mode 100644
index 0000000..65e918f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/PchUsbPolicy/PchUsbPolicy.h
@@ -0,0 +1,126 @@
+/** @file
+ PCH Usb policy PPI produced by a platform driver specifying
+ various expected PCH Usb settings. This PPI is consumed by the
+ PCH PEI drivers.
+
+@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 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
+**/
+#ifndef _PCH_USB_POLICY_H_
+#define _PCH_USB_POLICY_H_
+
+///
+/// PCH Usb policy provided by platform for PEI phase
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "PchAccess.h"
+#include "PchPlatformPolicy.h"
+#endif
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_USB_POLICY_PPI_GUID \
+ { \
+ 0x887acae1, 0x6a8c, 0x4eee, 0x97, 0xd, 0x91, 0x12, 0xda, 0x63, 0xbc, 0xf1 \
+ }
+#else
+#define PCH_USB_POLICY_PPI_GUID \
+ { \
+ 0x887acae1, 0x6a8c, 0x4eee, \
+ { \
+ 0x97, 0xd, 0x91, 0x12, 0xda, 0x63, 0xbc, 0xf1 \
+ } \
+ }
+#endif
+
+extern EFI_GUID gPchUsbPolicyPpiGuid;
+
+typedef struct _PCH_USB_POLICY_PPI PCH_USB_POLICY_PPI;
+
+///
+/// PPI revision number
+/// Any backwards compatible changes to this PPI will result in an update in the revision number
+/// Major changes will require publication of a new PPI
+///
+/// Revision 1: Original version
+///
+#define PCH_USB_POLICY_PPI_REVISION_1 1
+///
+/// Revision 2: Add ManualMode, ManualModeUsb20PerPinRoute and ManualModeUsb30PerPinEnable
+/// to PCH_USB30_CONTROLLER_SETTINGS
+/// Deprecated XhciStreams of PCH_USB30_CONTROLLER_SETTINGS
+///
+#define PCH_USB_POLICY_PPI_REVISION_2 2
+///
+/// Revision 3: Add UsbPrecondition in UsbConfig
+///
+#define PCH_USB_POLICY_PPI_REVISION_3 3
+///
+/// Revision 4: Add XhciIdleL1 to PCH_USB30_CONTROLLER_SETTINGS
+///
+#define PCH_USB_POLICY_PPI_REVISION_4 4
+
+//
+// Generic definitions for device enabling/disabling used by PCH code.
+//
+#define PCH_DEVICE_ENABLE 1
+#define PCH_DEVICE_DISABLE 0
+
+#define EHCI_MODE 1
+
+///
+/// PCH Usb policy PPI produced by a platform driver specifying various expected
+/// PCH Usb settings that would be used by PCH_INIT_PPI.UsbInit () and USB PEI module.
+/// This PPI needs to be installed before calling PCH_INIT_PPI.UsbInit ().
+///
+struct _PCH_USB_POLICY_PPI {
+ ///
+ /// This member specifies the revision of the PEI PCH USB Policy PPI.
+ /// This field is used to indicate backwards compatible changes to the protocol.
+ /// Platform code that produces this PPI must fill with the correct revision value
+ /// for the PCH reference code to correctly interpret the content of the PPI fields.
+ ///
+ UINT8 Revision;
+ ///
+ /// This member describes USB controller's related configuration.
+ ///
+ PCH_USB_CONFIG *UsbConfig;
+ ///
+ /// This member decides which USB controller needs to be initialed and allocated
+ /// resource in Pei Phase. It will be referred by USB PEI module.
+ /// For RMH enabled, please set this field to EHCI_MODE.
+ ///
+ UINT8 Mode;
+ ///
+ /// This member describes EHCI memory base address. USB PEI module will refer to
+ /// this field to program memory base address of each EHCI controllers.
+ ///
+ UINTN EhciMemBaseAddr;
+ ///
+ /// This member describes EHCI memory length. USB PEI module will check this field
+ /// to determine if the memory resource is less than the required. Each EHCI controller
+ /// requires 0x400 memory space.
+ ///
+ UINT32 EhciMemLength;
+ ///
+ /// This member describes XHCI memory base address. USB PEI module will refer to
+ /// this field to program memory base address of the XHCI controller.
+ ///
+ UINTN XhciMemBaseAddr;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c b/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c
new file mode 100644
index 0000000..91c73b0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.c
@@ -0,0 +1,26 @@
+/** @file
+ This code abstracts the PEI core to provide SmmControl services.
+
+@copyright
+ Copyright (c) 2002 - 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
+**/
+
+#include "Tiano.h"
+#include "Pei.h"
+#include EFI_PPI_DEFINITION (SmmControl)
+
+EFI_GUID gPeiSmmControlPpiGuid = PEI_SMM_CONTROL_PPI_GUID;
+
+EFI_GUID_STRING(&gPeiSmmControlPpiGuid, "SmmControl", "SMM Control PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h b/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h
new file mode 100644
index 0000000..659aa63
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/SmmControl/SmmControl.h
@@ -0,0 +1,72 @@
+/** @file
+ This code abstracts the PEI core to provide SmmControl services.
+
+@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
+**/
+
+#ifndef _PEI_SMM_CONTROL_PPI_H_
+#define _PEI_SMM_CONTROL_PPI_H_
+
+///
+/// Define the SPI PPI GUID
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PEI_SMM_CONTROL_PPI_GUID \
+ { \
+ 0x61c68702, 0x4d7e, 0x4f43, 0x8d, 0xef, 0xa7, 0x43, 0x5, 0xce, 0x74, 0xc5 \
+ }
+#else
+#define PEI_SMM_CONTROL_PPI_GUID \
+ { \
+ 0x61c68702, 0x4d7e, 0x4f43, \
+ { \
+ 0x8d, 0xef, 0xa7, 0x43, 0x5, 0xce, 0x74, 0xc5 \
+ } \
+ }
+#endif
+
+EFI_FORWARD_DECLARATION (PEI_SMM_CONTROL_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_ACTIVATE) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI * This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_DEACTIVATE) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI * This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+typedef struct _PEI_SMM_CONTROL_PPI {
+ PEI_SMM_ACTIVATE Trigger;
+ PEI_SMM_DEACTIVATE Clear;
+} PEI_SMM_CONTROL_PPI;
+
+extern EFI_GUID gPeiSmmControlPpiGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c b/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c
new file mode 100644
index 0000000..5e58bed
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.c
@@ -0,0 +1,44 @@
+/** @file
+ This file defines the EFI SPI PPI which implements the
+ Intel(R) SPI Host Controller Compatibility Interface.
+
+@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
+**/
+
+//
+// Statements that include other files
+//
+//
+// External include files do NOT need to be explicitly specified in real EDKII
+// environment
+//
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+//
+// Include the PPI header file
+//
+#include "Spi.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gPeiSpiPpiGuid = PEI_SPI_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gPeiSpiPpiGuid, "SPI PPI", "Intel(R) Serial Peripheral Interface PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h b/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h
new file mode 100644
index 0000000..85fef0a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/Spi/Spi.h
@@ -0,0 +1,57 @@
+/** @file
+ This file defines the EFI SPI PPI which implements the
+ Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2006 - 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
+**/
+#ifndef _PEI_SPI_H_
+#define _PEI_SPI_H_
+
+#include <Protocol/Spi/Spi.h>
+
+///
+/// Define the SPI PPI GUID
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PEI_SPI_PPI_GUID \
+ { \
+ 0xfbf26154, 0x4e55, 0x4bdc, 0xaf, 0x7b, 0xd9, 0x18, 0xac, 0x44, 0x3f, 0x61 \
+ }
+#else
+#define PEI_SPI_PPI_GUID \
+ { \
+ 0xfbf26154, 0x4e55, 0x4bdc, \
+ { \
+ 0xaf, 0x7b, 0xd9, 0x18, 0xac, 0x44, 0x3f, 0x61 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gPeiSpiPpiGuid;
+
+///
+/// Reuse the EFI_SPI_PROTOCOL definitions
+/// This is possible becaues the PPI implementation does not rely on a PeiService pointer,
+/// as it uses EDKII Glue Lib to do IO accesses
+///
+typedef EFI_SPI_PROTOCOL PEI_SPI_PPI;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c b/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c
new file mode 100644
index 0000000..1e7827c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.c
@@ -0,0 +1,32 @@
+/** @file
+ Watchdog Timer PPI
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+#include "Wdt.h"
+
+//
+// PPI GUID definition
+//
+EFI_GUID gWdtPpiGuid = WDT_PPI_GUID;
+
+//
+// PPI description
+//
+EFI_GUID_STRING(&gWdtPpiGuid, "WDT PPI", "Watchdog Timer PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h b/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h
new file mode 100644
index 0000000..8246fad
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Ppi/Wdt/Wdt.h
@@ -0,0 +1,53 @@
+/** @file
+ Watchdog Timer PPI
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#ifndef _PEI_WDT_H_
+#define _PEI_WDT_H_
+
+#include <Protocol/Wdt/Wdt.h>
+///
+/// GUID for the WDT PPI
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define WDT_PPI_GUID \
+ { \
+ 0xF38D1338, 0xAF7A, 0x4FB6, 0x91, 0xDB, 0x1A, 0x9C, 0x21, 0x83, 0x57, 0x0D \
+ }
+
+#else
+
+#define WDT_PPI_GUID \
+ { \
+ 0xF38D1338, 0xAF7A, 0x4FB6, \
+ { \
+ 0x91, 0xDB, 0x1A, 0x9C, 0x21, 0x83, 0x57, 0x0D \
+ } \
+ }
+
+#endif
+//
+// Extern the GUID for PPI users.
+//
+extern EFI_GUID gWdtPpiGuid;
+
+///
+/// Reuse WDT_PROTOCOL definition
+///
+typedef WDT_PROTOCOL WDT_PPI;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.c b/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.c
new file mode 100644
index 0000000..6a23962
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.c
@@ -0,0 +1,47 @@
+/** @file
+ This protocol is used to report and control what BIOS is mapped to the
+ BIOS address space anchored at 4GB boundary.
+
+@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
+**/
+
+//
+// Statements that include other files
+//
+//
+// 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"
+#endif
+
+#include "ActiveBios.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiActiveBiosProtocolGuid = EFI_ACTIVE_BIOS_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING
+ (
+ &gEfiActiveBiosProtocolGuid, "Active BIOS Protocol",
+ "The active BIOS protocol provides services related to where BIOS address space is directed in hardware."
+ );
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.h b/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.h
new file mode 100644
index 0000000..744be68
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/ActiveBios/ActiveBios.h
@@ -0,0 +1,136 @@
+/** @file
+ This protocol is used to report and control what BIOS is mapped to the
+ BIOS address space anchored at 4GB boundary.
+
+ This protocol is EFI compatible.
+
+ E.G. For current generation ICH, the 4GB-16MB to 4GB range can be mapped
+ to PCI, SPI, or FWH.
+
+@copyright
+ Copyright (c) 2005 - 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
+**/
+#ifndef _EFI_ACTIVE_BIOS_PROTOCOL_H_
+#define _EFI_ACTIVE_BIOS_PROTOCOL_H_
+
+///
+/// Define the protocol GUID
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_ACTIVE_BIOS_PROTOCOL_GUID \
+ { \
+ 0xebbe2d1b, 0x1647, 0x4bda, 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a \
+ }
+#else
+#define EFI_ACTIVE_BIOS_PROTOCOL_GUID \
+ { \
+ 0xebbe2d1b, 0x1647, 0x4bda, \
+ { \
+ 0xab, 0x9a, 0x78, 0x63, 0xe3, 0x96, 0xd4, 0x1a \
+ } \
+ }
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiActiveBiosProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_ACTIVE_BIOS_PROTOCOL EFI_ACTIVE_BIOS_PROTOCOL;
+
+///
+/// Protocol definitions
+///
+typedef enum {
+ ActiveBiosStateSpi,
+ ActiveBiosStateLpc,
+ ActiveBiosStateMax
+} EFI_ACTIVE_BIOS_STATE;
+
+/**
+ Change the current active BIOS settings to the requested state.
+ The caller is responsible for requesting a supported state from
+ the EFI_ACTIVE_BIOS_STATE selections.
+ This will fail if someone has locked the interface and the correct key is
+ not provided.
+
+ @param[in] This Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+ @param[in] DesiredState The requested state to configure the system for.
+ @param[in] Key If the interface is locked, Key must be the Key
+ returned from the LockState function call.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval EFI_ACCESS_DENIED The interface is currently locked.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE) (
+ IN EFI_ACTIVE_BIOS_PROTOCOL * This,
+ IN EFI_ACTIVE_BIOS_STATE DesiredState,
+ IN UINTN Key
+ );
+
+/**
+ Lock the current active BIOS state from further changes. This allows a
+ caller to implement a critical section. This is optionally supported
+ functionality. Size conscious implementations may choose to require
+ callers cooperate without support from this protocol.
+
+ @param[in] This Pointer to the EFI_ACTIVE_BIOS_PROTOCOL instance.
+ @param[in] Lock TRUE to lock the current state, FALSE to unlock.
+ @param[in, out] Key If Lock is TRUE, then a key will be returned. If
+ Lock is FALSE, the key returned from the prior call
+ to lock the protocol must be provided to unlock the
+ protocol. The value of Key is undefined except that
+ it cannot be 0.
+
+ @retval EFI_SUCCESS Command succeed.
+ @exception EFI_UNSUPPORTED The function is not supported.
+ @retval EFI_ACCESS_DENIED The interface is currently locked.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE) (
+ IN EFI_ACTIVE_BIOS_PROTOCOL * This,
+ IN BOOLEAN Lock,
+ IN OUT UINTN *Key
+ );
+
+///
+/// Protocol definition
+///
+/// Note that some functions are optional. This means that they may be NULL.
+/// Caller is required to verify that an optional function is defined by checking
+/// that the value is not NULL.
+///
+/// This protocol allows the PCH to be configured to map the top 16 MB of memory
+/// below 4 GB to different buses, LPC, SPI, or PCI. The State reflects the current
+/// setting. SetState() allows consumers to request a new state, and LockState()
+/// allows consumers to prevent other consumers from changing the state. It is the
+/// caller's responsibility to configure and lock the desired state to prevent issues
+/// resulting from other consumers changing the state.
+///
+struct _EFI_ACTIVE_BIOS_PROTOCOL {
+ EFI_ACTIVE_BIOS_STATE State; ///< The current state mapping that is selected.
+ EFI_ACTIVE_BIOS_SET_ACTIVE_BIOS_STATE SetState; ///< Change the current state to the requested state mapping.
+ EFI_ACTIVE_BIOS_LOCK_ACTIVE_BIOS_STATE LockState; ///< Lock the current state mapping to prevent changes to the current state.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.cif b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.cif
new file mode 100644
index 0000000..edc8183
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.cif
@@ -0,0 +1,33 @@
+<component>
+ name = "IntelPchProtocolLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Protocol\"
+ RefName = "IntelPchProtocolLib"
+[files]
+"IntelPchProtocolLib.sdl"
+"IntelPchProtocolLib.mak"
+"ActiveBios\ActiveBios.h"
+"ActiveBios\ActiveBios.c"
+"PchPlatformPolicy\PchPlatformPolicy.h"
+"PchPlatformPolicy\PchPlatformPolicy.c"
+"Spi\Spi.h"
+"Spi\Spi.c"
+"SerialGpio\SerialGpio.h"
+"SerialGpio\SerialGpio.c"
+"SmmIoTrapDispatch\SmmIoTrapDispatch.h"
+"SmmIoTrapDispatch\SmmIoTrapDispatch.c"
+"PchInfo\PchInfo.h"
+"PchInfo\PchInfo.c"
+"PchInfo\UsbHcPortPrecondition.h"
+"PchReset\PchReset.h"
+"PchReset\PchReset.c"
+"PchS3Support\PchS3Support.h"
+"PchS3Support\PchS3Support.c"
+"SmmIchnDispatchEx\SmmIchnDispatchEx.h"
+"SmmIchnDispatchEx\SmmIchnDispatchEx.c"
+"IntelPchProtocolLib.inf"
+"Wdt\Wdt.h"
+"Wdt\Wdt.c"
+"PchSmmIoTrapControl\PchSmmIoTrapControl.c"
+"PchSmmIoTrapControl\PchSmmIoTrapControl.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.inf b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.inf
new file mode 100644
index 0000000..ebda5f7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.inf
@@ -0,0 +1,70 @@
+## @file
+# Component description file for the PCH protocol library
+#
+#@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 = $(PROJECT_PCH_FAMILY)ProtocolLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ ActiveBios/ActiveBios.h
+ ActiveBios/ActiveBios.c
+ PchPlatformPolicy/PchPlatformPolicy.h
+ PchPlatformPolicy/PchPlatformPolicy.c
+ Spi/Spi.h
+ Spi/Spi.c
+ SerialGpio/SerialGpio.h
+ SerialGpio/SerialGpio.c
+ SmmIoTrapDispatch/SmmIoTrapDispatch.h
+ SmmIoTrapDispatch/SmmIoTrapDispatch.c
+ PchSmmIoTrapControl/PchSmmIoTrapControl.h
+ PchSmmIoTrapControl/PchSmmIoTrapControl.c
+ PchInfo/PchInfo.h
+ PchInfo/PchInfo.c
+ PchReset/PchReset.h
+ PchReset/PchReset.c
+ PchS3Support/PchS3Support.h
+ PchS3Support/PchS3Support.c
+ SmmIchnDispatchEx/SmmIchnDispatchEx.h
+ SmmIchnDispatchEx/SmmIchnDispatchEx.c
+ Wdt/Wdt.h
+ Wdt/Wdt.c
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+#
+# 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
+
+[nmake.common]
+C_STD_INCLUDE=
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.mak b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.mak
new file mode 100644
index 0000000..1f328b5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.mak
@@ -0,0 +1,62 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/IntelPchProtocolLib/IntelPchProtocolLib.mak 1 2/08/12 9:01a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:01a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelPchProtocolLib/IntelPchProtocolLib.mak $
+#
+# 1 2/08/12 9:01a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+# MAK file for the ModulePart:IntelPchProtocolLib
+EDK : IntelPchProtocolLib
+
+$(INTEL_PCH_PROTOCOL_LIB) : IntelPchProtocolLib
+
+IntelPchProtocolLib : $(BUILD_DIR)\IntelPchProtocolLib.mak IntelPchProtocolLibBin
+
+$(BUILD_DIR)\IntelPchProtocolLib.mak : $(INTEL_PCH_PROTOCOL_LIB_DIR)\$(@B).cif $(INTEL_PCH_PROTOCOL_LIB_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(INTEL_PCH_PROTOCOL_LIB_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IntelPchProtocolLib_INCLUDES =\
+ $(EDK_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+IntelPchProtocolLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\IntelPchProtocolLib.mak all\
+ "MY_INCLUDES=$(IntelPchProtocolLib_INCLUDES)" \
+ TYPE=LIBRARY LIBRARIES=
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Protocol/IntelPchProtocolLib.sdl b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.sdl
new file mode 100644
index 0000000..0d0b35d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/IntelPchProtocolLib.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/IntelPchProtocolLib/IntelPchProtocolLib.sdl 1 2/08/12 9:01a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:01a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/IntelPchProtocolLib/IntelPchProtocolLib.sdl $
+#
+# 1 2/08/12 9:01a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "IntelPchProtocolLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable IntelPchProtocolLib support in Project"
+End
+
+PATH
+ Name = "INTEL_PCH_PROTOCOL_LIB_DIR"
+End
+
+MODULE
+ File = "IntelPchProtocolLib.mak"
+ Help = "Includes IntelPchProtocolLib.mak to Project"
+End
+
+ELINK
+ Name = "INTEL_PCH_PROTOCOL_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IntelPchProtocolLib.lib"
+ Parent = "INTEL_PCH_PROTOCOL_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/Protocol/PchInfo/PchInfo.c b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.c
new file mode 100644
index 0000000..24f5b2e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.c
@@ -0,0 +1,41 @@
+/** @file
+ This file defines the Pch Info Protocol.
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// 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"
+#endif
+
+#include "PchInfo.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiPchInfoProtocolGuid = EFI_PCH_INFO_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gEfiPchInfoProtocolGuid, "PCH Info Protocol", "PCH Information Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h
new file mode 100644
index 0000000..d03867a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/PchInfo.h
@@ -0,0 +1,121 @@
+/** @file
+ This file defines the PCH Info Protocol.
+
+@copyright
+ Copyright (c) 2008 - 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 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
+**/
+#ifndef _PCH_INFO_H_
+#define _PCH_INFO_H_
+
+///
+/// Define PCH INFO protocol GUID
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "UsbHcPortPrecondition.h"
+#define EFI_PCH_INFO_PROTOCOL_GUID \
+ { \
+ 0x984eb4e9, 0x5a95, 0x41de, 0xaa, 0xd0, 0x53, 0x66, 0x8c, 0xa5, 0x13, 0xc0 \
+ }
+
+#else
+#define EFI_PCH_INFO_PROTOCOL_GUID \
+ { \
+ 0x984eb4e9, 0x5a95, 0x41de, \
+ { \
+ 0xaa, 0xd0, 0x53, 0x66, 0x8c, 0xa5, 0x13, 0xc0 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiPchInfoProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_PCH_INFO_PROTOCOL EFI_PCH_INFO_PROTOCOL;
+
+///
+/// Protocol revision number
+/// Any backwards compatible changes to this protocol will result in an update in the revision number
+/// Major changes will require publication of a new protocol
+///
+/// Revision 1: Original version
+///
+#define PCH_INFO_PROTOCOL_REVISION_1 1
+///
+/// Revision 2: Add Preconditioned for Usb precondition support.
+///
+#define PCH_INFO_PROTOCOL_REVISION_2 2
+
+///
+/// RCVersion[7:0] is the release number.
+/// For example:
+/// LptFramework 0.6.0-01 should be 00 06 00 01 (0x00060001)
+/// LptFramework 0.6.2 should be 00 06 02 00 (0x00060200)
+/// LptFramework 0.7.0 should be 00 07 00 00 (0x00070000)
+/// LptFramework 0.7.1 should be 00 07 01 00 (0x00070100)
+/// LptFramework 0.8.0 should be 00 08 00 00 (0x00080000)
+/// LptFramework 0.8.1 should be 00 08 01 00 (0x00080100)
+/// LptFramework 0.9.0 should be 00 09 00 00 (0x00090000)
+/// LptFramework 1.0.0 should be 01 00 00 00 (0x01000000)
+/// LptFramework 1.1.0 should be 01 01 00 00 (0x01010000)
+/// LptFramework 1.2.0 should be 01 02 00 00 (0x01020000)
+/// LptFramework 1.3.0 should be 01 03 00 00 (0x01030000)
+/// LptFramework 1.3.1 should be 01 03 01 00 (0x01030100)
+/// LptFramework 1.4.0 should be 01 04 00 00 (0x01040000)
+/// LptFramework 1.5.0 should be 01 05 00 00 (0x01050000)
+/// LptFramework 1.6.0 should be 01 06 00 00 (0x01060000)
+/// LptFramework 1.6.1 should be 01 06 01 00 (0x01060100)
+/// LptFramework 1.6.2 should be 01 06 02 00 (0x01060200)
+/// LptFramework 1.7.0 should be 01 07 00 00 (0x01070000)
+/// LptFramework 1.8.0 should be 01 08 00 00 (0x01080000)
+/// LptFramework 1.9.0 should be 01 09 00 00 (0x01090000)
+/// LptFramework 1.9.1 should be 01 09 01 00 (0x01090100)
+///
+#define PCH_RC_VERSION 0x01090100
+
+///
+/// Protocol definition
+///
+/// This protocol is used to provide the information of PCH controller.
+///
+struct _EFI_PCH_INFO_PROTOCOL {
+ ///
+ /// This member specifies the revision of the PCH Info protocol. This field is used
+ /// to indicate backwards compatible changes to the protocol. Platform code that
+ /// consumes this protocol must read the correct revision value to correctly interpret
+ /// the content of the protocol fields.
+ ///
+ UINT8 Revision;
+ ///
+ /// The actual bus number of the PCH devices.
+ ///
+ UINT8 BusNumber;
+ ///
+ /// The reference code package release number
+ ///
+ UINT32 RCVersion;
+ ///
+ /// Indicate the Usb precondition feature is working, and it links all the Usb HC
+ /// precondition structures in the list.
+ ///
+ EFI_USB_HC_PORT_PRECONDITION *Preconditioned;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/UsbHcPortPrecondition.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/UsbHcPortPrecondition.h
new file mode 100644
index 0000000..56b13cb
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchInfo/UsbHcPortPrecondition.h
@@ -0,0 +1,53 @@
+/** @file
+ Header file for the PCH USB Common Driver
+
+@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
+**/
+#ifndef _USB_HC_PORT_PRECONDITION_H_
+#define _USB_HC_PORT_PRECONDITION_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#endif
+
+typedef struct _EFI_USB_HC_LOCATION {
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+} EFI_USB_HC_LOCATION;
+
+typedef struct _EFI_USB_PORT_ENUM_TIMING_TABLE {
+ UINTN ResetRecovery;
+} EFI_USB_PORT_ENUM_TIMING_TABLE;
+
+EFI_FORWARD_DECLARATION (EFI_USB_HC_PORT_PRECONDITION);
+
+typedef
+BOOLEAN
+(EFIAPI *EFI_USB_HC_PORT_RESET_STATUS) (
+ IN EFI_USB_HC_PORT_PRECONDITION *This,
+ IN UINT8 PortNumber
+ );
+
+struct _EFI_USB_HC_PORT_PRECONDITION {
+ UINT8 Revision;
+ EFI_USB_HC_PORT_PRECONDITION *Next;
+ EFI_USB_HC_LOCATION Location;
+ EFI_USB_HC_PORT_RESET_STATUS IsRootPortReset;
+ EFI_USB_PORT_ENUM_TIMING_TABLE Timing;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.c b/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.c
new file mode 100644
index 0000000..dfb9d2c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.c
@@ -0,0 +1,44 @@
+/** @file
+ PCH policy protocol produced by a platform driver specifying various
+ expected PCH settings. This protocol is consumed by the PCH drivers.
+
+@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
+**/
+
+//
+// Statements that include other files
+//
+//
+// 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"
+#endif
+
+#include "PchPlatformPolicy.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gDxePchPlatformPolicyProtocolGuid = DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING
+ (&gDxePchPlatformPolicyProtocolGuid, "PchPlatformPolicy Protocol", "Intel(R) DXE Phase PCH Platform Policy Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.h
new file mode 100644
index 0000000..82df716
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchPlatformPolicy/PchPlatformPolicy.h
@@ -0,0 +1,1061 @@
+/** @file
+ PCH policy protocol produced by a platform driver specifying various
+ expected PCH settings. This protocol is consumed by the PCH drivers.
+
+@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
+
+**/
+#ifndef _PCH_PLATFORM_POLICY_H_
+#define _PCH_PLATFORM_POLICY_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 "PchAccess.h"
+#include "PchUsbConfig.h"
+#endif
+///
+/// PCH policy provided by platform for DXE phase
+///
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID \
+ { \
+ 0x9797aaf8, 0xe49b, 0x4f02, 0xa3, 0x68, 0xc8, 0x14, 0x8d, 0x2b, 0xc9, 0xe7 \
+ }
+#else
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID \
+ { \
+ 0x9797aaf8, 0xe49b, 0x4f02, \
+ { \
+ 0xa3, 0x68, 0xc8, 0x14, 0x8d, 0x2b, 0xc9, 0xe7 \
+ } \
+ }
+#endif
+
+extern EFI_GUID gDxePchPlatformPolicyProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL DXE_PCH_PLATFORM_POLICY_PROTOCOL;
+
+///
+/// Protocol revision number
+/// Any backwards compatible changes to this protocol will result in an update in the revision number
+/// Major changes will require publication of a new protocol
+///
+
+///
+/// Revision 1: Original version
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_1 1
+
+///
+/// Revision 2: Add L1Substates in PCH_PCI_EXPRESS_ROOT_PORT_CONFIG
+/// for BIOS Capability to Enable/Disable L1 Substates.
+/// Add override configuration for L1L2 and L1 substates.
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_2 2
+
+///
+/// Revision 3: Add RootPortFunctionSwapping in PCH_PCI_EXPRESS_CONFIG
+/// for switching the support of RootPortFunctionSwapping.
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_3 3
+
+///
+/// Revision 4: Add LegacyDmaDisable in PCH_PWR_OPT_CONFIG
+/// Add PchPwrCycDur in PCH_MISC_PM_CONFIG
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_4 4
+
+///
+/// Revision 5: Add Port30Settings in PCH_USB_CONFIG
+/// Add PcieWakeFromDeepSx in PCH_WAKE_CONFIG
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_5 5
+
+///
+/// Revision 6: Add DciEn in PCH_MISC_CONFIG
+/// Add DDR50 support in PCH_SERIAL_IO_CONFIG
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_6 6
+
+///
+/// Revision 7: Add LTR related policies in PCH_PCIE_PWR_OPT
+/// LtrMaxSnoopLatency
+/// LtrMaxNoSnoopLatency
+/// SnoopLatencyOverrideMode
+/// SnoopLatencyOverrideMultiplier
+/// SnoopLatencyOverrideValue
+/// NonSnoopLatencyOverrideMode
+/// NonSnoopLatencyOverrideMultiplier
+/// NonSnoopLatencyOverrideValue
+/// Update SlpLanLowDc usage.
+///
+#define DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7 7
+
+//
+// Generic definitions for device enabling/disabling used by PCH code.
+//
+#define PCH_DEVICE_ENABLE 1
+#define PCH_DEVICE_DISABLE 0
+
+//
+// ---------------------------- Device Enabling ------------------------------
+//
+///
+/// PCH Device enablings
+///
+/// The PCH_DEVICE_ENABLING block allows platform modules to tell the PCH drivers
+/// to enable/disable a set of PCH features.
+/// Platform modules may need to refer Setup options, schematic, BIOS specification
+/// to update these fields.
+///
+typedef struct {
+ ///
+ /// This member determines if enable or disable Intel Gigabit LAN device.
+ /// It must be set to disable while the device is not used.
+ ///
+ UINT8 Lan : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not Intel HD Audio (Azalia) should be enabled.
+ /// If enabled and no codec exists the reference code will automatically disable
+ /// the Azalia device.
+ ///
+ UINT8 Azalia : 2; ///< 0: Disable; 1: Enable; 2: Auto
+ ///
+ /// This member describes whether or not the SATA controllers should be enabled.
+ ///
+ UINT8 Sata : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the SMBus controller of PCH should be enabled.
+ ///
+ UINT8 Smbus : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the PCI ClockRun feature of PCH should
+ /// be enabled.
+ ///
+ UINT8 PciClockRun : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not PCH display logic should be enabled.
+ /// PCH display logic properly decodes the Register Access that are used to communicate
+ /// with the North Display in the IMC. This device should be enabled or disabled
+ /// as defined in the BIOS specification.
+ ///
+ UINT8 Display : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Compatibility Revision ID (CRID) feature
+ /// of PCH should be enabled.
+ ///
+ UINT8 Crid : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the DMA of Serial IO controllers should be enabled.
+ ///
+ UINT8 SerialIoDma : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO I2c0 controller should be enabled.
+ ///
+ UINT8 SerialIoI2c0 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO I2c1 controller should be enabled.
+ ///
+ UINT8 SerialIoI2c1 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO Spi0 controller should be enabled.
+ ///
+ UINT8 SerialIoSpi0 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO Spi1 controller should be enabled.
+ ///
+ UINT8 SerialIoSpi1 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO Uart0 controller should be enabled.
+ ///
+ UINT8 SerialIoUart0 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO Uart1 controller should be enabled.
+ ///
+ UINT8 SerialIoUart1 : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Serial IO Sdio controller should be enabled.
+ ///
+ UINT8 SerialIoSdio : 1; ///< 0: Disable; 1: Enable
+ ///
+ /// This member describes whether or not the Asdio Dsp controller should be enabled.
+ ///
+ UINT8 AudioDsp : 1; ///< 0: Disable; 1: Enable
+ UINT8 Rsvdbits : 7; ///< Reserved fields for future expansion w/o protocol change
+} PCH_DEVICE_ENABLING;
+
+//
+// ---------------------------- PCI Express Config ----------------------
+//
+///
+/// The values before AutoConfig match the setting of PCI Express Base Specification 1.1, please be careful for adding new feature
+///
+typedef enum {
+ PchPcieAspmDisabled,
+ PchPcieAspmL0s,
+ PchPcieAspmL1,
+ PchPcieAspmL0sL1,
+ PchPcieAspmAutoConfig,
+ PchPcieAspmMax
+} PCH_PCI_EXPRESS_ASPM_CONTROL;
+
+///
+/// Refer to PCH EDS for the PCH implementation values corresponding
+/// to below PCI-E spec defined ranges
+///
+typedef enum {
+ PchPcieL1SubstatesDisabled,
+ PchPcieL1SubstatesL1_1,
+ PchPcieL1SubstatesL1_2,
+ PchPcieL1SubstatesL1_1_2,
+ PchPcieL1SubstatesMax
+} PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL;
+
+typedef enum {
+ PchPcieCompletionTO_Default,
+ PchPcieCompletionTO_50_100us,
+ PchPcieCompletionTO_1_10ms,
+ PchPcieCompletionTO_16_55ms,
+ PchPcieCompletionTO_65_210ms,
+ PchPcieCompletionTO_260_900ms,
+ PchPcieCompletionTO_1_3P5s,
+ PchPcieCompletionTO_4_13s,
+ PchPcieCompletionTO_17_64s,
+ PchPcieCompletionTO_Disabled
+} PCH_PCIE_COMPLETION_TIMEOUT;
+
+typedef enum {
+ PchPcieOverrideDisabled = 0x00,
+ PchPcieL1L2Override = 0x01,
+ PchPcieL1SubstatesOverride = 0x02,
+ PchPcieL1L2AndL1SubstatesOverride = 0x03
+} PCH_PCI_EXPRESS_ASPM_OVERRIDE_CONFIG;
+
+typedef struct {
+ UINT8 Enable : 1; ///< Root Port enabling, 0: Disable; 1: Enable.
+ UINT8 Hide : 1; ///< Whether or not to hide the configuration space of this port.
+ UINT8 SlotImplemented : 1; ///< Indicates whether the root port is connected to a slot.
+ UINT8 HotPlug : 1; ///< Indicate whether the root port is hot plug available.
+ UINT8 PmSci : 1; ///< Indicate whether the root port power manager SCI is enabled.
+ UINT8 ExtSync : 1; ///< Indicate whether the extended synch is enabled.
+ UINT8 Rsvdbits : 2;
+ //
+ // Error handlings
+ //
+ UINT8 UnsupportedRequestReport : 1; ///< Indicate whether the Unsupported Request Report is enabled.
+ UINT8 FatalErrorReport : 1; ///< Indicate whether the Fatal Error Report is enabled.
+ UINT8 NoFatalErrorReport : 1; ///< Indicate whether the No Fatal Error Report is enabled.
+ UINT8 CorrectableErrorReport : 1; ///< Indicate whether the Correctable Error Report is enabled.
+ UINT8 PmeInterrupt : 1; ///< Indicate whether the PME Interrupt is enabled.
+ UINT8 SystemErrorOnFatalError : 1; ///< Indicate whether the System Error on Fatal Error is enabled.
+ UINT8 SystemErrorOnNonFatalError : 1; ///< Indicate whether the System Error on Non Fatal Error is enabled.
+ UINT8 SystemErrorOnCorrectableError : 1; ///< Indicate whether the System Error on Correctable Error is enabled.
+
+ UINT8 AdvancedErrorReporting : 1; ///< Indicate whether the Advanced Error Reporting is enabled
+ UINT8 TransmitterHalfSwing : 1; ///< Indicate whether the Transmitter Half Swing is enabled.
+ UINT8 Reserved : 6; ///< Reserved fields for future expansion w/o protocol change
+
+ UINT8 FunctionNumber; ///< The function number this root port is mapped to
+ UINT8 PhysicalSlotNumber; ///< Indicates the slot number for the root port.
+ PCH_PCIE_COMPLETION_TIMEOUT CompletionTimeout; ///< The completion timeout configuration of the root port
+ PCH_PCI_EXPRESS_ASPM_CONTROL Aspm; ///< The ASPM configuration of the root port
+ PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1Substates; ///< The L1 Substates configuration of the root port
+} PCH_PCI_EXPRESS_ROOT_PORT_CONFIG;
+
+typedef struct {
+ UINT16 VendorId; ///< The vendor Id of Pci Express card ASPM setting override, 0xFFFF means any Vendor ID
+ UINT16 DeviceId; ///< The Device Id of Pci Express card ASPM setting override, 0xFFFF means any Device ID
+ UINT8 RevId; ///< The Rev Id of Pci Express card ASPM setting override, 0xFF means all steppings
+ UINT8 BaseClassCode; ///< The Base Class Code of Pci Express card ASPM setting override, 0xFF means all base class
+ UINT8 SubClassCode; ///< The Sub Class Code of Pci Express card ASPM setting override, 0xFF means all sub class
+ PCH_PCI_EXPRESS_ASPM_CONTROL EndPointAspm; ///< The override ASPM setting from End point
+ PCH_PCI_EXPRESS_ASPM_OVERRIDE_CONFIG OverrideConfig; ///< The override configuration. e.g. 0x0 means this subset is applicable to L1L2 override only.
+ UINT16 L1SubstatesCapOffset; ///< The L1Substates Capability Offset
+ UINT32 L1SubstatesCapMask; ///< The L1Substates Capability Mask
+} PCH_PCIE_DEVICE_ASPM_OVERRIDE;
+
+typedef enum {
+ PchPciePort1,
+ PchPciePort2,
+ PchPciePort3,
+ PchPciePort4,
+ PchPciePort5,
+ PchPciePort6,
+ PchPciePort7,
+ PchPciePort8
+} PCH_PCIE_SBDE_PORTS;
+
+///
+/// The PCH_PCI_EXPRESS_CONFIG block describes the expected configuration of the PCH PCI Express controllers
+///
+typedef struct {
+ ///
+ /// Temp Bus Number range available to be assigned to each root port and its downstream
+ /// devices for initialization of these devices before PCI Bus enumeration.
+ ///
+ UINT8 TempRootPortBusNumMin;
+ ///
+ /// Temp Bus Number range available to be assigned to each root port and its downstream
+ /// devices for initialization of these devices before PCI Bus enumeration.
+ ///
+ UINT8 TempRootPortBusNumMax;
+ ///
+ /// These members describe the configuration of each PCH PCIe root port.
+ ///
+ PCH_PCI_EXPRESS_ROOT_PORT_CONFIG RootPort[LPTH_PCIE_MAX_ROOT_PORTS];
+ UINT8 NumOfDevAspmOverride; ///< Number of Pci Express card Aspm setting override
+ PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride; ///< The Pointer which is point to Pci Express card Aspm setting override
+ ///
+ /// The PCIe Port that selected for enable Subtractive Decode.
+ ///
+ PCH_PCIE_SBDE_PORTS PchPcieSbdePort;
+ ///
+ /// This member describes whether the PCI Express Clock Gating for each root port
+ /// is enabled by platform modules.
+ ///
+ UINT8 RootPortClockGating : 1;
+ ///
+ /// This member determines if enable subtractive decode over PCIe
+ ///
+ UINT8 EnableSubDecode : 1; ///< Determines if enable subtractive decode over PCIe
+ UINT8 Rsvdbits : 6; ///< Reserved fields for future expansion w/o protocol change
+ ///
+ /// Support root port function number swapping if root port of function 0 is disabled.
+ /// When RootPortFunctionSwapping enabled, the FunctionNumber for per root port will be ignored.
+ /// It allows to automatically swap the function 0 to eanble root port by enabling this policy, or
+ /// elaborates the FunctionNumber per root port and disable this policy.
+ /// NOTE: When RootPortFunctionSwapping is disabled, Bios tries to force enable the root port of function 0.
+ /// Be careful not assign the function 0 to the port connecting to Gbe/Nand or no lane available.
+ ///
+ UINT8 RootPortFunctionSwapping;
+} PCH_PCI_EXPRESS_CONFIG;
+
+//
+// ---------------------------- SATA Config -----------------------------
+//
+typedef enum {
+ PchSataOromDelay2sec,
+ PchSataOromDelay4sec,
+ PchSataOromDelay6sec,
+ PchSataOromDelay8sec
+} PCH_SATA_OROM_DELAY;
+
+typedef enum {
+ PchSataSpeedSupportDefault,
+ PchSataSpeedSupportGen1,
+ PchSataSpeedSupportGen2,
+ PchSataSpeedSupportGen3
+} PCH_SATA_SPEED_SUPPORT;
+
+typedef struct {
+ UINT8 Enable : 1; ///< 0: Disable; 1: Enable
+ UINT8 HotPlug : 1; ///< 0: Disable; 1: Enable
+ UINT8 InterlockSw : 1; ///< 0: Disable; 1: Enable
+ UINT8 External : 1; ///< 0: Disable; 1: Enable
+ UINT8 SpinUp : 1; ///< 0: Disable; 1: Enable the COMRESET initialization Sequence to the device
+ UINT8 SolidStateDrive : 1; ///< 0: HDD; 1: SSD
+ UINT8 DevSlp : 1; ///< 0: Disable; 1: Enable DevSlp on the port
+ UINT8 EnableDitoConfig: 1; ///< 0: Disable; 1: Enable
+ UINT8 DmVal : 4; ///< DM value to be set
+ UINT8 Rsvdbits : 4; ///< Reserved fields for future expansion w/o protocol change
+ UINT16 DitoVal : 10; ///< Dito value to be set
+ UINT16 Rsvdbits16 : 6; ///< Reserved fields for future expansion w/o protocol change
+} PCH_SATA_PORT_SETTINGS;
+
+///
+/// The PCH_SATA_CONFIG block describes the expected configuration of the SATA controllers.
+///
+typedef struct {
+ PCH_SATA_PORT_SETTINGS PortSettings[LPTH_AHCI_MAX_PORTS];
+ UINT8 RaidAlternateId : 1; ///< 0: Disable; 1: Enable
+ ///< Whether RAID Alternate ID is enabled. When disabled, the SATA controller D31:F2
+ ///< in RAID mode will report Device ID 282Xh; when enabled, the SATA controller
+ ///< D31:F2 in RAID mode will report Device ID 292Xh.
+ UINT8 Raid0 : 1; ///< 0: Disable; 1: Enable RAID0
+ UINT8 Raid1 : 1; ///< 0: Disable; 1: Enable RAID1
+ UINT8 Raid10 : 1; ///< 0: Disable; 1: Enable RAID10
+ UINT8 Raid5 : 1; ///< 0: Disable; 1: Enable RAID5
+ UINT8 Irrt : 1; ///< 0: Disable; 1: Enable Intel Rapid Recovery Technology
+ UINT8 OromUiBanner : 1; ///< 0: Disable; 1: Enable OROM UI and BANNER
+ UINT8 HddUnlock : 1; ///< 0: Disable; 1: Indicates that the HDD password unlock in the OS is enabled
+
+ UINT8 LedLocate : 1; ///< 0: Disable; 1: Indicates that the LED/SGPIO hardware is attached and ping to locate feature is enabled on the OS
+ UINT8 IrrtOnly : 1; ///< 0: Disable; 1: Allow only IRRT drives to span internal and external ports
+ UINT8 TestMode : 1; ///< 0: Disable; 1: Allow entrance to the PCH SATA test modes
+ UINT8 SalpSupport : 1; ///< 0: Disable; 1: Enable Aggressive Link Power Management
+ UINT8 LegacyMode : 1; ///< 0: Native PCI mode; 1: Legacy mode when controller 1 is operating in IDE mode
+ UINT8 SmartStorage : 1; ///< 0: Disable; 1: Enable RST Smart Storage caching Bit
+ UINT8 OromUiDelay : 2; ///< 00: 2 secs; 01: 4 secs; 10: 6 secs; 11: 8 secs
+
+ UINT8 SpeedSupport : 4; ///< Indicates the maximum speed the SATA controller can support
+ ///< 1h: 1.5 Gb/s (Gen 1); 2h: 3 Gb/s(Gen 2); 3h: 6 Gb/s (Gen 1)
+ UINT8 Rsvdbits : 4; ///< Reserved fields for future expansion w/o protocol change
+} PCH_SATA_CONFIG;
+
+//
+// --------------------------- AZALIA Config ------------------------------
+//
+typedef struct {
+ UINT32 VendorDeviceId; ///< This is the Vendor ID (byte 3 and byte 2) and Device ID (byte 1 and byte 0) of the Azalia codec.
+ UINT16 SubSystemId; ///< This is the sub system ID of this codec.
+ UINT8 RevisionId; ///< This is the revision ID of this codec. 0xFF applies to all steppings
+ UINT8 FrontPanelSupport; ///< Whether or not support front panel. 1: Yes, 0: No.
+ UINT16 NumberOfRearJacks; ///< Number of rear jacks.
+ UINT16 NumberOfFrontJacks; ///< Number of front jacks.
+} PCH_AZALIA_VERB_TABLE_HEADER;
+
+typedef struct {
+ PCH_AZALIA_VERB_TABLE_HEADER VerbTableHeader; ///< The header information in Azalia verb table.
+ UINT32 *VerbTableData; ///< Pointer to the buffer containing verb tables data provided by platform.
+} PCH_AZALIA_VERB_TABLE;
+
+
+///
+/// The AZALIA_CONFIG block describes the expected configuration of the Intel HD Audio (Azalia) feature.
+///
+typedef struct {
+ UINT8 Pme : 1; ///< Azalia wake-on-ring, 0: Disable; 1: Enable
+ UINT8 DS : 1; ///< 0: Docking is not supported; 1:Docking is supported
+ UINT8 DA : 1; ///< 0: Docking is not attached; 1:Docking is attached
+ UINT8 Rsvdbits : 5;
+ UINT8 AzaliaVerbTableNum; ///< Number of verb tables provided by platform
+ PCH_AZALIA_VERB_TABLE *AzaliaVerbTable; ///< Pointer to the actual verb table(s)
+ UINT16 ResetWaitTimer; ///< The delay timer after Azalia reset, the value is number of microseconds
+} PCH_AZALIA_CONFIG;
+
+//
+// --------------------------- AUDIO DSP Config ------------------------------
+//
+///
+/// The PCH_AUDIO_DSP_CONFIG block describes the misc power management configurations
+/// of the Audio Dsp controller, and also the Acpi or Pci mode selection for the
+/// Audio Dsp controller.
+///
+typedef struct {
+ UINT8 AudioDspD3PowerGating : 1; ///< This flag enables/disables the Audio Dsp D3 power gating.
+ UINT8 AudioDspBluetoothSupport : 1; ///< Audio Dsp Bluetooth support enabled.
+ UINT8 AudioDspAcpiMode : 1; ///< If this is enabled, the Audio Dsp device is shown as ACPI device,
+ ///< and the PCI controller for the Audio Dsp will be hidden, and vice versa.
+ UINT8 AudioDspAcpiInterruptMode : 1; ///< If this is enabled, the Audio Dsp device uses ACPI interrupts
+ UINT8 Rsvdbits : 4;
+} PCH_AUDIO_DSP_CONFIG;
+
+//
+// --------------------------- Serial IO Config ------------------------------
+//
+///
+/// The PCH_LP_SERIAL_CONFIG block provides the configurations to set the Serial IO controllers
+/// to Acpi devices or Pci controllers, and also set the interrupt type to Acpi or Pci
+/// through platform policy. It also provides to configure the I2c0 and I2c1 voltage
+/// to 1.8v or 3.3v by platform setting.
+///
+typedef struct {
+ UINT8 SerialIoMode : 1; ///< Set to 0 will create Acpi devices for Serial IO Controllers. Set to 1 will show the Pci devices.
+ UINT8 SerialIoInterruptMode : 1; ///< Configures all Serial IO Controllers in PCI or ACPI Interrupt Mode.
+ UINT8 I2c0VoltageSelect : 1; ///< Selects the IO voltage for I2c0 controller. It can be 1.8v or 3.3v
+ UINT8 I2c1VoltageSelect : 1; ///< selects the IO voltage for I2c1 controller. It can be 1.8v or 3.3v
+ ///
+ /// GpioInt Configuration
+ ///
+ UINT8 GpioIrqRoute : 1; ///< 0: IRQ14; 1: IRQ15
+ UINT8 DriverModeTouchPanel : 1; ///< Driver Mode Touch Panel (ACPI=0:GPIO=1)
+ UINT8 DriverModeTouchPad : 1; ///< Driver Mode Touch Pad (ACPI=0:GPIO=1)
+ UINT8 DriverModeSensorHub : 1; ///< Driver Mode Sensor Hub (ACPI=0;GPIO=1)
+
+ UINT8 Ddr50Support : 1; ///< enables DDR50 support in SDIO controller
+ UINT8 Reserved : 7; // padding
+} PCH_SERIAL_IO_CONFIG;
+
+typedef enum {
+ PchSerialIoIsAcpi = 0,
+ PchSerialIoIsPci
+} PCH_SERIAL_IO_MODE_CONFIG;
+
+typedef enum {
+ PchSerialIoIs33V = 0,
+ PchSerialIoIs18V
+} PCH_LP_SERIAL_IO_VOLTAGE_SEL;
+
+//
+// --------------------------- Smbus Config ------------------------------
+//
+
+///
+/// The SMBUS_CONFIG block lists the reserved addresses for non-ARP capable devices in the platform.
+///
+typedef struct {
+ UINT8 NumRsvdSmbusAddresses; ///< The number of elements in the SmbusAddressTable.
+ UINT8 *RsvdSmbusAddressTable; ///< The pointer to an array of addresses reserved for non-ARP-capable SMBus devices.
+} PCH_SMBUS_CONFIG;
+
+//
+// --------------------------- Miscellaneous PM Config ------------------------------
+//
+typedef struct {
+ UINT8 MeWakeSts : 1; ///< Clear the ME_WAKE_STS bit in the Power and Reset Status (PRSTS) register.
+ UINT8 MeHrstColdSts : 1; ///< Clear the ME_HRST_COLD_STS bit in the Power and Reset Status (PRSTS) register.
+ UINT8 MeHrstWarmSts : 1; ///< Clear the ME_HRST_WARM_STS bit in the Power and Reset Status (PRSTS) register.
+ UINT8 MeHostPowerDn : 1; ///< Clear the ME_HOST_PWRDN bit in the Power and Reset Status (PRSTS) register.
+ UINT8 WolOvrWkSts : 1; ///< Clear the WOL_OVR_WK_STS bit in the Power and Reset Status (PRSTS) register.
+ UINT8 Rsvdbits : 3;
+} PCH_POWER_RESET_STATUS;
+
+typedef struct {
+ UINT8 PmeB0S5Dis : 1; ///< Corresponds to the PME_B0_S5_DIS bit in the General PM Configuration 3 (GEN_PM_CON_3) register.
+ UINT8 WolEnableOverride : 1; ///< Corresponds to the "MOL Enable Override" bit in the General PM Configuration 3 (GEN_PM_CON_3) register.
+ UINT8 Gp27WakeFromDeepSx : 1; ///< Determine if enable GP27 to wake from deep Sx.
+ UINT8 PcieWakeFromDeepSx : 1; ///< Determine if enable PCIe to wake from deep Sx.
+ UINT8 Rsvdbits : 4;
+} PCH_WAKE_CONFIG;
+
+typedef enum {
+ PchDeepSxPolDisable = 0,
+ PchMobileDpS5En,
+ PchDesktopDpS5En,
+ PchMobileDpS4S5En,
+ PchDesktopDpS4S5En,
+ PchMobileDpS3S4S5En,
+ PchDesktopDpS3S4S5En
+} PCH_DEEP_SX_CONFIG;
+
+typedef enum {
+ PchSlpS360us,
+ PchSlpS31ms,
+ PchSlpS350ms,
+ PchSlpS32s
+} PCH_SLP_S3_MIN_ASSERT;
+
+typedef enum {
+ PchSlpS4PchTime, ///< The time defined in PCH EDS Power Sequencing and Reset Signal Timings table
+ PchSlpS41s,
+ PchSlpS42s,
+ PchSlpS43s,
+ PchSlpS44s
+} PCH_SLP_S4_MIN_ASSERT;
+
+typedef enum {
+ PchSlpSus0ms,
+ PchSlpSus500ms,
+ PchSlpSus1s,
+ PchSlpSus4s
+} PCH_SLP_SUS_MIN_ASSERT;
+
+typedef enum {
+ PchSlpA0ms,
+ PchSlpA4s,
+ PchSlpA98ms,
+ PchSlpA2s
+} PCH_SLP_A_MIN_ASSERT;
+
+///
+/// The PCH_MISC_PM_CONFIG block describes expected miscellaneous power management settings.
+/// The PowerResetStatusClear field would clear the Power/Reset status bits, please
+/// set the bits if you want PCH Init driver to clear it, if you want to check the
+/// status later then clear the bits.
+///
+typedef struct {
+ ///
+ /// Specify which Power/Reset bits need to be cleared by
+ /// the PCH Init Driver.
+ /// Usually platform drivers take care of these bits, but if
+ /// not, let PCH Init driver clear the bits.
+ ///
+ PCH_POWER_RESET_STATUS PowerResetStatusClear;
+ PCH_WAKE_CONFIG WakeConfig; ///< Specify Wake Policy
+ PCH_DEEP_SX_CONFIG PchDeepSxPol; ///< Deep Sx Policy
+ PCH_SLP_S3_MIN_ASSERT PchSlpS3MinAssert; ///< SLP_S3 Minimum Assertion Width Policy
+ PCH_SLP_S4_MIN_ASSERT PchSlpS4MinAssert; ///< SLP_S4 Minimum Assertion Width Policy
+ PCH_SLP_SUS_MIN_ASSERT PchSlpSusMinAssert; ///< SLP_SUS Minimum Assertion Width Policy
+ PCH_SLP_A_MIN_ASSERT PchSlpAMinAssert; ///< SLP_A Minimum Assertion Width Policy
+ UINT8 SlpStrchSusUp : 1; ///< Enable/Disable SLP_X Stretching After SUS Well Power Up
+ ///
+ /// Enable/Disable SLP_LAN# Low on DC Power.
+ /// Configure On DC PHY Power Diable according to policy SlpLanLowDc.
+ /// When this is enabled, 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.
+ ///
+ UINT8 SlpLanLowDc : 1;
+ UINT8 Rsvdbits : 6;
+ ///
+ /// Reset Power Cycle Duration could be customized in the unit of second.Please refer to EDS
+ /// for all support settings. So far PCH supports 1~4 seconds, and PCH default is 4 seconds.
+ /// 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
+ ///
+ UINT8 PchPwrCycDur; ///< Reset Power Cycle Duration
+} PCH_MISC_PM_CONFIG;
+
+//
+// --------------------------- IO APIC Config ------------------------------
+//
+///
+/// The PCH_IO_APIC_CONFIG block describes the expected configuration of the PCH
+/// IO APIC, it's optional and PCH code would ignore it if the BdfValid bit is
+/// not TRUE. Bus:device:function fields will be programmed to the register
+/// LPC_IBDF(D31:F0:R6Ch-6Dh), it's using for the following purpose:
+/// As the Requester ID when initiating Interrupt Messages to the processor.
+/// As the Completer ID when responding to the reads targeting the IOxAPI's
+/// Memory-Mapped I/O registers.
+/// This field defaults to Bus 0: Device 31: Function 0 after reset. BIOS can
+/// program this field to provide a unique Bus:Device:Function number for the
+/// internal IOxAPIC.
+///
+typedef struct {
+ BOOLEAN BdfValid; ///< Whether the BDF value is valid, PCH code will not program these fields if this bit is not TRUE.
+ UINT8 BusNumber; ///< Bus/Device/Function used as Requestor / Completer ID.
+ UINT8 DeviceNumber; ///< Bus/Device/Function used as Requestor / Completer ID.
+ UINT8 FunctionNumber; ///< Bus/Device/Function used as Requestor / Completer ID.
+ UINT8 IoApicEntry24_39 :1; ///< 0: Disable; 1: Enable IOAPIC Entry 24-39.
+ UINT8 RsvdBits :7;
+} PCH_IO_APIC_CONFIG;
+
+//
+// --------------------------- Subsystem Vendor ID / Subsystem ID Config -----
+//
+///
+/// The PCH_DEFAULT_SVID_SID block describes the default Subsystem Vendor ID and
+/// Subsystem ID of the PCH devices.
+/// This field will be ignored if the value of SubSystemVendorId and SubSystemId
+/// are both 0.
+/// If the SVID and SID registers of some PCH devices are filled before PchInit
+/// driver execute then this field will be ignored because SVID and SID registers
+/// are write once.
+///
+typedef struct {
+ UINT16 SubSystemVendorId; ///< Default Subsystem Vendor ID of the PCH devices.
+ UINT16 SubSystemId; ///< Default Subsystem ID of the PCH devices.
+} PCH_DEFAULT_SVID_SID;
+
+//
+// --------------------------- Lock Down Config ------------------------------
+//
+#define PCH_BWP_SIGNATURE EFI_SIGNATURE_32 ('P', 'B', 'W', 'P')
+///
+/// The PCH_LOCK_DOWN_CONFIG block describes the expected configuration of the PCH
+/// for security requirement.
+///
+typedef struct {
+ ///
+ /// Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit.
+ ///
+ UINT8 GlobalSmi : 1;
+ ///
+ /// Enable BIOS Interface Lock Down bit to prevent writes to the Backup Control Register
+ /// Top Swap bit and the General Control and Status Registers Boot BIOS Straps.
+ ///
+ UINT8 BiosInterface : 1;
+ ///
+ /// Enable GPIO Lockdown Enable bit to enables lockdown of the GPIO registers:
+ /// GPIO_USE_SEL, GP_IO_SEL, GP_LVL, GPIO_USE_SEL2, GP_IO_SEL2, GP_LVL2,
+ /// GPIO_USE_SEL3, GP_IO_SEL3, GP_LVL3, GP_RST_SEL.
+ ///
+ UINT8 GpioLockDown : 1;
+ ///
+ /// Enable RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh in the upper
+ /// and lower 128-byte bank of RTC RAM.
+ ///
+ UINT8 RtcLock : 1;
+ ///
+ /// Enable the BIOS Lock Enable (BLE) feature and set SMM_BWP bit (D31:F0:RegDCh[5])
+ /// for the BIOS region protection. When it is enabled, the BIOS Region can only be
+ /// modified from SMM after ExitPmAuth protocol is installed.
+ /// Note: When BiosLock is enabled, platform code also needs to update to take care
+ /// of BIOS modification (including SetVariable) in DXE or runtime phase after
+ /// ExitPmAuth protocol is installed.
+ ///
+ UINT8 BiosLock : 1;
+ UINT8 Rsvdbits : 3;
+ ///
+ /// Indicates the IO Address which is used to generate IO Trap SMI to register
+ /// IchnBiosWp callback function in PchBiosLockIoTrapCallback () to handle TCO
+ /// BIOSWR SMI. Please refer to the sample code of PchBiosWriteProtect driver for
+ /// more details about PchBiosLockIoTrapCallback().If PchBiosLockIoTrapAddress is 0,
+ /// BIOS will allocate available IO address with 256 byte range from GCD and pass it
+ /// to PchBiosLockIoTrapAddress. PCH Reference code replaces the SW SMI generated
+ /// by PchBiosLockSwSmiNumber with the IO Trap SMI generated by PchBiosLockIoTrapAddress.
+ ///
+ UINT16 PchBiosLockIoTrapAddress; ///< IO Trap range base address for Bios Lock
+} PCH_LOCK_DOWN_CONFIG;
+
+//
+// --------------------------- Thermal Config ------------------------------------
+//
+typedef struct {
+ UINT8 TselLock : 1;
+ UINT8 TscLock : 1;
+ UINT8 TsmicLock : 1;
+ UINT8 PhlcLock : 1;
+ UINT8 Rsvdbits : 4;
+} PCH_THERMAL_ALERT_ENABLE;
+
+typedef struct {
+ UINT32 T0Level : 9;
+ UINT32 T1Level : 9;
+ UINT32 T2Level : 9;
+ UINT32 TTEnable : 1;
+ UINT32 TTState13Enable : 1;
+ UINT32 TTLock : 1;
+ UINT32 SuggestedSetting : 1; ///< Enable/Disable suggested representative values
+ ///
+ /// ULT processors support thermal management and cross thermal throttling between the processor package
+ /// and LP PCH. The PMSYNC message from PCH to CPU includes specific bit fields to update the PCH
+ /// thermal status to the processor which is factored into the processor throttling.
+ /// Enable/Disable PCH Cross Throttling; 0: Disabled, 1: Enabled
+ ///
+ UINT32 PchCrossThrottling : 1;
+} THERMAL_THROTTLE_LEVELS;
+
+typedef struct {
+ UINT8 DmiTsawEn : 1; ///< DMI Thermal Sensor Autonomous Width Enable
+ UINT8 SuggestedSetting : 1; ///< Enable/Disable suggested representative values
+ UINT8 Rsvdbits : 6;
+
+ UINT8 TS0TW : 2; ///< Thermal Sensor 0 Target Width
+ UINT8 TS1TW : 2; ///< Thermal Sensor 1 Target Width
+ UINT8 TS2TW : 2; ///< Thermal Sensor 2 Target Width
+ UINT8 TS3TW : 2; ///< Thermal Sensor 3 Target Width
+} DMI_HW_WIDTH_CONTROL;
+
+typedef struct {
+ UINT8 P0T1M : 2; ///< Port 0 T1 Multipler
+ UINT8 P0T2M : 2; ///< Port 0 T2 Multipler
+ UINT8 P0T3M : 2; ///< Port 0 T3 Multipler
+ UINT8 P0TDisp : 2; ///< Port 0 Tdispatch
+
+ UINT8 P1T1M : 2; ///< Port 1 T1 Multipler
+ UINT8 P1T2M : 2; ///< Port 1 T2 Multipler
+ UINT8 P1T3M : 2; ///< Port 1 T3 Multipler
+ UINT8 P1TDisp : 2; ///< Port 1 Tdispatch
+
+ UINT8 P0Tinact : 2; ///< Port 0 Tinactive
+ UINT8 P0TDispFinit : 1; ///< Port 0 Alternate Fast Init Tdispatch
+ UINT8 P1Tinact : 2; ///< Port 1 Tinactive
+ UINT8 P1TDispFinit : 1; ///< Port 1 Alternate Fast Init Tdispatch
+ UINT8 SuggestedSetting : 1; ///< Enable/Disable suggested representative values
+ UINT8 Rsvdbits : 1;
+} SATA_THERMAL_THROTTLE;
+
+///
+/// If DmiIot of DmiConfig is enabled, the TTLevels and DmiHaAWC value will not be used.
+///
+typedef struct {
+ THERMAL_THROTTLE_LEVELS TTLevels;
+ DMI_HW_WIDTH_CONTROL DmiHaAWC;
+ SATA_THERMAL_THROTTLE SataTT;
+} PCH_THERMAL_THROTTLING;
+
+///
+/// The PCH_THERMAL_CONFIG block describes the expected configuration of the PCH for Thermal.
+///
+typedef struct {
+ ///
+ /// This field determines if the PCH's TEMP_ALERT# pin will be asserted while the
+ /// temperature of processor core, PCH, Memory Controller/Graphics and DIMM is
+ /// outside the temperature limits.
+ ///
+ PCH_THERMAL_ALERT_ENABLE ThermalAlertEnable;
+ ///
+ /// This field reports the status of Thermal Device. When it reports ThermalDevice
+ /// is disabled, the PCI configuration space of thermal device will be hidden by
+ /// setting FD.TTD prior to end of POST.
+ ///
+ BOOLEAN ThermalDeviceEnable;
+ ///
+ /// This field decides the settings of Thermal throttling. When the Suggested Setting
+ /// is enabled, PCH RC will use the suggested representative values.
+ ///
+ PCH_THERMAL_THROTTLING ThermalThrottling;
+ ///
+ /// This field decides the temperature, 0x00 is the hottest temperature and 0x1FF
+ /// is the lowest temperature
+ ///
+ UINT16 PchHotLevel;
+} PCH_THERMAL_CONFIG;
+
+//
+// --------------------------- HPET Config ------------------------------
+//
+typedef struct {
+ UINT8 BusNumber; ///< Bus Number HPETn used as Requestor / Completer ID
+ UINT8 DeviceNumber; ///< Device Number HPETn used as Requestor / Completer ID
+ UINT8 FunctionNumber; ///< Function Number HPETn used as Requestor / Completer ID
+} PCH_HPET_BDF_CONFIG;
+
+///
+/// The PCH_LPC_HPET_CONFIG block describes the expected configuration of the PCH for HPET.
+///
+typedef struct {
+ BOOLEAN BdfValid; ///< Whether the BDF value is valid
+ PCH_HPET_BDF_CONFIG Hpet[PCH_HPET_BDF_MAX]; ///< Lpc HPET n Bus:Device:Function Configuration
+} PCH_LPC_HPET_CONFIG;
+
+//
+// --------------------------- Serial IRQ Config ------------------------------
+//
+typedef enum {
+ PchQuietMode,
+ PchContinuousMode
+} PCH_SIRQ_MODE;
+///
+/// Refer to PCH EDS for the details of Start Frame Pulse Width in Continuous and Quiet mode
+///
+typedef enum {
+ PchSfpw4Clk,
+ PchSfpw6Clk,
+ PchSfpw8Clk
+} PCH_START_FRAME_PULSE;
+
+///
+/// The PCH_LPC_SIRQ_CONFIG block describes the expected configuration of the PCH for Serial IRQ.
+///
+typedef struct {
+ BOOLEAN SirqEnable; ///< Determines if enable Serial IRQ
+ PCH_SIRQ_MODE SirqMode; ///< Serial IRQ Mode Select. 0: quiet mode 1: continuous mode.
+ PCH_START_FRAME_PULSE StartFramePulse; ///< Start Frame Pulse Width
+} PCH_LPC_SIRQ_CONFIG;
+
+//
+// ---------------------------- DMI Config -----------------------------
+//
+///
+/// The PCH_DMI_CONFIG block describes the expected configuration of the PCH for DMI.
+///
+typedef struct {
+ UINT8 DmiAspm : 1; ///< Enable/Disable ASPM on PCH side of the DMI Link.
+ ///< While DmiAspm is enabled, DMI ASPM will be set to Intel recommended value.
+ UINT8 DmiExtSync : 1; ///< Determines if force extended transmission of FTS ordered sets when
+ ///< exiting L0s prior to entering L0.
+ UINT8 DmiIot : 1; ///< Enable/Disable DMI IOT
+ UINT8 Rsvdbits : 5;
+} PCH_DMI_CONFIG;
+
+//
+// --------------------------- Power Optimizer Config ------------------------------
+//
+typedef struct {
+ UINT8 LtrEnable :1; ///< Latency Tolerance Reporting Mechanism.
+ UINT8 ObffEnable :1; ///< Pcie end point Optimized Buffer Flush/Fill (OBFF) capability for the root port.
+ UINT8 LtrConfigLock :1;
+ UINT8 Rsvdbits :5;
+ UINT16 LtrMaxSnoopLatency; ///< Latency Tolerance Reporting, Max Snoop Latency.
+ UINT16 LtrMaxNoSnoopLatency; ///< Latency Tolerance Reporting, Max Non-Snoop Latency.
+ UINT8 SnoopLatencyOverrideMode; ///< Latency Tolerance Reporting, Snoop Latency Override Mode.
+ UINT8 SnoopLatencyOverrideMultiplier; ///< Latency Tolerance Reporting, Snoop Latency Override Multiplier.
+ UINT16 SnoopLatencyOverrideValue; ///< Latency Tolerance Reporting, Snoop Latency Override Value.
+ UINT8 NonSnoopLatencyOverrideMode; ///< Latency Tolerance Reporting, Non-Snoop Latency Override Mode.
+ UINT8 NonSnoopLatencyOverrideMultiplier; ///< Latency Tolerance Reporting, Non-Snoop Latency Override Multiplier.
+ UINT16 NonSnoopLatencyOverrideValue; ///< Latency Tolerance Reporting, Non-Snoop Latency Override Value.
+} PCH_PCIE_PWR_OPT;
+
+typedef struct {
+ UINT16 VendorId; ///< PCI configuration space offset 0
+ UINT16 DeviceId; ///< PCI configuration space offset 2
+ UINT8 RevId; ///< PCI configuration space offset 8; 0xFF means all steppings
+/**
+ SnoopLatency bit definition
+ Note: All Reserved bits must be set to 0
+
+ BIT[15] - When set to 1b, indicates that the values in bits 9:0 are valid
+ When clear values in bits 9:0 will be ignored
+ BITS[14:13] - Reserved
+ BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+ 000b - 1 ns
+ 001b - 32 ns
+ 010b - 1024 ns
+ 011b - 32,768 ns
+ 100b - 1,048,576 ns
+ 101b - 33,554,432 ns
+ 110b - Reserved
+ 111b - Reserved
+ BITS[9:0] - Snoop Latency Value. The value in these bits will be multiplied with
+ the scale in bits 12:10
+**/
+ UINT16 SnoopLatency;
+/**
+ NonSnoopLatency bit definition
+ Note: All Reserved bits must be set to 0
+
+ BIT[15] - When set to 1b, indicates that the values in bits 9:0 are valid
+ When clear values in bits 9:0 will be ignored
+ BITS[14:13] - Reserved
+ BITS[12:10] - Value in bits 9:0 will be multiplied with the scale in these bits
+ 000b - 1 ns
+ 001b - 32 ns
+ 010b - 1024 ns
+ 011b - 32,768 ns
+ 100b - 1,048,576 ns
+ 101b - 33,554,432 ns
+ 110b - Reserved
+ 111b - Reserved
+ BITS[9:0] - Non Snoop Latency Value. The value in these bits will be multiplied with
+ the scale in bits 12:10
+**/
+ UINT16 NonSnoopLatency;
+} PCH_PCIE_DEVICE_LTR_OVERRIDE;
+
+///
+/// The PCH_PWR_OPT_CONFIG block describes the expected configuration of the PCH for Power Optimizer.
+///
+typedef struct {
+ UINT8 PchPwrOptDmi :1; ///< enable/disable DMI Power Optimizer on PCH side.
+ UINT8 PchPwrOptGbe :1; ///< enable/disable Gbe Power Optimizer on PCH side.
+ UINT8 PchPwrOptXhci :1; ///< enable/disable XHCI Power Optimizer on PCH side.
+ UINT8 PchPwrOptEhci :1; ///< enable/disable EHCI Power Optimizer on PCH side.
+ UINT8 PchPwrOptSata :1; ///< enable/disable SATA Power Optimizer on PCH side.
+ UINT8 MemCloseStateEn :1; ///< enable/disable MEM CLOSED State on PCH side.
+ UINT8 InternalObffEn :1; ///< enable/disable Optimized Buffer Flush/Fill (OBFF) protocol for internal on PCH side.
+ UINT8 ExternalObffEn :1; ///< enable/disable Optimized Buffer Flush/Fill (OBFF) protocol for external on PCH side.
+ UINT8 NumOfDevLtrOverride; ///< Number of Pci Express card listed in LTR override table
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride; ///< Pointer to Pci Express devices LTR override table
+ PCH_PCIE_PWR_OPT PchPwrOptPcie[LPTH_PCIE_MAX_ROOT_PORTS]; ///< related configuration for PCIE ports power optimization.
+ UINT8 LegacyDmaDisable :1; ///< disable/enable legacy DMA controller (8254) and port 0x61 timer
+ UINT8 Rsvdbits :7;
+} PCH_PWR_OPT_CONFIG;
+
+//
+// --------------------- Miscellaneous Config ------------------------------
+//
+///
+/// The PCH_MISC_CONFIG block describes the expected configuration of the PCH for Miscellaneous Configuration.
+///
+typedef struct {
+ ///
+ /// This member determines the SMBIOS OEM type (0x80 to 0xFF) defined in SMBIOS
+ /// Type 14 - Group Associations structure - item type.
+ /// FVI structure uses it as SMBIOS OEM type to provide version information.
+ ///
+ UINT8 FviSmbiosType;
+ ///
+ /// This member enables/disables Direct Connect Interface (DCI) for LPT-LP.
+ /// 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.
+ ///
+ UINT8 DciEn :1;
+ UINT8 Rsvdbits :7;
+} PCH_MISC_CONFIG;
+
+//
+// ------------ General PCH Platform Policiy protocol definition ------------
+//
+///
+/// The PCH platform policy protocol allows the platform code to publish a set of
+/// configuration information that the PCH drivers will use to configure the PCH hardware.
+/// The Revision field is used to accommodate backward compatible changes to the protocol.
+/// The Revision should be initialized to DXE_PLATFORM_PCH_POLICY_PROTOCOL_REVISION_X
+/// by the protocol producer.
+/// The BusNumber field is used for platform to assign Bus number with multiple instances.
+///
+struct _DXE_PCH_PLATFORM_POLICY_PROTOCOL {
+ ///
+ /// This member specifies the revision of the PCH Policy protocol.
+ /// This field is used to indicate backwards compatible changes to the protocol.
+ /// Platform code that produces this protocol must fill with the correct revision
+ /// value for the PCH reference code to correctly interpret the content of the
+ /// protocol fields.
+ ///
+ UINT8 Revision;
+ ///
+ /// This member describes the desired bus number of the PCH controller.
+ ///
+ UINT8 BusNumber;
+ ///
+ /// This member describes which PCH devices should be enabled or disabled.
+ ///
+ PCH_DEVICE_ENABLING *DeviceEnabling;
+ ///
+ /// This member describes USB controller's related configuration.
+ ///
+ PCH_USB_CONFIG *UsbConfig;
+ ///
+ /// This member describes PCI Express controller's related configuration.
+ ///
+ PCH_PCI_EXPRESS_CONFIG *PciExpressConfig;
+ ///
+ /// This member describes SATA controller's related configuration.
+ ///
+ PCH_SATA_CONFIG *SataConfig;
+ ///
+ /// This member describes the Intel HD Audio (Azalia) related configuration.
+ ///
+ PCH_AZALIA_CONFIG *AzaliaConfig;
+ ///
+ /// This member describes SMBus related configuration.
+ ///
+ PCH_SMBUS_CONFIG *SmbusConfig;
+ ///
+ /// This member describes miscellaneous platform power management configurations.
+ ///
+ PCH_MISC_PM_CONFIG *MiscPmConfig;
+ ///
+ /// This member describes IOAPIC related configuration.
+ ///
+ PCH_IO_APIC_CONFIG *IoApicConfig;
+ ///
+ /// This member describes default SVID and Sid for PCH devices.
+ ///
+ PCH_DEFAULT_SVID_SID *DefaultSvidSid;
+ ///
+ /// This member describes LockDown related configuration.
+ ///
+ PCH_LOCK_DOWN_CONFIG *LockDownConfig;
+ ///
+ /// This member describes Thermal related configuration.
+ ///
+ PCH_THERMAL_CONFIG *ThermalConfig;
+ ///
+ /// This member describes HPET related configuration.
+ ///
+ PCH_LPC_HPET_CONFIG *HpetConfig;
+ ///
+ /// This member describes the expected configuration of the PCH for Serial IRQ.
+ ///
+ PCH_LPC_SIRQ_CONFIG *SerialIrqConfig;
+ ///
+ /// This member describes DMI related configuration.
+ ///
+ PCH_DMI_CONFIG *DmiConfig;
+ ///
+ /// This member describes the Power Optimizer configuration.
+ ///
+ PCH_PWR_OPT_CONFIG *PwrOptConfig;
+ ///
+ /// This member describes the Miscellaneous configuration.
+ ///
+ PCH_MISC_CONFIG *MiscConfig;
+ ///
+ /// This member describes the Audio Dsp related configuration
+ ///
+ PCH_AUDIO_DSP_CONFIG *AudioDspConfig;
+ ///
+ /// This member describes the Serial IO related configuration
+ ///
+ PCH_SERIAL_IO_CONFIG *SerialIoConfig;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.c b/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.c
new file mode 100644
index 0000000..28210a6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.c
@@ -0,0 +1,44 @@
+/** @file
+ This file defines the PCH Reset Protocol
+
+@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 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
+**/
+
+//
+// Include the protocol header file
+//
+//
+// 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"
+#endif
+
+#include "PchReset.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gPchResetProtocolGuid = PCH_RESET_PROTOCOL_GUID;
+EFI_GUID gPchResetCallbackProtocolGuid = PCH_RESET_CALLBACK_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gPchResetProtocolGuid, "PCH Reset Protocol", "Intel(R) PCH Reset Protocol");
+EFI_GUID_STRING(&gPchResetProtocolGuid, "PCH Reset Callback Protocol", "Intel(R) PCH Reset Callback Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.h
new file mode 100644
index 0000000..f11a744
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchReset/PchReset.h
@@ -0,0 +1,139 @@
+/** @file
+ PCH Reset Protocol
+
+@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 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
+**/
+#ifndef _PCH_RESET_H_
+#define _PCH_RESET_H_
+
+///
+/// GUID for the PCH Reset Protocol
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_RESET_PROTOCOL_GUID \
+ { \
+ 0xdb63592c, 0xb8cc, 0x44c8, 0x91, 0x8c, 0x51, 0xf5, 0x34, 0x59, 0x8a, 0x5a \
+ }
+#define PCH_RESET_CALLBACK_PROTOCOL_GUID \
+ { \
+ 0x3a3300ab, 0xc929, 0x487d, 0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0 \
+ }
+#else
+#define PCH_RESET_PROTOCOL_GUID \
+ { \
+ 0xdb63592c, 0xb8cc, 0x44c8, \
+ { \
+ 0x91, 0x8c, 0x51, 0xf5, 0x34, 0x59, 0x8a, 0x5a \
+ } \
+ }
+#define PCH_RESET_CALLBACK_PROTOCOL_GUID \
+ { \
+ 0x3a3300ab, 0xc929, 0x487d, \
+ { \
+ 0xab, 0x34, 0x15, 0x9b, 0xc1, 0x35, 0x62, 0xc0 \
+ } \
+ }
+#endif
+
+#define EFI_CAPSULE_VARIABLE_NAME L"CapsuleUpdateData"
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gPchResetProtocolGuid;
+extern EFI_GUID gPchResetCallbackProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_RESET_PROTOCOL PCH_RESET_PROTOCOL;
+
+typedef struct _PCH_RESET_CALLBACK_PROTOCOL PCH_RESET_CALLBACK_PROTOCOL;
+
+//
+// Related Definitions
+//
+///
+/// PCH Reset Types
+///
+typedef enum {
+ ColdReset,
+ WarmReset,
+ ShutdownReset,
+ PowerCycleReset,
+ GlobalReset,
+ GlobalResetWithEc
+} PCH_RESET_TYPE;
+
+//
+// Member functions
+//
+/**
+ Execute Pch Reset from the host controller.
+
+ @param[in] This Pointer to the PCH_RESET_PROTOCOL instance.
+ @param[in] PchResetType Pch Reset Types which includes ColdReset, WarmReset, ShutdownReset,
+ PowerCycleReset, GlobalReset, GlobalResetWithEc
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_INVALID_PARAMETER If ResetType is invalid.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET) (
+ IN PCH_RESET_PROTOCOL * This,
+ IN PCH_RESET_TYPE PchResetType
+ );
+
+/**
+ Execute call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The callback function has been done successfully
+ @retval EFI_NOT_FOUND Failed to find Pch Reset Callback protocol. Or, none of
+ callback protocol is installed.
+ @retval Others Do not do any reset from PCH
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_RESET_CALLBACK) (
+ IN PCH_RESET_TYPE PchResetType
+ );
+
+///
+/// Interface structure for the Pch Reset Protocol
+///
+struct _PCH_RESET_PROTOCOL {
+ PCH_RESET Reset;
+};
+
+///
+/// PCH_RESET_CALLBACK_PROTOCOL Structure Definition
+///
+/// This protocol is used to execute PCH Reset from the host controller.
+/// The PCH Reset protocol and PCH Reset PPI implement the Intel (R) PCH Reset Interface
+/// for DXE and PEI environments, respectively. If other drivers need to run their
+/// callback function right before issuing the reset, they can install PCH Reset
+/// Callback Protocol/PPI before PCH Reset DXE/PEI driver to achieve that.
+///
+struct _PCH_RESET_CALLBACK_PROTOCOL {
+ PCH_RESET_CALLBACK ResetCallback;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.c b/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.c
new file mode 100644
index 0000000..284ad1e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.c
@@ -0,0 +1,43 @@
+/** @file
+ This file defines the PCH S3 Support Protocol.
+
+@copyright
+ Copyright (c) 2008 - 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 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// 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"
+#endif
+
+#include "PchS3Support.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiPchS3SupportProtocolGuid = EFI_PCH_S3_SUPPORT_PROTOCOL_GUID;
+EFI_GUID gEfiPchS3SupportSmmProtocolGuid = EFI_PCH_S3_SUPPORT_SMM_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gEfiPchS3SupportProtocolGuid, "PCH S3 Support Protocol", "PCH S3 Support Protocol");
+EFI_GUID_STRING(&gEfiPchS3SupportSmmProtocolGuid, "PCH S3 SMM Support Protocol", "PCH S3 SMM Support Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.h
new file mode 100644
index 0000000..5ac64a6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchS3Support/PchS3Support.h
@@ -0,0 +1,218 @@
+/** @file
+ This file defines the PCH S3 support Protocol.
+
+@copyright
+ Copyright (c) 2008 - 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 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
+**/
+#ifndef _PCH_S3_SUPPORT_PROTOCOL_H_
+#define _PCH_S3_SUPPORT_PROTOCOL_H_
+
+///
+/// Define the PCH S3 Support protocol GUID
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_PCH_S3_SUPPORT_PROTOCOL_GUID \
+ { \
+ 0x2224aee3, 0x8d0b, 0x480a, 0xb2, 0x72, 0x2a, 0xbe, 0x92, 0xcd, 0x4e, 0x78 \
+ }
+#else
+#define EFI_PCH_S3_SUPPORT_PROTOCOL_GUID \
+ { \
+ 0x2224aee3, 0x8d0b, 0x480a, \
+ { \
+ 0xb2, 0x72, 0x2a, 0xbe, 0x92, 0xcd, 0x4e, 0x78 \
+ } \
+ }
+#endif
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_PCH_S3_SUPPORT_SMM_PROTOCOL_GUID \
+ { \
+ 0xe8fe82e8, 0x7d00, 0x41ff, 0x91, 0x1e, 0xb, 0x99, 0x6f, 0x85, 0xc9, 0x57 \
+ }
+#else
+#define EFI_PCH_S3_SUPPORT_SMM_PROTOCOL_GUID \
+ { \
+ 0xe8fe82e8, 0x7d00, 0x41ff, \
+ { \
+ 0x91, 0x1e, 0xb, 0x99, 0x6f, 0x85, 0xc9, 0x57 \
+ } \
+ }
+#endif
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_PCH_S3_SUPPORT_DATA_GUID \
+ { 0xd5beb067, 0xc08e, 0x40fb, 0x8f, 0x27, 0x52, 0x0, 0xcf, 0xe4, 0x2c, 0x9 }
+#else
+#define EFI_PCH_S3_SUPPORT_DATA_GUID \
+ { 0xd5beb067, 0xc08e, 0x40fb, { 0x8f, 0x27, 0x52, 0x0, 0xcf, 0xe4, 0x2c, 0x9 } }
+#endif
+
+#include "PchPlatformPolicy/PchPlatformPolicy.h"
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiPchS3SupportProtocolGuid;
+extern EFI_GUID gEfiPchS3SupportSmmProtocolGuid;
+extern EFI_GUID gS3SupportSmramDataGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_PCH_S3_SUPPORT_PROTOCOL EFI_PCH_S3_SUPPORT_PROTOCOL;
+typedef struct _EFI_PCH_S3_SUPPORT_SMM_PROTOCOL EFI_PCH_S3_SUPPORT_SMM_PROTOCOL;
+
+typedef enum {
+ PchS3ItemTypeSendCodecCommand,
+ PchS3ItemTypeInitPcieRootPortDownstream,
+ PchS3ItemTypePcieSetPm,
+ PchS3ItemTypeProgramIobp,
+ PchS3ItemTypeMax
+} EFI_PCH_S3_DISPATCH_ITEM_TYPE;
+
+///
+/// In the following structures it is required that they are usable in both PEI (32-bit) and DXE (64-bit).
+/// As a result, Pointers and Enumerations will be of different underlying sizes. Therefore neither should
+/// appear in the middle of these structures. If done, then size adjustment will need to be explicit
+/// via other mechanisms (like a union).
+///
+typedef struct {
+ UINT32 HdaBar;
+ UINT32 CodecCmdData;
+} EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND;
+
+typedef struct {
+ UINT8 RootPortBus;
+ UINT8 RootPortDevice;
+ UINT8 RootPortFunc;
+ UINT8 TempBusNumberMin;
+ UINT8 TempBusNumberMax;
+} EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM;
+
+typedef struct {
+ UINT8 RootPortBus;
+ UINT8 RootPortDevice;
+ UINT8 RootPortFunc;
+ PCH_PCI_EXPRESS_ASPM_CONTROL RootPortAspm;
+ UINT8 NumOfDevAspmOverride;
+ UINT32 DevAspmOverrideAddr;
+ UINT8 TempBusNumberMin;
+ UINT8 TempBusNumberMax;
+ UINT8 NumOfDevLtrOverride;
+ UINT32 DevLtrOverrideAddr;
+ UINT32 PchPwrOptPcie;
+ PCH_PCIE_EXPRESS_L1SUBSTATES_CONTROL L1SubstatesConfig;
+ UINT8 PolicyRevision;
+ BOOLEAN FirstRPToSetPm;
+ BOOLEAN L1SupportedInAllEnabledPorts;
+ BOOLEAN ClkreqSupportedInAllEnabledPorts;
+} EFI_PCH_S3_PARAMETER_PCIE_SET_PM;
+
+typedef struct {
+ UINT32 RootComplexBar;
+ UINT32 Address;
+ UINT32 AndMask;
+ UINT32 OrMask;
+} EFI_PCH_S3_PARAMETER_PROG_IOBP;
+
+typedef struct {
+ union { // The union definition is in place because this structure
+ EFI_PCH_S3_DISPATCH_ITEM_TYPE Value; // is used in both DXE and PEI where enumerations are
+ UINT64 Spacer; // different sizes.
+ } ItemType;
+ VOID *Parameter;
+} EFI_PCH_S3_DISPATCH_ITEM;
+
+typedef struct {
+ EFI_GUID PchS3CustomScriptGuid;
+ UINT32 MaximumBufferSize;
+ UINT32 BufferSpaceRemaining;
+ UINT8 *NextDispatchItem;
+ //EFI_PCH_S3_DISPATCH_ITEM DispatchItemAray[] // This structure is followed in memory
+ // by an Array of EFI_PCH_S3_DISPATCH_ITEM structures
+} EFI_PCH_S3_DISPATCH_ARRAY;
+
+#define QWORD_ALIGNED_SIZE(x) ((sizeof (x) + 7) / 8 * 8) // QWORD alignment is needed for the variable lengths
+ // of the "Parameter" field of the EFI_PCH_S3_DISPATCH_ITEM
+ // structure. Alignment must be maintained between
+ // the 32-bit PEI code and 64-bit DXE code.
+
+//
+// Member functions
+//
+/**
+ Set an item to be dispatched at S3 resume time. At the same time, the entry point
+ of the PCH S3 support image is returned to be used in subsequent boot script save
+ call
+
+ @param[in] This Pointer to the protocol instance.
+ @param[in] DispatchItem The item to be dispatched.
+ @param[out] S3DispatchEntryPoint The entry point of the PCH S3 support image.
+
+ @retval EFI_STATUS Successfully completed.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM) (
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL * This,
+ IN EFI_PCH_S3_DISPATCH_ITEM * DispatchItem,
+ OUT EFI_PHYSICAL_ADDRESS * S3DispatchEntryPoint
+ );
+
+/**
+ Perform the EFI_PCH_S3_SUPPORT_SMM_PROTOCOL IO Trap to invoke DispatchArray data copy and
+ IO Trap Unregister.
+
+ @param[in] This Pointer to the protocol instance.
+
+ @retval EFI_STATUS Successfully completed.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCH_S3_SUPPORT_READY_TO_LOCK) (
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL *This
+ );
+
+///
+/// Protocol definition
+///
+/// This Protocol is used to set an item to be dispatched at S3 resume time.
+/// At the same time, the entry point of the PCH S3 support image is returned to
+/// be used in subsequent boot script save call.
+///
+struct _EFI_PCH_S3_SUPPORT_PROTOCOL {
+ EFI_PCH_S3_SUPPORT_SET_S3_DISPATCH_ITEM SetDispatchItem; ///< Set the item to be dispatched at S3 resume time.
+ EFI_PCH_S3_SUPPORT_READY_TO_LOCK ReadyToLock; ///< The caller is finished using the protocol and it can be locked.
+};
+
+
+///
+/// Protocol Definition
+///
+/// This Protocol is used to communicate the location of the Boot Services copy of the EFI_PCH_S3_DISPATCH_ARRAY.
+/// The pointer is then used to allow the SMM module to copy the data to the appropriate SMRAM location. The
+/// ProtocolSize is communicated in # of Pages.
+///
+struct _EFI_PCH_S3_SUPPORT_SMM_PROTOCOL {
+ UINT16 ProtocolSize; ///< Protocol size in Pages (due to Page alignment requirements in SMM)
+ UINT16 PchS3SupportIoTrap; ///< IO Trap port to support ExitPmAuth notification for copy and unregister
+ EFI_PCH_S3_DISPATCH_ARRAY *DispatchArray; ///< A pointer to the Boot Services copy of the Dispatch Array
+};
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.c b/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.c
new file mode 100644
index 0000000..c32e7ff
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.c
@@ -0,0 +1,42 @@
+/** @file
+ This file defines the PCH SMM IO Trap Control Protocol
+
+@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 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
+**/
+
+//
+// Include the protocol header file
+//
+//
+// 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"
+#endif
+
+#include "PchSmmIoTrapControl.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gPchSmmIoTrapControlGuid = PCH_SMM_IO_TRAP_CONTROL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gPchSmmIoTrapDispatchProtocolGuid, "PCH IO Trap Control Protocol", "EFI PCH SMM IO Trap Control Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.h b/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.h
new file mode 100644
index 0000000..2e0395e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/PchSmmIoTrapControl/PchSmmIoTrapControl.h
@@ -0,0 +1,90 @@
+/** @file
+ PCH SMM IO Trap Control Protocol
+
+@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 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
+**/
+#ifndef _PCH_SMM_IO_TRAP_CONTROL_H_
+#define _PCH_SMM_IO_TRAP_CONTROL_H_
+
+///
+/// GUID for the SMM IO Trap Control Protocol
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define PCH_SMM_IO_TRAP_CONTROL_GUID \
+ { \
+ 0x514D2AFD, 0x2096, 0x4283, 0x9D, 0xA6, 0x70, 0x0C, 0xD2, 0x7D, 0xC7, 0xA5 \
+ }
+#else
+#define PCH_SMM_IO_TRAP_CONTROL_GUID \
+ { \
+ 0x514D2AFD, 0x2096, 0x4283, \
+ { \
+ 0x9D, 0xA6, 0x70, 0x0C, 0xD2, 0x7D, 0xC7, 0xA5 \
+ } \
+ }
+#endif
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gPchSmmIoTrapControlGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL PCH_SMM_IO_TRAP_CONTROL_PROTOCOL;
+
+//
+// Related Definitions
+//
+
+//
+// Member functions
+//
+
+/**
+ The Prototype of Pause and Resume IoTrap callback function.
+
+ @param[in] This Pointer to the PCH_SMM_IO_TRAP_CONTROL_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to change state.
+
+ @retval EFI_SUCCESS This operation is complete.
+ @retval EFI_INVALID_PARAMETER The DispatchHandle is invalid.
+ @retval EFI_ACCESS_DENIED The SMI status is alrady PAUSED/RESUMED.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *PCH_SMM_IO_TRAP_CONTROL_FUNCTION) (
+ IN PCH_SMM_IO_TRAP_CONTROL_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+/**
+ Interface structure for the SMM IO trap pause and resume protocol
+ This protocol provides the functions to runtime control the IoTrap SMI enabled/disable.
+ This applys the capability to the DispatchHandle which returned by IoTrap callback
+ registration, and the DispatchHandle which must be MergeDisable = TRUE and Address != 0.
+ Besides, when S3 resuem, it only restores the state of IoTrap callback registration.
+ The Paused/Resume state won't be restored after S3 resume.
+**/
+struct _PCH_SMM_IO_TRAP_CONTROL_PROTOCOL {
+ PCH_SMM_IO_TRAP_CONTROL_FUNCTION Pause;
+ PCH_SMM_IO_TRAP_CONTROL_FUNCTION Resume;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.c b/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.c
new file mode 100644
index 0000000..09c40e1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.c
@@ -0,0 +1,34 @@
+/** @file
+ This file defines the EFI Serial GPIO Interface Protocol which implements the
+ Intel(R) Serial Data over GPIO Pin functionality Protocol Interface.
+
+@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
+**/
+
+//
+// Include the protocol header file
+//
+#include "SerialGpio.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiSerialGpioProtocolGuid = EFI_SERIAL_GPIO_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gEfiSerialGpioProtocolGuid, "Serial GPIO Protocol", "Intel(R) Serial GPIO Interface Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.h b/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.h
new file mode 100644
index 0000000..9559cb1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SerialGpio/SerialGpio.h
@@ -0,0 +1,166 @@
+/** @file
+ This file defines the EFI Serial GPIO Interface Protocol which implements the
+ Intel(R) Serial Data over GPIO Pin functionality Protocol Interface.
+
+@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
+**/
+#ifndef _EFI_SERIAL_GPIO_H_
+#define _EFI_SERIAL_GPIO_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"
+#endif
+///
+/// Define the Serial GPIO protocol GUID
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_SERIAL_GPIO_PROTOCOL_GUID \
+ { \
+ 0xf52c3858, 0x5ef8, 0x4d41, 0x83, 0x4e, 0xc3, 0x9e, 0xef, 0x8a, 0x45, 0xa3 \
+ }
+#else
+#define EFI_SERIAL_GPIO_PROTOCOL_GUID \
+ { \
+ 0xf52c3858, 0x5ef8, 0x4d41, \
+ { \
+ 0x83, 0x4e, 0xc3, 0x9e, 0xef, 0x8a, 0x45, 0xa3 \
+ } \
+ }
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSerialGpioProtocolGuid;
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_SERIAL_GPIO_PROTOCOL EFI_SERIAL_GPIO_PROTOCOL;
+
+//
+// This is the max number of GPIO pins in this ICH chipset that support Blink feature
+// 0~31 GPIO in ICH8M support blink feature
+//
+#define SERIAL_GPIO_MAX_PIN_NUMBER 32
+#define SERIAL_GPIO_MAX_DATA_RATE 63
+#define WAIT_TIME 100000
+#define WAIT_PERIOD 10
+
+///
+/// Serial GPIO protocol data structures and definitions
+///
+typedef enum {
+ EnumSerialGpioDataByte,
+ EnumSerialGpioDataWord,
+ EnumSerialGpioDataUndefined,
+ EnumSerialGpioDataDword,
+ EnumSerialGpioDataMax
+} SERIAL_GPIO_DATA_WIDTH;
+
+//
+// Protocol member functions
+//
+/**
+ Register for one GPIO Pin that will be used as serial GPIO.
+ For PCH only GPIO0~31 will have the capability to be used as serail GPIO.
+ The caller of this procedure need to be very clear of whPch GPIO should be used as serail GPIO,
+ it should not be input, native, conflict with other GPIO, or Index > 31 on the caller's platform.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER SerialGpioPinIndex is out of range
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_GPIO_REGISTER) (
+ IN EFI_SERIAL_GPIO_PROTOCOL * This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Unregister for one GPIO Pin that has been used as serial GPIO, and recover the registers before
+ registering.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER Invalid function parameters
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_GPIO_UNREGISTER) (
+ IN EFI_SERIAL_GPIO_PROTOCOL * This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Execute SERIAL_GPIO commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] GpioPinIndex Index of the GPIO pin.
+ @param[in] DataRate The data rate for serail data transfering. 1 ~ SERIAL_GPIO_MAX_DATA_RATE; 1: 128ns intervals; ...; 8: 8*128 = 1024ns intervals, default value;...
+ @param[in] DataCountInByte Number of bytes of the data will be transmitted through the GPIO pin.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada sent through the GPIO pin.
+
+ @retval EFI_SUCCESS Execute succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, GPIO serial data sent failed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SERIAL_GPIO_SEND_DATA) (
+ IN EFI_SERIAL_GPIO_PROTOCOL * This,
+ IN UINT8 GpioPinIndex,
+ IN UINT8 DataRate,
+ IN UINTN DataCountInByte,
+ IN OUT UINT8 *Buffer
+ );
+
+///
+/// Protocol definition
+///
+/// This Protocol allows a platform module to execute the IntelR Serial Data over
+/// GPIO Pin functionality Protocol Interface.
+/// The caller will first call the SerialGpioRegister() function to configure the GPIO
+/// to be used. Then the caller will execute one or more calls to the SerialGpioSendData()
+/// function to perform serial GPIO activities. Finally, the caller will use the
+/// SerialGpioUnRegister() function to un-register and allow other consumers to utilize
+/// the serial GPIO services.
+/// If the serial GPIO capabilities are in use by another caller, the registration
+/// function will return an error.
+///
+struct _EFI_SERIAL_GPIO_PROTOCOL {
+ EFI_SERIAL_GPIO_REGISTER SerialGpioRegister; ///< Register for one GPIO pin that will be used as serial GPIO.
+ EFI_SERIAL_GPIO_SEND_DATA SerialGpioSendData; ///< Execute SERIAL_GPIO commands from the host controller.
+ EFI_SERIAL_GPIO_UNREGISTER SerialGpioUnRegister; ///< Un-register the current GPIO pin used for serial GPIO, and recovers the registers before registering.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c
new file mode 100644
index 0000000..224e62f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.c
@@ -0,0 +1,46 @@
+/** @file
+ This file defines the SmmIchnDispatch Extended Protocol
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+
+//
+// Include the protocol header file
+//
+//
+// 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"
+#endif
+
+#include "SmmIchnDispatchEx.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiSmmIchnDispatchExProtocolGuid = EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING
+ (
+ &gEfiSmmIchnDispatchExProtocolGuid, "SMM ICHn SMI Dispatch Extended Protocol",
+ "EFI 2.0 SMM ICHn SMI Dispatch Extended Protocol"
+ );
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h
new file mode 100644
index 0000000..79e5ad7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIchnDispatchEx/SmmIchnDispatchEx.h
@@ -0,0 +1,177 @@
+/** @file
+ SmmIchnDispatch Extended Protocol
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+#ifndef _EFI_SMM_ICHN_DISPATCH_EX_H_
+#define _EFI_SMM_ICHN_DISPATCH_EX_H_
+
+///
+/// GUID for the SmmIchnDispatch Extended Protocol
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID \
+ { \
+ 0x3920405b, 0xc897, 0x44da, 0x88, 0xf3, 0x4c, 0x49, 0x8a, 0x6f, 0xf7, 0x36 \
+ }
+#else
+#define EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL_GUID \
+ { \
+ 0x3920405b, 0xc897, 0x44da, \
+ { \
+ 0x88, 0xf3, 0x4c, 0x49, 0x8a, 0x6f, 0xf7, 0x36 \
+ } \
+ }
+
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSmmIchnDispatchExProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL;
+
+//
+// Related Definitions
+//
+///
+/// Ichn Dispatch Extended Types
+///
+typedef enum {
+ IchnExPciExpress = NUM_ICHN_TYPES + 1,
+ IchnExMonitor,
+ IchnExSpi,
+ IchnExQRT,
+ IchnExGpioUnlock,
+ IchnExTmrOverflow,
+ IchnExPcie0Hotplug,
+ IchnExPcie1Hotplug,
+ IchnExPcie2Hotplug,
+ IchnExPcie3Hotplug,
+ IchnExPcie4Hotplug,
+ IchnExPcie5Hotplug,
+ IchnExPcie6Hotplug,
+ IchnExPcie7Hotplug,
+ IchnExPcie0LinkActive,
+ IchnExPcie1LinkActive,
+ IchnExPcie2LinkActive,
+ IchnExPcie3LinkActive,
+ IchnExPcie4LinkActive,
+ IchnExPcie5LinkActive,
+ IchnExPcie6LinkActive,
+ IchnExPcie7LinkActive,
+ //
+ // INSERT NEW ITEMS JUST BEFORE THIS LINE
+ //
+ IchnExTypeMAX ///< the maximum number of items in this enumeration
+} EFI_SMM_ICHN_EX_SMI_TYPE;
+
+typedef struct {
+ EFI_SMM_ICHN_EX_SMI_TYPE Type;
+} EFI_SMM_ICHN_DISPATCH_EX_CONTEXT;
+
+//
+// Member functions
+//
+
+/**
+ Dispatch function for a ICH n Extended specific SMI handler.
+
+ @param[in] DispatchHandle Handle of this dispatch function.
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The DispatchContext fields are filled in
+ by the dispatching driver prior to
+ invoking this dispatch function.
+
+ @retval None
+**/
+typedef
+VOID
+(EFIAPI *EFI_SMM_ICHN_DISPATCH_EX) (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT * DispatchContext
+ );
+
+/**
+ Register a child SMI source dispatch function with a parent SMM driver
+
+ @param[in] This Protocol instance pointer.
+ @param[in] DispatchFunction Pointer to dispatch function to be invoked for
+ this SMI source
+ @param[in] DispatchContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling
+ the register function to indicate to the register
+ function the ICHN SMI source for which the dispatch
+ function should be invoked.
+ @param[out] DispatchHandle Handle of dispatch function, for when interfacing
+ with the parent SMM driver.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ registered and the SMI source has been enabled.
+ @retval EFI_DEVICE_ERROR The driver was unable to enable the SMI source.
+ @retval EFI_OUT_OF_RESOURCES Not enough memory (system or SMM) to manage this
+ child.
+ @retval EFI_INVALID_PARAMETER DispatchContext is invalid. The ICHN input value
+ is not within valid range.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_EX_REGISTER) (
+ IN EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL * This,
+ IN EFI_SMM_ICHN_DISPATCH_EX DispatchFunction,
+ IN EFI_SMM_ICHN_DISPATCH_EX_CONTEXT * DispatchContext,
+ OUT EFI_HANDLE * DispatchHandle
+ );
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver
+
+ @param[in] This Protocol instance pointer.
+ @param[in] DispatchHandle Handle of dispatch function to deregister.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered and the SMI source has been disabled
+ if there are no other registered child dispatch
+ functions for this SMI source.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+ @retval Others TBD
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_ICHN_EX_UNREGISTER) (
+ IN EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL * This,
+ IN EFI_HANDLE DispatchHandle
+ );
+
+///
+/// Interface structure for the SMM Ich n specific SMI Dispatch Protocol
+///
+/// This protocol provides the ability to dispatch function for a ICHn specific SMI.
+/// This protocol acts as an extension to the EFI_SMM_ICHN_DISPATCH_PROTOCOL capabilities
+/// by defining several new SMI types: IchnExPciExpress, IchnExMonitor, IchnExSpi,
+/// IchnExQRT, IchnGpioUnlockSmi, IchnExTmrOverflow, IchnExPcieXHotplug, IchnExPcieXLinkActive.
+///
+struct _EFI_SMM_ICHN_DISPATCH_EX_PROTOCOL {
+ EFI_SMM_ICHN_EX_REGISTER Register; ///< Register a child SMI source dispatch function with a parent SMM driver.
+ EFI_SMM_ICHN_EX_UNREGISTER UnRegister; ///< Un-register a child SMI source dispatch function with a parent SMM driver.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c
new file mode 100644
index 0000000..dfd348f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.c
@@ -0,0 +1,42 @@
+/** @file
+ This file defines the PCH SMM IO Trap Dispatch Protocol
+
+@copyright
+ Copyright (c) 2005 - 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
+**/
+
+//
+// Include the protocol header file
+//
+//
+// 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"
+#endif
+
+#include "SmmIoTrapDispatch.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiSmmIoTrapDispatchProtocolGuid = EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gEfiSmmIoTrapDispatchProtocolGuid, "SMM IO Trap Protocol", "EFI PCH SMM IO Trap Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h
new file mode 100644
index 0000000..8923d3c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/SmmIoTrapDispatch/SmmIoTrapDispatch.h
@@ -0,0 +1,182 @@
+/** @file
+ PCH SMM IO Trap Dispatch Protocol
+
+@copyright
+ Copyright (c) 2005 - 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
+**/
+#ifndef _EFI_SMM_IO_TRAP_DISPATCH_H_
+#define _EFI_SMM_IO_TRAP_DISPATCH_H_
+
+///
+/// GUID for the SMM IO Trap Dispatch Protocol
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID \
+ { \
+ 0xdb7f536b, 0xede4, 0x4714, 0xa5, 0xc8, 0xe3, 0x46, 0xeb, 0xaa, 0x20, 0x1d \
+ }
+#else
+#define EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID \
+ { \
+ 0xdb7f536b, 0xede4, 0x4714, \
+ { \
+ 0xa5, 0xc8, 0xe3, 0x46, 0xeb, 0xaa, 0x20, 0x1d \
+ } \
+ }
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSmmIoTrapDispatchProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL;
+
+//
+// Related Definitions
+//
+///
+/// IO Trap valid types
+///
+typedef enum {
+ WriteTrap,
+ ReadTrap,
+ ReadWriteTrap,
+ IoTrapTypeMaximum
+} EFI_SMM_IO_TRAP_DISPATCH_TYPE;
+
+///
+/// IO Trap context structure containing information about the IO trap event that should invoke the callback
+///
+typedef struct {
+ UINT16 Address; ///< IO Trap range base address (NULL means allocate)
+ UINT16 Length; ///< IO Trap range length
+ EFI_SMM_IO_TRAP_DISPATCH_TYPE Type; ///< Access types to trap on
+ VOID *Context; ///< Callback function context
+ BOOLEAN MergeDisable; ///< Determine if IoTrap needs to be merged with other registered IoTrap
+} EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT;
+
+///
+/// IO Trap context structure containing information about the IO trap that occurred
+///
+typedef struct {
+ UINT16 Address; ///< IO address trapped
+ EFI_SMM_IO_TRAP_DISPATCH_TYPE Type; ///< IO access type
+ UINT32 WriteData; ///< Data written (contents undefined for read trap)
+ VOID *Context; ///< Callback function context
+} EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT;
+
+//
+// Member functions
+//
+
+/**
+ Dispatch function for an IO Trap specific SMI handler.
+
+ @param[in] DispatchHandle Handle of this dispatch function.
+ @param[in] CallbackContext Pointer to the dispatched function's context.
+ The CallbackContext fields are updated
+ by the dispatching driver prior to
+ invoking this callback function.
+
+ @retval None
+**/
+typedef
+VOID
+(EFIAPI *EFI_SMM_IO_TRAP_DISPATCH_CALLBACK) (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT * CallbackContext
+ );
+
+/**
+ Register an IO trap SMI child handler for a specified SMI.
+ This service will register a child for a given SMI source.
+ The caller will provide information about the IO trap characteristics via the context.
+ This includes base address, length, and type (read, write, read/write).
+ The service will allocate the IO range if the base address is 0, and the RegisterContext
+ Address field will be updated and returned to the caller.
+ The service will allocate system resources via GCD services for the requested IO trap range and type.
+ An error will be returned if insufficient resources are available to fulfill the request.
+ The service will not perform GCD allocation if the base address is non-zero. In this case,
+ the caller is responsible for the existence and allocation of the specific IO range.
+ An error may be returned if some or all of the requested resources conflict with an existing IO trap child handler.
+ It is not required that implementations will allow multiple children for a single IO trap SMI source.
+ Some implementations may support multiple children.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchFunction Pointer to the dispatch function to be invoked for this SMI source.
+ @param[in, out] RegisterContext Pointer to the dispatch function's context.
+ The caller fills this context in before calling the register function to indicate to the
+ register function the IO trap SMI source for which the dispatch function should be invoked.
+ This may not be NULL.
+ @param[out] DispatchHandle Handle of the dispatch function, for when interfacing with the parent SMM driver.
+ Type EFI_HANDLE is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+ This may not be NULL.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully registered.
+ @retval EFI_DEVICE_ERROR The driver was unable to complete due to hardware error.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources are available to fulfill
+ the IO trap range request.
+ @retval EFI_INVALID_PARAMETER RegisterContext is invalid. The input value is not within a valid range.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_IO_TRAP_DISPATCH_REGISTER) (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL * This,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK DispatchFunction,
+ IN OUT EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT * RegisterContext,
+ OUT EFI_HANDLE * DispatchHandle
+ );
+
+/**
+ Unregister a child SMI source dispatch function with a parent SMM driver
+
+ This service removes a previously installed child dispatch handler.
+ This does not guarantee that the system resources will be freed from the GCD.
+
+ @param[in] This Pointer to the EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL instance.
+ @param[in] DispatchHandle Handle of the child service to remove.
+ Type EFI_HANDLE is defined in InstallProtocolInterface() in the EFI 1.10 Specification.
+
+ @retval EFI_SUCCESS The dispatch function has been successfully
+ unregistered.
+ @retval EFI_INVALID_PARAMETER Handle is invalid.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SMM_IO_TRAP_DISPATCH_UNREGISTER) (
+ IN EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL * This,
+ IN EFI_HANDLE * DispatchHandle
+ );
+
+///
+/// Interface structure for the SMM IO trap specific SMI Dispatch Protocol
+///
+/// This protocol provides the ability to install child handlers for IO trap SMI.
+/// These handlers will be invoked to respond to specific IO trap SMI. IO trap SMI
+/// would typically be generated on reads or writes to specific processor IO space
+/// addresses or ranges. This protocol will typically abstract a limited hardware
+/// resource, so callers should handle errors gracefully.
+///
+struct _EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL {
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER Register; ///< Installs a child service to be dispatched when the requested IO trap SMI occurs.
+ EFI_SMM_IO_TRAP_DISPATCH_UNREGISTER UnRegister; ///< Removes a previously registered child service.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c b/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c
new file mode 100644
index 0000000..2df15e8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.c
@@ -0,0 +1,48 @@
+/** @file
+ This file defines the EFI SPI Protocol which implements the
+ Intel(R) SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2004 - 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 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
+**/
+
+//
+// Statements that include other files
+//
+//
+// 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"
+#endif
+//
+// Include the protocol header file
+//
+#include "Spi.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gEfiSpiProtocolGuid = EFI_SPI_PROTOCOL_GUID;
+EFI_GUID gEfiSmmSpiProtocolGuid = EFI_SMM_SPI_PROTOCOL_GUID;
+EFI_GUID gEfiSpiDataProtocolGuid = EFI_SPI_DATA_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gEfiSpiProtocolGuid, "SPI Protocol", "Intel(R) Serial Peripheral Interface Protocol");
+EFI_GUID_STRING(&gEfiSmmSpiProtocolGuid, "SMM SPI Protocol", "Intel(R) Serial Peripheral Interface Protocol");
+EFI_GUID_STRING(&gEfiSpiDataProtocolGuid, "SPI Data Protocol", "Intel(R) Serial Peripheral Data Interface Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h b/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h
new file mode 100644
index 0000000..d44332b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/Spi/Spi.h
@@ -0,0 +1,346 @@
+/** @file
+ This file defines the EFI SPI Protocol which implements the
+ Intel(R) PCH SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2006 - 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 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
+**/
+#ifndef _EFI_SPI_H_
+#define _EFI_SPI_H_
+
+///
+/// Define the SPI protocol GUID
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_SPI_PROTOCOL_GUID \
+ { \
+ 0xf8b84ae6, 0x8465, 0x4f95, 0x9f, 0xb, 0xea, 0xaa, 0x37, 0xc6, 0x15, 0x5a \
+ }
+#define EFI_SMM_SPI_PROTOCOL_GUID \
+ { \
+ 0xbd75fe35, 0xfdce, 0x49d7, 0xa9, 0xdd, 0xb2, 0x6f, 0x1f, 0xc6, 0xb4, 0x37 \
+ }
+#define EFI_SPI_DATA_PROTOCOL_GUID \
+ { \
+ 0xd617e1a8, 0x207d, 0x4544, 0xb1, 0x2d, 0x94, 0xd0, 0x96, 0x60, 0xa2, 0xd1 \
+ }
+#else
+#define EFI_SPI_PROTOCOL_GUID \
+ { \
+ 0xf8b84ae6, 0x8465, 0x4f95, \
+ { \
+ 0x9f, 0xb, 0xea, 0xaa, 0x37, 0xc6, 0x15, 0x5a \
+ } \
+ }
+#define EFI_SMM_SPI_PROTOCOL_GUID \
+ { \
+ 0xbd75fe35, 0xfdce, 0x49d7, \
+ { \
+ 0xa9, 0xdd, 0xb2, 0x6f, 0x1f, 0xc6, 0xb4, 0x37 \
+ } \
+ }
+#define EFI_SPI_DATA_PROTOCOL_GUID \
+ { \
+ 0xd617e1a8, 0x207d, 0x4544, \
+ { \
+ 0xb1, 0x2d, 0x94, 0xd0, 0x96, 0x60, 0xa2, 0xd1 \
+ } \
+ }
+#endif
+
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gEfiSpiProtocolGuid;
+extern EFI_GUID gEfiSmmSpiProtocolGuid;
+extern EFI_GUID gEfiSpiDataProtocolGuid;
+
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _EFI_SPI_PROTOCOL EFI_SPI_PROTOCOL;
+typedef struct _EFI_SPI_DATA_PROTOCOL EFI_SPI_DATA_PROTOCOL;
+
+//
+// SPI protocol data structures and definitions
+//
+///
+/// Number of Prefix Opcodes allowed on the SPI interface
+///
+#define SPI_NUM_PREFIX_OPCODE 2
+
+///
+/// Number of Opcodes in the Opcode Menu
+///
+#define SPI_NUM_OPCODE 8
+
+///
+/// Opcode Type
+/// EnumSpiOpcodeCommand: Command without address
+/// EnumSpiOpcodeRead: Read with address
+/// EnumSpiOpcodeWrite: Write with address
+///
+typedef enum {
+ EnumSpiOpcodeReadNoAddr,
+ EnumSpiOpcodeWriteNoAddr,
+ EnumSpiOpcodeRead,
+ EnumSpiOpcodeWrite,
+ EnumSpiOpcodeMax
+} SPI_OPCODE_TYPE;
+
+typedef enum {
+ EnumSpiCycle20MHz,
+ EnumSpiCycle33MHz,
+ EnumSpiCycle66MHz, ///< not supported by PCH
+ EnumSpiCycle50MHz,
+ EnumSpiCycleMax
+} SPI_CYCLE_FREQUENCY;
+
+typedef enum {
+ EnumSpiRegionAll,
+ EnumSpiRegionBios,
+ EnumSpiRegionMe,
+ EnumSpiRegionGbE,
+ EnumSpiRegionDescriptor,
+ EnumSpiRegionPlatformData,
+ EnumSpiRegionMax
+} SPI_REGION_TYPE;
+
+///
+/// Hardware Sequencing required operations (as listed in PCH EDS "Hardware
+/// Sequencing Commands and Opcode Requirements"
+///
+typedef enum {
+ EnumSpiOperationWriteStatus,
+ EnumSpiOperationProgramData_1_Byte,
+ EnumSpiOperationProgramData_64_Byte,
+ EnumSpiOperationReadData,
+ EnumSpiOperationWriteDisable,
+ EnumSpiOperationReadStatus,
+ EnumSpiOperationWriteEnable,
+ EnumSpiOperationFastRead,
+ EnumSpiOperationEnableWriteStatus,
+ EnumSpiOperationErase_256_Byte,
+ EnumSpiOperationErase_4K_Byte,
+ EnumSpiOperationErase_8K_Byte,
+ EnumSpiOperationErase_64K_Byte,
+ EnumSpiOperationFullChipErase,
+ EnumSpiOperationJedecId,
+ EnumSpiOperationDualOutputFastRead,
+ EnumSpiOperationDiscoveryParameters,
+ EnumSpiOperationOther,
+ EnumSpiOperationMax
+} SPI_OPERATION;
+
+///
+/// SPI Command Configuration
+///
+typedef struct _SPI_COMMAND_CONFIG {
+ ///
+ /// The expected frequency to be used (value to be programmed to the SSFC Register)
+ ///
+ SPI_CYCLE_FREQUENCY Frequency;
+ ///
+ /// Which Hardware Sequencing required operation this opcode respoinds to.
+ /// The required operations are listed in EDS Table 5-55: "Hardware
+ /// Sequencing Commands and Opcode Requirements"
+ /// If the opcode does not corresponds to any operation listed, use
+ /// EnumSpiOperationOther, and provides TYPE and Code for it in
+ /// SpecialOpcodeEntry.
+ ///
+ SPI_OPERATION Operation;
+} SPI_COMMAND_CONFIG;
+
+///
+/// Special Opcode entries
+///
+typedef struct _SPI_SPECIAL_OPCODE_ENTRY {
+ ///
+ /// Opcode Menu Index whose Opcode Type/Menu Configuration Register need to be
+ /// overrided or programmed per "Type" and "Code". Filled this field with 0xFF
+ /// as the end tag of SpecialOpcodeEntry.
+ ///
+ UINT8 OpcodeIndex;
+ ///
+ /// Operation Type (value to be programmed to the OPTYPE register)
+ ///
+ SPI_OPCODE_TYPE Type;
+ ///
+ /// The opcode (value to be programmed to the OPMENU register)
+ ///
+ UINT8 Code;
+} SPI_SPECIAL_OPCODE_ENTRY;
+
+///
+/// Initialization data table loaded to the SPI host controller
+///
+/// Note: Most of time, the SPI flash parts with the same vendor would have the same
+/// Prefix Opcode, Opcode menu, so you can provide one table for the SPI flash parts with
+/// the same vendor.
+///
+typedef struct _SPI_INIT_DATA {
+ ///
+ /// Prefix opcodes which are loaded into the SPI host controller
+ ///
+ UINT8 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];
+ ///
+ /// Determines Opcode Type, Menu and Frequency of the SPI commands
+ ///
+ SPI_COMMAND_CONFIG SpiCmdConfig[SPI_NUM_OPCODE];
+ ///
+ /// Special Opcode entry for the special operations.
+ ///
+ SPI_SPECIAL_OPCODE_ENTRY *SpecialOpcodeEntry;
+ ///
+ /// The offset of the start of the BIOS image relative to the flash device.
+ /// Please note this is a Flash Linear Address, NOT a memory space address.
+ /// This value is platform specific and depends on the system flash map.
+ /// This value is only used on non Descriptor mode.
+ ///
+ UINTN BiosStartOffset;
+ ///
+ /// The the BIOS Image size in flash. This value is platform specific
+ /// and depends on the system flash map. Please note BIOS Image size may
+ /// be smaller than BIOS Region size (in Descriptor Mode) or the flash size
+ /// (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be
+ /// placed at the top end of the BIOS Region (in Descriptor Mode) or the flash
+ /// (in Non Descriptor Mode)
+ ///
+ UINTN BiosSize;
+} SPI_INIT_DATA;
+
+//
+// Protocol member functions
+//
+
+/**
+ JEDEC Read IDs from SPI flash part, this function will return 1-byte Vendor ID and 2-byte Device ID
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] Address This value is to determine the command is sent to SPI Component 1 or 2
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the data received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Read Jedec Id completed.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @exception EFI_UNSUPPORTED This function is unsupported after SpiProtocolInit is called
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_READ_ID) (
+ IN EFI_SPI_PROTOCOL * This,
+ IN UINTN Address,
+ IN OUT UINT8 * Buffer
+ );
+
+/**
+ Initializes the host controller to execute SPI commands.
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] InitData Pointer to caller-allocated buffer containing the SPI
+ interface initialization table.
+
+ @retval EFI_SUCCESS Opcode initialization on the SPI host controller completed.
+ @retval EFI_ACCESS_DENIED The SPI configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_INIT) (
+ IN EFI_SPI_PROTOCOL * This,
+ IN SPI_INIT_DATA * InitData
+ );
+
+/**
+ Execute SPI commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] OpcodeIndex Index of the command in the OpCode Menu.
+ @param[in] PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+ @param[in] DataCycle TRUE if the SPI cycle contains data
+ @param[in] Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+ @param[in] ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+ @param[in] Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] DataByteCount Number of bytes in the data portion of the SPI cycle.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @exception EFI_UNSUPPORTED Command not supported.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SPI_EXECUTE) (
+ IN EFI_SPI_PROTOCOL * This,
+ IN UINT8 OpcodeIndex,
+ IN UINT8 PrefixOpcodeIndex,
+ IN BOOLEAN DataCycle,
+ IN BOOLEAN Atomic,
+ IN BOOLEAN ShiftOut,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer,
+ IN SPI_REGION_TYPE SpiRegionType
+ );
+
+///
+/// EFI SPI Protocol definition
+///
+/// These protocols/PPI allows a platform module to perform SPI operations through the
+/// Intel PCH SPI Host Controller Interface.
+///
+struct _EFI_SPI_PROTOCOL {
+ EFI_SPI_READ_ID ReadId; ///< JEDEC Read IDs from SPI flash part, this function will return 1-byte Vendor ID and 2-byte Device ID.
+ EFI_SPI_INIT Init; ///< Initialize the host controller to execute SPI commands.
+ EFI_SPI_EXECUTE Execute; ///< Execute SPI commands from the host controller.
+};
+
+///
+/// This protocol provides data about the Flash device to non-SPI modules in order to
+/// allow other entities to determine if their data is coming directly from Flash or
+/// if it is coming from other areas of memory.
+///
+struct _EFI_SPI_DATA_PROTOCOL {
+ ///
+ /// The offset of the start of the BIOS image within memory space address.
+ ///
+ UINTN BiosStartMemoryAddress;
+ ///
+ /// The the BIOS Image size in flash. This value is platform specific
+ /// and depends on the system flash map. Please note BIOS Image size may
+ /// be smaller than BIOS Region size (in Descriptor Mode) or the flash size
+ /// (in Non Descriptor Mode), and in this case, BIOS Image will be placed
+ /// at the top end of the BIOS Region (in Descriptor Mode) or the flash
+ /// (in Non Descriptor Mode)
+ ///
+ UINTN BiosSize;
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c b/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c
new file mode 100644
index 0000000..03ec452
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.c
@@ -0,0 +1,34 @@
+/** @file
+ Watchdog Timer protocol
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#include "EdkIIGlueDxe.h"
+#endif
+
+#include "Wdt.h"
+
+//
+// Protocol GUID definition
+//
+EFI_GUID gWdtProtocolGuid = WDT_PROTOCOL_GUID;
+
+//
+// Protocol description
+//
+EFI_GUID_STRING(&gWdtProtocolGuid, "WDT Protocol", "Watchdog Timer Protocol");
diff --git a/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h b/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h
new file mode 100644
index 0000000..322aa2f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Protocol/Wdt/Wdt.h
@@ -0,0 +1,157 @@
+/** @file
+ Watchdog Timer protocol
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#ifndef _DXE_WDT_H_
+#define _DXE_WDT_H_
+
+///
+/// GUID for the WDT Protocol
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define WDT_PROTOCOL_GUID \
+ { \
+ 0xB42B8D12, 0x2ACB, 0x499a, 0xA9, 0x20, 0xDD, 0x5B, 0xE6, 0xCF, 0x09, 0xB1 \
+ }
+
+#else
+
+#define WDT_PROTOCOL_GUID \
+ { \
+ 0xB42B8D12, 0x2ACB, 0x499a, \
+ { \
+ 0xA9, 0x20, 0xDD, 0x5B, 0xE6, 0xCF, 0x09, 0xB1 \
+ } \
+ }
+
+#endif
+//
+// Extern the GUID for protocol users.
+//
+extern EFI_GUID gWdtProtocolGuid;
+//
+// Forward reference for ANSI C compatibility
+//
+typedef struct _WDT_PROTOCOL WDT_PROTOCOL;
+
+/**
+ Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+ causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+ function was called too.
+
+ @param[in] TimeoutValue Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+ @retval EFI_SUCCESS if everything's OK
+ @retval EFI_INVALID_PARAMETER if TimeoutValue parameter is wrong
+**/
+typedef
+EFI_STATUS
+(EFIAPI *WDT_RELOAD_AND_START) (
+ UINT32 TimeoutValue
+ );
+
+/**
+ Returns WDT failure status.
+
+ @param[in] None
+
+ @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE If there was WDT expiration or unexpected reset
+ @retval V_PCH_OC_WDT_CTL_STATUS_OK Otherwise
+**/
+typedef
+UINT8
+(EFIAPI *WDT_CHECK_STATUS) (
+ VOID
+ );
+
+/**
+ Returns information if WDT coverage for the duration of BIOS execution
+ was requested by an OS application.
+
+ @param[in] None
+
+ @retval TRUE if WDT was requested
+ @retval FALSE if WDT was not requested
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_REQUIRED) (
+ VOID
+ );
+
+/**
+ Returns WDT enabled/disabled status.
+
+ @param[in] None
+
+ @retval TRUE if WDT is enabled
+ @retval FALSE if WDT is disabled
+**/
+typedef
+UINT8
+(EFIAPI *IS_WDT_ENABLED) (
+ VOID
+ );
+
+/**
+ Disables WDT timer.
+
+ @param[in] None
+
+ @retval None
+**/
+typedef
+VOID
+(EFIAPI *WDT_DISABLE) (
+ VOID
+ );
+
+/**
+ Normally, each reboot performed while watchdog runs is considered a failure.
+ This function allows platform to perform expected reboots with WDT running,
+ without being interpreted as failures.
+ In DXE phase, it is enough to call this function any time before reset.
+ In PEI phase, between calling this function and performing reset, ReloadAndStart()
+ must not be called.
+
+ @param[in] None
+
+ @retval None
+**/
+typedef
+VOID
+(EFIAPI *WDT_ALLOW_KNOWN_RESET) (
+ VOID
+ );
+
+///
+/// These protocols and PPI allow a platform module to perform watch dog timer operations
+/// through the Intel PCH LPC Host Controller Interface. The WDT protocol and WDT PPI
+/// implement the Intel (R) Watch Dog timer for DXE, and PEI environments, respectively.
+/// WDT_PROTOCOL referenced hereafter represents both WDT_PROTOCOL and WDT_PPI, as they
+/// share the identical data structure.
+///
+struct _WDT_PROTOCOL {
+ WDT_RELOAD_AND_START ReloadAndStart; ///< Reloads WDT with new timeout value and starts it.
+ WDT_CHECK_STATUS CheckStatus; ///< Returns WDT failure status.
+ WDT_DISABLE Disable; ///< Disables WDT timer.
+ WDT_ALLOW_KNOWN_RESET AllowKnownReset; ///< Perform expected reboots with WDT running, without being interpreted as failures.
+ IS_WDT_REQUIRED IsWdtRequired; ///< Returns information if WDT coverage for the duration of BIOS execution was requested by an OS application.
+ IS_WDT_ENABLED IsWdtEnabled; ///< Returns WDT enabled/disabled status.
+};
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.c b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.c
new file mode 100644
index 0000000..4516b1f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.c
@@ -0,0 +1,254 @@
+/** @file
+ PCH RESET Common Library implements the Pch Reset Interface.
+
+@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 "PchReset.h"
+
+/**
+ Initialize an Pch Reset protocol instance.
+ The function will assert in debug if PCH RCBA has not been initialized
+
+ @param[in] PchResetInstance Pointer to PchResetInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+PchResetProtocolConstructor (
+ PCH_RESET_INSTANCE *PchResetInstance
+ )
+{
+ ///
+ /// Check if the current PCH is known and supported by this code
+ ///
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "PCH Reset Protocol not supported due to no proper PCH LPC found!\n"));
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Initialize the Reset protocol instance
+ ///
+ PchResetInstance->Signature = PCH_RESET_SIGNATURE;
+ PchResetInstance->Handle = NULL;
+ PchResetInstance->PchResetProtocol.Reset = PchReset;
+
+ ///
+ /// Sanity check to ensure PCH RCBA initialization has occurred previously.
+ ///
+ PchResetInstance->PchRootComplexBar = PCH_RCRB_BASE;
+ ASSERT (PchResetInstance->PchRootComplexBar != 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Execute Pch Reset from the host controller.
+
+ @param[in] This Pointer to the PCH_RESET_PROTOCOL instance.
+ @param[in] PchResetType Pch Reset Types which includes ColdReset, WarmReset, ShutdownReset,
+ PowerCycleReset, GlobalReset, GlobalResetWithEc
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_INVALID_PARAMETER If ResetType is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchReset (
+ IN PCH_RESET_PROTOCOL *This,
+ IN PCH_RESET_TYPE PchResetType
+ )
+{
+ PCH_RESET_INSTANCE *PchResetInstance;
+ UINTN PchRootComplexBar;
+ UINT16 PmBase;
+ UINT16 GpioBase;
+ UINT8 OutputData;
+ UINT32 Data32;
+ UINT16 Data16;
+ EFI_STATUS Status;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ PchResetInstance = PCH_RESET_INSTANCE_FROM_THIS (This);
+ PchRootComplexBar = PchResetInstance->PchRootComplexBar;
+ PmBase = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ GpioBase = PciRead16 (
+ PCI_LIB_ADDRESS (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;
+
+ switch (PchResetType) {
+ case WarmReset:
+ IoWrite8 ((UINTN) R_PCH_RST_CNT, (UINT8) V_PCH_RST_CNT_SOFTSTARTSTATE);
+ OutputData = V_PCH_RST_CNT_SOFTRESET;
+ break;
+
+ case ColdReset:
+ IoWrite8 ((UINTN) R_PCH_RST_CNT, (UINT8) V_PCH_RST_CNT_HARDSTARTSTATE);
+
+// AMI_OVERRIDE, [EIP81593] >>>
+#ifdef COLD_RESET_WITH_POWER_CYCLE
+ OutputData = V_PCH_RST_CNT_FULLRESET;
+#else
+ OutputData = V_PCH_RST_CNT_HARDRESET;
+#endif
+// AMI_OVERRIDE, [EIP81593] <<<
+ break;
+
+ case ShutdownReset:
+ ///
+ /// Firstly, ACPI decode must be enabled
+ ///
+ PciOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_CNT),
+ (UINT8) (B_PCH_LPC_ACPI_CNT_ACPI_EN)
+ );
+
+ ///
+ /// Then, GPE0_EN should be disabled to avoid any GPI waking up the system from S5
+ ///
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (PmBase + R_PCH_ACPI_GPE0_EN_127_96), 0);
+ } else if (PchSeries == PchH) {
+ IoWrite16 ((UINTN) (PmBase + R_PCH_ACPI_GPE0a_EN), 0);
+ IoWrite16 ((UINTN) (PmBase + R_PCH_ACPI_GPE0b_EN), 0);
+ }
+
+ ///
+ /// Secondly, PwrSts register must be cleared
+ ///
+ /// Write a "1" to bit[8] of power button status register at
+ /// (PM_BASE + PM1_STS_OFFSET) to clear this bit
+ ///
+ Data16 = B_PCH_SMI_STS_PM1_STS_REG;
+// AMI_OVERWRITE >>> EIP136638
+ IoWrite16 ((UINTN) (PmBase + R_PCH_ACPI_PM1_STS), Data16);
+// AMI_OVERWRITE <<<
+
+ ///
+ /// Finally, transform system into S5 sleep state
+ ///
+ Data32 = IoRead32 ((UINTN) (PmBase + R_PCH_ACPI_PM1_CNT));
+
+ Data32 = (UINT32) ((Data32 &~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S5);
+
+ IoWrite32 ((UINTN) (PmBase + R_PCH_ACPI_PM1_CNT), Data32);
+
+ Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN;
+
+ IoWrite32 ((UINTN) (PmBase + R_PCH_ACPI_PM1_CNT), Data32);
+
+ return EFI_SUCCESS;
+
+ case PowerCycleReset:
+ case GlobalReset:
+ case GlobalResetWithEc:
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 4.6 GPIO Reset Requirement
+ /// System BIOS is recommended to clear "GPIO Reset Select" registers [GP_RST_SEL1 (GPIOBASE + offset 60h),
+ /// GP_RST_SEL2 (GPIOBASE + offset 64h) and GP_RST_SEL3 (GPIOBASE + offset 68h)] before issuing a hard or
+ /// global reset unless specially requested by the platform designer.
+ ///
+ IoWrite32 ((UINTN) (GpioBase + R_PCH_GP_RST_SEL), 0);
+ IoWrite32 ((UINTN) (GpioBase + R_PCH_GP_RST_SEL2), 0);
+ IoWrite32 ((UINTN) (GpioBase + R_PCH_GP_RST_SEL3), 0);
+
+ if ((PchResetType == GlobalReset) || (PchResetType == GlobalResetWithEc)) {
+ PciOr32 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_PMIR),
+ (UINT32) (B_PCH_LPC_PMIR_CF9GR)
+ );
+ }
+
+ if ((PchResetType == GlobalResetWithEc) &&
+ ((MmioRead32 (PchRootComplexBar + R_PCH_RCRB_DEEP_S4_POL) &
+ (B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_AC | B_PCH_RCRB_DEEP_S4_POL_DPS4_EN_DC)) == 0) &&
+ ((MmioRead32 (PchRootComplexBar + R_PCH_RCRB_DEEP_S5_POL) &
+ (B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_AC | B_PCH_RCRB_DEEP_S5_POL_DPS5_EN_DC)) == 0)) {
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 4.5 Global Reset
+ /// For systems with an embedded controller, System BIOS should also take these additional steps when it performs the Global Reset:
+ /// CF9h Global Reset:
+ ///
+ if (PchSeries == PchH) {
+ /// 1. Set GPIOBASE + offset 00h[30] = 1b (for non-Deep Sx enabled platforms)
+ /// 2. Set GPIOBASE + offset 04h[30] = 0b (for non-Deep Sx enabled platforms)
+ /// 3. Set GPIOBASE + offset 0Ch[30] = 0b (for non-Deep Sx enabled platforms)
+ /// 4. Set GPIOBASE + offset 60h[30] = 1b (for non-Deep Sx enabled platforms)
+ /// NOTE: For Deep Sx enabled platforms steps 1,2 and 3 should be skipped and pin should be left in native mode
+ /// 5. Set CF9GR bit, D31:F0:ACh[20], issue a Global Reset through a 0xCF9 write of either 06h or 0Eh commands.
+ /// Global Reset MEI Message
+ /// 1. BIOS makes sure GPIO30 is left in native mode (default mode) before sending a Global Reset MEI message.
+ ///
+ IoOr32 ((UINTN) (GpioBase + R_PCH_GPIO_USE_SEL), (UINT32) (BIT30));
+ IoAnd32 ((UINTN) (GpioBase + R_PCH_GPIO_IO_SEL), (UINT32) (~BIT30));
+ IoAnd32 ((UINTN) (GpioBase + R_PCH_GPIO_LVL), (UINT32) (~BIT30));
+ }
+
+ if (PchSeries == PchLp) {
+ /// 1. Set GPIOBASE + offset 1F0h[0] = 1b (for non-Deep Sx enabled platforms)
+ /// 2. Set GPIOBASE + offset 1F0h[2] = 0b (for non-Deep Sx enabled platforms)
+ /// 3. Set GPIOBASE + offset 1F0h[31] = 0b (for non-Deep Sx enabled platforms)
+ /// 4. Set GPIOBASE + offset 60h[30] = 1h (for non-Deep Sx enabled platforms)
+ /// NOTE: For Deep Sx enabled platforms steps 1,2 and 3 should be skipped and pin should be left in native mode
+ /// 5. Set CF9GR bit, D31:F0:ACh[20], issue a Global Reset through a 0xCF9 write of either 06h or 0Eh commands.
+ /// Global Reset MEI Message
+ /// 1. BIOS makes sure GPIO30 is left in native mode (default mode) before sending a Global Reset MEI message.
+ ///
+ IoOr32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (B_PCH_GPIO_OWN0_GPIO_USE_SEL));
+ IoAnd32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (~B_PCH_GPIO_OWN0_GPIO_IO_SEL));
+ IoAnd32 ((UINTN) (GpioBase + R_PCH_GP_30_CONFIG0), (UINT32) (~B_PCH_GPIO_OWN0_GPO_LVL));
+ }
+ IoOr32 ((UINTN) (GpioBase + R_PCH_GP_RST_SEL), (UINT32) (BIT30));
+ }
+
+ OutputData = V_PCH_RST_CNT_FULLRESET;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PchResetCallback (PchResetType);
+
+ if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {
+ IoWrite8 ((UINTN) R_PCH_RST_CNT, OutputData);
+ ///
+ /// Waiting for system reset
+ ///
+ EFI_DEADLOOP ();
+ }
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.h b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.h
new file mode 100644
index 0000000..a9020a7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommon.h
@@ -0,0 +1,86 @@
+/** @file
+ Header file for PCH RESET Common Library.
+
+@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 _RESET_COMMON_H_
+#define _RESET_COMMON_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 "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_RESET_SIGNATURE EFI_SIGNATURE_32 ('I', 'E', 'R', 'S')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE Handle;
+ PCH_RESET_PROTOCOL PchResetProtocol;
+ UINTN PchRootComplexBar;
+} PCH_RESET_INSTANCE;
+
+#define PCH_RESET_INSTANCE_FROM_THIS(a) \
+ CR ( \
+ a, \
+ PCH_RESET_INSTANCE, \
+ PchResetProtocol, \
+ PCH_RESET_SIGNATURE \
+ )
+
+//
+// Function prototypes used by the Pch Reset protocol.
+//
+
+/**
+ Initialize an Pch Reset protocol instance.
+ The function will assert in debug if PCH RCBA has not been initialized
+
+ @param[in] PchResetInstance Pointer to PchResetInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+PchResetProtocolConstructor (
+ PCH_RESET_INSTANCE *PchResetInstance
+ );
+
+/**
+ Execute Pch Reset from the host controller.
+
+ @param[in] This Pointer to the PCH_RESET_PROTOCOL instance.
+ @param[in] PchResetType Pch Reset Types which includes ColdReset, WarmReset, ShutdownReset,
+ PowerCycleReset, GlobalReset, GlobalResetWithEc
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_INVALID_PARAMETER If ResetType is invalid.
+**/
+EFI_STATUS
+EFIAPI
+PchReset (
+ IN PCH_RESET_PROTOCOL *This,
+ IN PCH_RESET_TYPE PchResetType
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.cif
new file mode 100644
index 0000000..8fad0d9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PchResetCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Reset\Common"
+ RefName = "PchResetCommonLib"
+[files]
+"PchResetCommonLib.sdl"
+"PchResetCommonLib.mak"
+"PchResetCommon.h"
+"PchResetCommon.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.mak
new file mode 100644
index 0000000..eecda96
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.mak
@@ -0,0 +1,124 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchResetCommonLib/PchResetCommonLib.mak 1 2/08/12 9:06a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:06a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchResetCommonLib/PchResetCommonLib.mak $
+#
+# 1 2/08/12 9:06a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchResetCommonLib
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+PchResetCommonLib : PchResetCommonPeiLib
+!ENDIF
+
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+PchResetCommonLib : PchResetCommonDxeLib
+!ENDIF
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+PchResetCommonLib : PchResetCommonDxeLib PchResetCommonPeiLib
+!ENDIF
+!ENDIF
+
+!IF "$(PchInitDxe_SUPPORT)" == "1"
+$(PchResetCommonDxeLib_LIB) : PchResetCommonDxeLib
+!ENDIF
+
+!IF "$(PchInitPeim_SUPPORT)" == "1"
+$(PchResetCommonPeiLib_LIB) : PchResetCommonPeiLib
+!ENDIF
+
+PchResetCommonDxeLib : $(BUILD_DIR)\PchResetCommonLib.mak PchResetCommonLibDxeBin
+
+PchResetCommonPeiLib : $(BUILD_DIR)\PchResetCommonLib.mak PchResetCommonLibPeiBin
+
+$(BUILD_DIR)\PchResetCommonLib.mak : $(PchResetCommonLib_DIR)\$(@B).cif $(PchResetCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchResetCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchResetCommonLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchResetCommonLibDxe_INCLUDES=\
+ $(PchResetCommonLib_INCLUDES) $(PCH_INITDXE_INCLUDES)
+
+PchResetCommonLibPeim_INCLUDES=\
+ $(PchResetCommonLib_INCLUDES) $(PCH_INITPEI_INCLUDES)
+
+PchResetCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+PchResetCommonLibPeim_DEFINES = \
+ $(PchResetCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+PchResetCommonLibDxe_DEFINES = \
+ $(PchResetCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+PchResetCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchResetCommonLib.mak all\
+ "MY_INCLUDES=$(PchResetCommonLibDxe_INCLUDES)" \
+ "CFLAGS=$(PchResetCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(PchResetCommonDxeLib_LIB)
+
+PchResetCommonLibPeiBin : $(EFISCRIPTLIB) $(EDKFRAMEWORKPROTOCOLLIB)
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\PchResetCommonLib.mak all\
+ "MY_INCLUDES=$(PchResetCommonLibPeim_INCLUDES)" \
+ "CFLAGS=$(PchResetCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(PchResetCommonPeiLib_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/Reset/Common/PchResetCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.sdl
new file mode 100644
index 0000000..745b6bd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Common/PchResetCommonLib.sdl
@@ -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/PchResetCommonLib/PchResetCommonLib.sdl 2 1/11/13 12:47a Scottyang $
+#
+# $Revision: 2 $
+#
+# $Date: 1/11/13 12:47a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchResetCommonLib/PchResetCommonLib.sdl $
+#
+# 2 1/11/13 12:47a Scottyang
+# [TAG] EIP81593
+# [Category] Improvement
+# [Description] Added new SDL token "COLD_RESET_WITH_POWER_CYCLE".
+# [Files] SB.sdl, SBGeneric.c, PchResetCommon.c,
+# PchResetCommonLib.sdl
+#
+# 1 2/08/12 9:06a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchResetCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchUsbCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchResetCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchResetCommonLib.mak to Project"
+ File = "PchResetCommonLib.mak"
+End
+
+ELINK
+ Name = "PchResetCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$$(LIB_BUILD_DIR)\PchResetCommonDxeLib.lib"
+ Parent = "PchResetCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchResetCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$$(LIB_BUILD_DIR)\PchResetCommonPeiLib.lib"
+ Parent = "PchResetCommonPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ # [EIP81593]>
+ELINK
+ Name = "/D COLD_RESET_WITH_POWER_CYCLE"
+ Parent = "GLOBAL_DEFINES"
+ InvokeOrder = AfterParent
+ Token = "COLD_RESET_WITH_POWER_CYCLE" "=" "1"
+End
+ # <[EIP81593]
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Reset/Pei/PchReset.c b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.c
new file mode 100644
index 0000000..5993d67
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.c
@@ -0,0 +1,134 @@
+/** @file
+ PCH RESET PEIM 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
+**/
+#include "PchReset.h"
+
+/**
+ Installs PCH RESET PPI
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS PCH SPI PPI is installed successfully
+ @retval EFI_OUT_OF_RESOURCES Can't allocate pool
+**/
+EFI_STATUS
+InstallPchReset (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ PEI_PCH_RESET_INSTANCE *PeiPchResetInstance;
+ PCH_RESET_INSTANCE *PchResetInstance;
+
+ DEBUG ((EFI_D_INFO, "InstallPchReset() Start\n"));
+
+ PeiPchResetInstance = (PEI_PCH_RESET_INSTANCE *) AllocateZeroPool (sizeof (PEI_PCH_RESET_INSTANCE));
+ if (NULL == PeiPchResetInstance) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PchResetInstance = &(PeiPchResetInstance->PchResetInstance);
+ PchResetProtocolConstructor (PchResetInstance);
+
+ PeiPchResetInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PeiPchResetInstance->PpiDescriptor.Guid = &gPchResetPpiGuid;
+ PeiPchResetInstance->PpiDescriptor.Ppi = &(PchResetInstance->PchResetProtocol);
+
+ ///
+ /// Install the PCH RESET PPI
+ ///
+ Status = (**PeiServices).InstallPpi (PeiServices, &PeiPchResetInstance->PpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "PCH RESET PPI Installed\n"));
+
+ DEBUG ((EFI_D_INFO, "InstallPchReset() End\n"));
+
+ return Status;
+}
+
+/**
+ Execute call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The callback function has been done successfully
+ @exception EFI_UNSUPPORTED Do not do any reset from PCH
+**/
+EFI_STATUS
+PchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ )
+{
+ EFI_STATUS Status;
+ UINTN Instance;
+ PCH_RESET_CALLBACK_PPI *PchResetCallbackPpi;
+
+ if ((PchResetType == GlobalReset) || (PchResetType == GlobalResetWithEc)) {
+ ///
+ /// After MRC is done, DRAM Init Done message will be sent to ME FW.
+ ///
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiMemoryDiscoveredPpiGuid,
+ 0,
+ NULL,
+ NULL
+ );
+
+ if (Status == EFI_SUCCESS) {
+ ///
+ /// After sending DRAM Init Done to ME FW, please do the global reset through HECI.
+ ///
+ DEBUG ((EFI_D_ERROR, "Please do the global reset through HECI \n"));
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ Instance = 0;
+
+ do {
+ ///
+ /// Those drivers that need to install Pch Reset Callback Ppi have the responsibility
+ /// to make sure themselves execute before Pch Reset PEI driver.
+ ///
+ Status = PeiServicesLocatePpi (
+ &gPchResetCallbackPpiGuid,
+ Instance,
+ NULL,
+ (VOID**) &PchResetCallbackPpi
+ );
+
+ if (Status == EFI_SUCCESS) {
+ PchResetCallbackPpi->ResetCallback (PchResetType);
+ } else {
+ if ((Instance == 0) && (Status == EFI_NOT_FOUND)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "None of Pch Reset Callback Ppi is found .\n"));
+ } else {
+ DEBUG ((EFI_D_INFO, "Failed to locate Pch Reset Callback Ppi.\n"));
+ }
+ }
+
+ Instance++;
+ } while (Status != EFI_NOT_FOUND);
+
+ return EFI_SUCCESS;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.dxs b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.dxs
new file mode 100644
index 0000000..5e18cb4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.dxs
@@ -0,0 +1,39 @@
+/** @file
+ Dependency expression source file.
+
+@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 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/Reset/Pei/PchReset.h b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.h
new file mode 100644
index 0000000..fa6ddc0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchReset.h
@@ -0,0 +1,65 @@
+/** @file
+ Header file for PCH RESET PEIM 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_RESET_H
+#define _PCH_RESET_H
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include EFI_PPI_PRODUCER (PchReset)
+#include "PchResetCommon.h"
+#include EFI_PPI_CONSUMER (MemoryDiscovered)
+#include "PchAccess.h"
+#endif
+
+typedef struct {
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ PCH_RESET_INSTANCE PchResetInstance;
+} PEI_PCH_RESET_INSTANCE;
+
+/**
+ Installs PCH RESET PPI
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS PCH SPI PPI is installed successfully
+ @retval EFI_OUT_OF_RESOURCES Can't allocate pool
+**/
+EFI_STATUS
+InstallPchReset (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ Execute call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The callback function has been done successfully
+ @exception EFI_UNSUPPORTED Do not do any reset from PCH
+**/
+EFI_STATUS
+EFIAPI
+PchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif
new file mode 100644
index 0000000..294cf3c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchResetPeim"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Reset\Pei"
+ RefName = "PchResetPeim"
+[files]
+"PchResetPeim.sdl"
+"PchResetPeim.mak"
+"PchReset.h"
+"PchReset.c"
+"PchReset.dxs"
+"PchResetPeim.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf
new file mode 100644
index 0000000..cd135c0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.inf
@@ -0,0 +1,84 @@
+## @file
+# Component description file for the Pch Reset PEIM.
+#
+#@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 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 = PchResetPeim
+FILE_GUID = 147B4839-5DBE-413f-917F-DFEB687C6312
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchReset.h
+ PchReset.c
+ ../Common/PchResetCommon.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
+#
+# 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
+
+[libraries.common]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkPpiLib
+ PchPlatformLib
+ EdkFrameworkPpiLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchReset.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchReset
+ 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/Reset/Pei/PchResetPeim.mak b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.mak
new file mode 100644
index 0000000..541ee4f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.mak
@@ -0,0 +1,99 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchResetPeim/PchResetPeim.mak 2 2/24/12 2:17a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:17a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchResetPeim/PchResetPeim.mak $
+#
+# 2 2/24/12 2:17a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:05a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchResetPeim module
+#---------------------------------------------------------------------------
+EDK : PchResetPeim
+PchResetPeim : $(BUILD_DIR)\PchResetPeim.mak PchResetPeimBin
+
+
+$(BUILD_DIR)\PchResetPeim.mak : $(PchResetPeim_DIR)\$(@B).cif $(PchResetPeim_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchResetPeim_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchResetPeim_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchResetPeim_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchReset"\
+ /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__
+
+PchResetPeim_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) \
+ $(PchResetCommonPeiLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchResetPeimBin: $(PchResetPeim_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchResetPeim.mak all \
+ "MY_INCLUDES=$(PchResetPeim_INCLUDES)"\
+ "MY_DEFINES=$(PchResetPeim_DEFINES)"\
+ NAME=PchResetPeim\
+ MAKEFILE=$(BUILD_DIR)\PchResetPeim.mak \
+ GUID=FF259F16-18D1-4298-8DD2-BD87FF2894A9\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchResetPeim_DIR)\PchReset.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/Reset/Pei/PchResetPeim.sdl b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.sdl
new file mode 100644
index 0000000..b213204
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/Pei/PchResetPeim.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/PchResetPeim/PchResetPeim.sdl 1 2/08/12 9:05a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:05a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchResetPeim/PchResetPeim.sdl $
+#
+# 1 2/08/12 9:05a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchResetPeim_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchInitPeim support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchResetPeim_DIR"
+End
+
+MODULE
+ File = "PchResetPeim.mak"
+ Help = "Includes PchResetPeim.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchResetPeim.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/Reset/RuntimeDxe/PchReset.c b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.c
new file mode 100644
index 0000000..8f4b925
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.c
@@ -0,0 +1,496 @@
+/** @file
+ PCH RESET Runtime 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 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 "PchReset.h"
+
+PCH_RESET_INSTANCE *mPchResetInstance;
+
+STATIC UINT8 mDaysOfMonthInfo[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+/**
+ Check if it is leap year
+
+ @param[in] Year year to be check
+
+ @retval True year is leap year
+ @retval FALSE year is not a leap year
+**/
+BOOLEAN
+IsLeapYear (
+ IN UINT16 Year
+ )
+{
+ return (Year % 4 == 0) && ((Year % 100 != 0) || (Year % 400 == 0));
+}
+
+/**
+ Set System Wakeup Alarm.
+
+ @param[in] WakeAfter Time offset in seconds to wake from S3
+
+ @retval EFI_SUCCESS Timer started successfully
+**/
+
+STATIC
+EFI_STATUS
+SetSystemWakeupAlarm (
+ IN UINT32 WakeAfter
+ )
+{
+ EFI_STATUS Status;
+ EFI_TIME Time;
+ EFI_TIME_CAPABILITIES Capabilities;
+ UINT32 Reminder;
+ UINT16 PmBase;
+ UINT8 DayOfMonth;
+ ///
+ /// For an instant wake 2 seconds is a safe value
+ ///
+ if (WakeAfter < 2) {
+ WakeAfter = 2;
+ }
+
+ Status = EfiGetTime (&Time, &Capabilities);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Reminder = WakeAfter + (UINT32) Time.Second;
+ Time.Second = Reminder % 60;
+ Reminder = Reminder / 60;
+ Reminder = Reminder + (UINT32) Time.Minute;
+ Time.Minute = Reminder % 60;
+ Reminder = Reminder / 60;
+ Reminder = Reminder + (UINT32) Time.Hour;
+ Time.Hour = Reminder % 24;
+ Reminder = Reminder / 24;
+
+ if (Reminder > 0) {
+ Reminder = Reminder + (UINT32) Time.Day;
+ if ((Time.Month == 2) && IsLeapYear (Time.Year)) {
+ DayOfMonth = 29;
+ } else {
+ DayOfMonth = mDaysOfMonthInfo[Time.Month - 1];
+ }
+ if (Reminder > DayOfMonth) {
+ Time.Day = (UINT8)Reminder - DayOfMonth;
+ Reminder = 1;
+ } else {
+ Time.Day = (UINT8)Reminder;
+ Reminder = 0;
+ }
+ }
+
+ if (Reminder > 0) {
+ if (Time.Month == 12) {
+ Time.Month = 1;
+ Time.Year = Time.Year + 1;
+ } else {
+ Time.Month = Time.Month + 1;
+ }
+ }
+
+ Status = EfiSetWakeupTime (TRUE, &Time);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PmBase = (UINT16) (PciRead32 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR);
+
+ ///
+ /// Clear RTC PM1 status
+ ///
+ IoWrite16 (PmBase + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC);
+
+ ///
+ /// set RTC_EN bit in PM1_EN to wake up from the alarm
+ ///
+ IoWrite16 (
+ PmBase + R_PCH_ACPI_PM1_EN,
+ (IoRead16 (PmBase + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC)
+ );
+ return Status;
+}
+
+// AMI_OVERRIDE, [EIP111666] >>>
+EFI_GUID gPchGetResetTypeGuid = PCH_RESET_PROTOCOL_GUID;
+
+EFI_STATUS
+EFIAPI
+PchResetExitBootServicesEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ PCH initialization before ExitBootServices / LegacyBoot events
+ Useful for operations which must happen later than at EndOfPost event
+
+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
+
+ --*/
+{
+ //
+ // Closed the event to avoid call twice
+ //
+ UINT8 LegacyBoot;
+ gBS->CloseEvent (Event);
+
+ gRT->SetVariable (
+ L"InLegacyBoot",
+ &gPchGetResetTypeGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT8),
+ &LegacyBoot
+ );
+ return EFI_SUCCESS;
+}
+// AMI_OVERRIDE, [EIP111666] <<<
+
+/**
+ Initialize the state information for the Timer Architectural Protocol
+
+ @param[in] ImageHandle Image handle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Cannot create the timer service
+**/
+EFI_STATUS
+EFIAPI
+InstallPchReset (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT64 Length;
+// AMI_OVERRIDE, NBDXE.c already done. >>>
+/* UINT64 BaseAddress;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR MemorySpaceDescriptor;
+ UINT64 Attributes;*/
+// AMI_OVERRIDE, NBDXE.c already done. <<<
+// AMI_OVERRIDE, [EIP111666] >>>
+ EFI_EVENT LegacyBootEvent;
+// AMI_OVERRIDE, [EIP111666] <<<
+
+ DEBUG ((EFI_D_INFO, "InstallPchReset() Start\n"));
+
+ Status = PciLibConstructor ();
+ ASSERT_EFI_ERROR (Status);
+// AMI_OVERRIDE, NBDXE.c already done. >>>
+/*
+ BaseAddress = MmPciAddress(0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ Length = 4096;
+
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &MemorySpaceDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes = MemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
+
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ Attributes
+ );
+ DEBUG ((EFI_D_INFO, "Status = %r\n",Status));
+ ASSERT_EFI_ERROR (Status);*/
+// AMI_OVERRIDE, NBDXE.c already done. <<<
+
+ Length = 4096;
+ // AMI_OVERRIDE_FOR_FIRST_BOOT
+ Status = PciLibRegisterMemory (
+ PCI_LIB_ADDRESS (0,
+ 0,
+ 0,
+ 0),
+ (UINTN) Length
+ );
+ // AMI_OVERRIDE_FOR_FIRST_BOOT
+
+ Status = PciLibRegisterMemory (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0),
+ (UINTN) Length
+ );
+ ASSERT_EFI_ERROR (Status);
+ ///
+ /// Allocate Runtime memory for the PchReset protocol instance.
+ ///
+ mPchResetInstance = AllocateRuntimeZeroPool (sizeof (PCH_RESET_INSTANCE));
+ if (mPchResetInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PchResetProtocolConstructor (mPchResetInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Install protocol interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mPchResetInstance->Handle,
+ &gPchResetProtocolGuid,
+ &mPchResetInstance->PchResetProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+// AMI_OVERRIDE, [EIP111666] >>>
+ Status = EfiCreateEventLegacyBootEx (
+ EFI_TPL_CALLBACK,
+ PchResetExitBootServicesEvent,
+ NULL,
+ &LegacyBootEvent
+ );
+// AMI_OVERRIDE, [EIP111666] <<<
+
+ ///
+ /// The Lib Deconstruct will automatically be called when entrypoint return error.
+ ///
+ DEBUG ((EFI_D_INFO, "InstallPchReset() End\n"));
+
+ return Status;
+}
+
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+/**
+ If need be, do any special reset required for capsules. For this
+ implementation where we're called from the ResetSystem() api,
+ just set our capsule variable and return to let the caller
+ do a soft reset.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+CapsuleReset (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN CapsuleDataPtr;
+ UINT32 Data32;
+ UINT32 Eflags;
+ UINT16 PmBase;
+
+ ///
+ /// Check if there are pending capsules to process
+ ///
+ Size = sizeof (CapsuleDataPtr);
+ Status = EfiGetVariable (
+ EFI_CAPSULE_VARIABLE_NAME,
+ &gEfiCapsuleVendorGuid,
+ NULL,
+ &Size,
+ (VOID *) &CapsuleDataPtr
+ );
+
+ if (Status == EFI_SUCCESS) {
+ ///
+ /// Wake up system 2 seconds after putting system into S3 to complete the reset operation.
+ ///
+ SetSystemWakeupAlarm (2);
+ ///
+ /// Process capsules across a system reset.
+ ///
+ PmBase = PciRead16 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ ASSERT (PmBase != 0);
+
+ Data32 = IoRead32 ((UINTN) (PmBase + R_PCH_ACPI_PM1_CNT));
+
+ Data32 = (UINT32) ((Data32 & ~(B_PCH_ACPI_PM1_CNT_SLP_TYP + B_PCH_ACPI_PM1_CNT_SLP_EN)) | V_PCH_ACPI_PM1_CNT_S3);
+
+ Eflags = (UINT32) AsmReadEflags ();
+
+ if ((Eflags & 0x200)) {
+ DisableInterrupts ();
+ }
+
+ AsmWbinvd ();
+ AsmWriteCr0 (AsmReadCr0 () | 0x060000000);
+
+ IoWrite32 (
+ (UINTN) (PmBase + R_PCH_ACPI_PM1_CNT),
+ (UINT32) Data32
+ );
+
+ Data32 = Data32 | B_PCH_ACPI_PM1_CNT_SLP_EN;
+
+ IoWrite32 (
+ (UINTN) (PmBase + R_PCH_ACPI_PM1_CNT),
+ (UINT32) Data32
+ );
+
+ if ((Eflags & 0x200)) {
+ EnableInterrupts ();
+ }
+ ///
+ /// Should not return
+ ///
+ EFI_DEADLOOP ();
+ }
+}
+#endif
+
+/**
+ Execute call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The callback function has been done successfully
+ @retval EFI_NOT_FOUND Failed to find Pch Reset Callback protocol. Or, none of
+ callback protocol is installed.
+ @retval Others Do not do any reset from PCH
+**/
+EFI_STATUS
+EFIAPI
+PchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ )
+{
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Index;
+ PCH_RESET_CALLBACK_PROTOCOL *PchResetCallback;
+// AMI_OVERRIDE, [EIP111666] >>>
+ UINTN VariableSize = 1;
+ UINT8 TempBuffer;
+ BOOLEAN LegacyBoot = FALSE;
+// AMI_OVERRIDE, [EIP111666] <<<
+
+// AMI_OVERRIDE, [EIP111666] >>>
+ Status = gRT->GetVariable (
+ L"InLegacyBoot",
+ &gPchGetResetTypeGuid,
+ NULL,
+ &VariableSize,
+ &TempBuffer
+ );
+
+ // If variable found, we are in runtime.
+ if(!EFI_ERROR(Status))
+ LegacyBoot = TRUE;
+
+ if (!(EfiAtRuntime () || LegacyBoot)) {
+// AMI_OVERRIDE, [EIP111666] <<<
+
+ ///
+ /// Retrieve all instances of Pch Reset Callback protocol
+ ///
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gPchResetCallbackProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ ///
+ /// Those drivers that need to install Pch Reset Callback protocol have the responsibility
+ /// to make sure themselves execute before Pch Reset Runtime driver.
+ ///
+ if (Status == EFI_NOT_FOUND) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Or, none of Pch Reset callback protocol is installed.\n"));
+ }
+
+ return Status;
+ }
+
+ for (Index = 0; Index < NumHandles; Index++) {
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gPchResetCallbackProtocolGuid,
+ (VOID **) &PchResetCallback
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (!EFI_ERROR (Status)) {
+ PchResetCallback->ResetCallback (PchResetType);
+ } else {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate Pch Reset Callback protocol.\n"));
+ return Status;
+ }
+ }
+ }
+
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ if (PchResetType == WarmReset) {
+ CapsuleReset ();
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context. Not used in this event handler.
+
+ @retval None
+**/
+EFI_RUNTIMESERVICE
+VOID
+PchResetVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mPchResetInstance->PchResetProtocol.Reset));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mPchResetInstance->PchRootComplexBar));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mPchResetInstance));
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.cif b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.cif
new file mode 100644
index 0000000..ba1456a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchReset"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Reset\RuntimeDxe"
+ RefName = "PchReset"
+[files]
+"PchReset.sdl"
+"PchReset.mak"
+"PchReset.c"
+"PchReset.h"
+"PchReset.dxs"
+"PchResetRuntime.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.dxs b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.dxs
new file mode 100644
index 0000000..7047c3a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.dxs
@@ -0,0 +1,39 @@
+/** @file
+ Dependency expression file.
+
+@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"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h
new file mode 100644
index 0000000..4a43703
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.h
@@ -0,0 +1,83 @@
+/** @file
+ Header file for PCH RESET Runtime 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_RESET_H
+#define _PCH_RESET_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 EFI_PROTOCOL_PRODUCER (PchReset)
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include EFI_GUID_DEFINITION (Capsule)
+#include "PchResetCommon.h"
+#include "DxeRuntimePciLibPciExpress.h"
+#endif
+
+/**
+ Initialize the state information for the Timer Architectural Protocol
+
+ @param[in] ImageHandle Image handle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Thread can be successfully created
+ @retval EFI_OUT_OF_RESOURCES Cannot allocate protocol data structure
+ @retval EFI_DEVICE_ERROR Cannot create the timer service
+**/
+EFI_STATUS
+EFIAPI
+InstallPchReset (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Execute call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The callback function has been done successfully
+ @retval EFI_NOT_FOUND Failed to find Pch Reset Callback protocol. Or, none of
+ callback protocol is installed.
+ @retval Others Do not do any reset from PCH
+**/
+EFI_STATUS
+EFIAPI
+PchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ );
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context. Not used in this event handler.
+
+ @retval None
+**/
+VOID
+PchResetVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.mak b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.mak
new file mode 100644
index 0000000..9e3ae14
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.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/PchReset/PchReset.mak 3 6/24/13 6:21a Scottyang $
+#
+# $Revision: 3 $
+#
+# $Date: 6/24/13 6:21a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchReset/PchReset.mak $
+#
+# 3 6/24/13 6:21a Scottyang
+# [TAG] EIP127297
+# [Category] Improvement
+# [Description] Update PCH RC 1.6.0.
+# [Files] SB.sd, SBDxe.c, ..\ReferenceCode\Chipset\LynxPoint\*.*
+#
+# 2 2/24/12 2:16a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:04a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchReset Driver
+#---------------------------------------------------------------------------
+EDK : PchReset
+PchReset : $(BUILD_DIR)\PchReset.mak PchResetBin
+
+
+PchReset_OBJECTS = \
+$(BUILD_DIR)\$(PchReset_DIR)\PchReset.obj
+
+$(BUILD_DIR)\PchReset.mak : $(PchReset_DIR)\$(@B).cif $(PchReset_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchReset_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchReset_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchReset_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchReset"\
+ /D"__EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=PchResetVirtualAddressChangeEvent"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+
+PchReset_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(ArchProtocolLib)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(DxeRuntimePciLibPciExpressLib_LIB)\
+ $(PchResetCommonDxeLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+
+PchResetBin: $(PchReset_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchReset.mak all \
+ "MY_INCLUDES=$(PchReset_INCLUDES)"\
+ "MY_DEFINES=$(PchReset_DEFINES)"\
+ GUID=BB1FBD4F-2E30-4793-9BED-74F672BC8FFE\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ "OBJECTS=$(PchReset_OBJECTS)" \
+ DEPEX1=$(PchReset_DIR)\PchReset.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/Reset/RuntimeDxe/PchReset.sdl b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.sdl
new file mode 100644
index 0000000..40d618b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchReset.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/PchReset/PchReset.sdl 1 2/08/12 9:04a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:04a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchReset/PchReset.sdl $
+#
+# 1 2/08/12 9:04a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchReset_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchReset support in Project"
+End
+
+PATH
+ Name = "PchReset_DIR"
+ Help = "PchReset file source directory"
+End
+
+MODULE
+ File = "PchReset.mak"
+ Help = "Includes PchReset to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchReset.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/Reset/RuntimeDxe/PchResetRuntime.inf b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchResetRuntime.inf
new file mode 100644
index 0000000..e099032
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Reset/RuntimeDxe/PchResetRuntime.inf
@@ -0,0 +1,90 @@
+## @file
+# Component description file for Pch Reset Runtime module
+#
+#@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 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 = PchResetRuntime
+FILE_GUID = AF59F2F5-5E28-4e03-80E2-4727545AF811
+COMPONENT_TYPE = RT_DRIVER
+
+[sources.common]
+ PchReset.c
+ PchReset.h
+ ../Common/PchResetCommon.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueEdkDxeRuntimeDriverLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeServicesTableLib
+ ArchProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchDxeRuntimePciLibPciExpress
+ EdkProtocolLib
+ PchPlatformLib
+ EdkFrameworkProtocolLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchReset.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchReset
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=PchResetVirtualAddressChangeEvent
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_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_EDK_DXE_RUNTIME_DRIVER_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c
new file mode 100644
index 0000000..943ffd7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.c
@@ -0,0 +1,369 @@
+/** @file
+ This is the driver that implements the PCH S3 Support protocol
+
+@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 "PchS3Support.h"
+#include "S3SupportHob.h"
+// AMI_OVERRIDE, [ EIP217847 ] >>>
+#include "token.h"
+// AMI_OVERRIDE, [ EIP217847 ] <<<
+
+//
+// Global Variables
+//
+EFI_HANDLE mImageHandle;
+EFI_PCH_S3_SUPPORT_PROTOCOL mPchS3SupportProtocol;
+EFI_PCH_S3_SUPPORT_SMM_PROTOCOL mPchS3SupportSmmProtocol;
+UINT32 mPchS3ImageEntryPoint;
+EFI_PCH_S3_DISPATCH_ARRAY *mPchS3CustomDispatchScript;
+
+//
+// GUID Definitions
+//
+EFI_GUID gS3SupportHobGuid = S3_SUPPORT_HOB_GUID;
+EFI_GUID gS3SupportSmramDataGuid = EFI_PCH_S3_SUPPORT_DATA_GUID;
+
+//
+// Functions
+//
+
+/**
+ PCH S3 support driver entry point
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+EFIAPI
+PchS3SupportEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "PchS3SupportEntryPoint() Start\n"));
+ mImageHandle = ImageHandle;
+
+ ///
+ /// Initialize the Boot Services memory for the Dispatch Script Array
+ ///
+ Status = InitializePchS3CustomScriptMemory();
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "Dispatch Script Array Space initialized.\n"));
+
+ ///
+ /// Retrieve the PCH S3 Support PEIM entry point and load it into the Module variable
+ ///
+ Status = LoadPchS3ImageEntryPoint (&mPchS3ImageEntryPoint);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "PCH S3 Image Entry Point intialized.\n"));
+
+ ///
+ /// Initialize and Install the PCH S3 Support and PCH S3 SMM Support protocols
+ ///
+ mPchS3SupportSmmProtocol.DispatchArray = mPchS3CustomDispatchScript;
+ mPchS3SupportSmmProtocol.ProtocolSize = 1; // Allocate one page
+ mPchS3SupportProtocol.SetDispatchItem = PchS3SetDispatchItem;
+ mPchS3SupportProtocol.ReadyToLock = S3SupportReadyToLock;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mImageHandle,
+ &gEfiPchS3SupportProtocolGuid,
+ &mPchS3SupportProtocol,
+ &gEfiPchS3SupportSmmProtocolGuid,
+ &mPchS3SupportSmmProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "PchS3SupportEntryPoint() End\n"));
+
+ return Status;
+}
+
+/**
+ Set an item to be dispatched at S3 resume time. This will initially create a Script
+ entry in Boot Services memory. At the same time, the entry point of the PCH S3 support
+ image is returned to be used in subsequent boot script save calls.
+
+ @param[in] This Pointer to the protocol instance.
+ @param[in] DispatchItem The item to be dispatched.
+ @param[out] S3DispatchEntryPoint The entry point of the PCH S3 support image.
+
+ @retval EFI_STATUS Successfully completed.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+EFI_STATUS
+EFIAPI
+PchS3SetDispatchItem (
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL *This,
+ IN EFI_PCH_S3_DISPATCH_ITEM *InputDispatchItem,
+ OUT EFI_PHYSICAL_ADDRESS *S3DispatchEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TypeSize;
+ UINT32 ParameterSize;
+ UINT32 Size;
+ UINT8 *CurrentPos;
+
+ DEBUG ((EFI_D_INFO, "PchS3SetDispatchItem() Start\n"));
+
+ Status = EFI_SUCCESS;
+
+ DEBUG ((EFI_D_INFO, "Dispatch Item Address: 0x%x; Dispatch Item Type: %x\n", (UINTN)InputDispatchItem, (UINTN)InputDispatchItem->ItemType.Value));
+
+ ///
+ /// Calculate the size required;
+ /// ** Always round up to be 8 byte aligned as the script is initially created from 64-bit code in DXE
+ ///
+ switch (InputDispatchItem->ItemType.Value) {
+ case PchS3ItemTypeSendCodecCommand:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND);
+ break;
+
+ case PchS3ItemTypeInitPcieRootPortDownstream:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM);
+ break;
+
+ case PchS3ItemTypePcieSetPm:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_PCIE_SET_PM);
+ break;
+
+ case PchS3ItemTypeProgramIobp:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_PROG_IOBP);
+ break;
+
+ default:
+ ParameterSize = 0;
+ DEBUG ((EFI_D_INFO, "Unrecognized Custom Dispatch Type\n"));
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ///
+ /// Round up TypeSize to be 8 byte aligned
+ ///
+ TypeSize = QWORD_ALIGNED_SIZE (EFI_PCH_S3_DISPATCH_ITEM_TYPE);
+
+ ///
+ /// Total size is TypeSize + ParameterSize
+ ///
+ Size = TypeSize + ParameterSize;
+
+ if (mPchS3CustomDispatchScript->BufferSpaceRemaining < Size) {
+ DEBUG ((EFI_D_INFO, "Space remaining in Dispatch Script buffer is too small\n"));
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (mPchS3CustomDispatchScript->NextDispatchItem == NULL) {
+ DEBUG ((EFI_D_INFO, "S3 Support Protocol has been unregistered. Error.\n"));
+ ASSERT (FALSE);
+ return EFI_ACCESS_DENIED;
+ }
+
+ ///
+ /// Store the dispatch type and dispatch parameter
+ ///
+ CurrentPos = mPchS3CustomDispatchScript->NextDispatchItem;
+ *(EFI_PCH_S3_DISPATCH_ITEM_TYPE *)CurrentPos = InputDispatchItem->ItemType.Value;
+ CurrentPos += TypeSize;
+ CopyMem (CurrentPos, InputDispatchItem->Parameter, ParameterSize);
+
+ ///
+ /// Move the pointer to the NextDispatchItem ahead to free space in our buffer
+ /// and decrement the space remaining data
+ ///
+ mPchS3CustomDispatchScript->NextDispatchItem += Size;
+ mPchS3CustomDispatchScript->BufferSpaceRemaining -= Size;
+
+ ///
+ /// Return the S3 Image's entry point
+ ///
+ *S3DispatchEntryPoint = mPchS3ImageEntryPoint;
+
+ DEBUG ((EFI_D_INFO, "PchS3SetDispatchItem() End\n"));
+
+ return Status;
+}
+
+
+/**
+ Perform the EFI_PCH_S3_SUPPORT_SMM_PROTOCOL IO Trap to invoke DispatchArray data copy and
+ IO Trap Unregister.
+
+ @param[in] This Pointer to the protocol instance.
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+EFIAPI
+S3SupportReadyToLock(
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+
+
+ DEBUG ((EFI_D_INFO, "S3SupportExitPmAuthCallback() Start\n"));
+
+ Status = EFI_SUCCESS;
+
+ DEBUG ((EFI_D_INFO, "Invoke the S3 Support IO Trap: 0x%x\n", mPchS3SupportSmmProtocol.PchS3SupportIoTrap));
+
+ ///
+ /// Invoke the SMM IO Trap Handler for invoking the data copy to SMRAM and unregistration of the IO Trap
+ ///
+ IoWrite32 (mPchS3SupportSmmProtocol.PchS3SupportIoTrap, 0);
+
+ if (mImageHandle != NULL)
+ {
+ DEBUG ((EFI_D_INFO, "Uninstall the S3 Support Protocol\n", mPchS3SupportSmmProtocol.PchS3SupportIoTrap));
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ mImageHandle,
+ &gEfiPchS3SupportProtocolGuid,
+ &mPchS3SupportProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+ DEBUG ((EFI_D_INFO, "S3SupportExitPmAuthCallback() End\n"));
+
+ return Status;
+}
+
+/**
+ Initialize the Pch S3 Custom Script memory area. This will later be transferred to SMRAM.
+
+ @param[in] VOID
+
+ @retval EFI_SUCCESS Successfully completed.
+ @retval EFI_OUT_OF_RESOURCES Not enough space was available to allocate for the BS memory required.
+**/
+EFI_STATUS
+InitializePchS3CustomScriptMemory (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ ///
+ /// Allocate Boot Services memory for the initial copy of the PCH S3 Custom Dispatch Script
+ ///
+ Status = (gBS->AllocatePool)(
+ EfiBootServicesData,
+ EFI_PAGE_SIZE,
+ &(VOID *)Address);
+ if (!EFI_ERROR (Status)) {
+
+ mPchS3CustomDispatchScript = (EFI_PCH_S3_DISPATCH_ARRAY *)(UINTN)Address;
+
+ ///
+ /// Initialize the DispatchScriptArray
+ /// Ensure to account for the HOB space that will be needed for moving the data from SMRAM to normal
+ /// memory during S3 resume in the MaximumBufferSize parameter.
+ ///
+ mPchS3CustomDispatchScript->PchS3CustomScriptGuid = gS3SupportSmramDataGuid;
+ mPchS3CustomDispatchScript->MaximumBufferSize = EFI_PAGE_SIZE - QWORD_ALIGNED_SIZE(EFI_HOB_GUID_TYPE);
+ mPchS3CustomDispatchScript->BufferSpaceRemaining = mPchS3CustomDispatchScript->MaximumBufferSize - QWORD_ALIGNED_SIZE(EFI_PCH_S3_DISPATCH_ARRAY);
+ mPchS3CustomDispatchScript->NextDispatchItem = (UINT8*)mPchS3CustomDispatchScript + QWORD_ALIGNED_SIZE(EFI_PCH_S3_DISPATCH_ARRAY);
+ }
+
+ return Status;
+}
+
+
+/**
+ Load the entry point address of the PCHS3Peim from the HOB that it generated during the PEI phase of POST
+
+ @param[out] ImageEntryPoint The ImageEntryPoint after success loading
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+LoadPchS3ImageEntryPoint (
+ OUT UINT32 *ImageEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ S3_SUPPORT_HOB *S3SupportHob;
+// EFI_SPI_DATA_PROTOCOL *SpiDataInterface;
+
+ DEBUG ((EFI_D_INFO, "LoadPchS3ImageEntryPoint() Start\n"));
+
+ Status = EFI_SUCCESS;
+ S3SupportHob = NULL;
+ *ImageEntryPoint = 0;
+
+ //
+ // Search for the S3SupportHob
+ //
+ S3SupportHob = GetFirstGuidHob(&gS3SupportHobGuid);
+ if (S3SupportHob == NULL) {
+ DEBUG ((EFI_D_INFO, "S3SupportHob not found.\n"));
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+
+ //
+ // Find the SPI protocol and save the pointer.
+ //
+// Status = gBS->LocateProtocol (&gEfiSpiDataProtocolGuid, NULL, &SpiDataInterface);
+// if (EFI_ERROR (Status)) {
+// DEBUG ((EFI_D_ERROR, "ERROR - Spi LocateProtocol failed!\n"));
+// return Status;
+// }
+
+ ///
+ /// If the PCH S3 PEIM is not located in flash, fail
+ ///
+// AMI_OVERRIDE, [ EIP217847 ] >>>
+// if (S3SupportHob->PchS3PeimEntryPoint < SpiDataInterface->BiosStartMemoryAddress ||
+// S3SupportHob->PchS3PeimEntryPoint > SpiDataInterface->BiosStartMemoryAddress + SpiDataInterface->BiosSize)
+ if ((S3SupportHob->PchS3PeimEntryPoint < (0xFFFFFFFF - FLASH_SIZE + 1)) || (S3SupportHob->PchS3PeimEntryPoint > 0xFFFFFFFF))
+// AMI_OVERRIDE, [ EIP217847 ] <<<
+ {
+ DEBUG ((EFI_D_INFO, "PchS3Image is NOT located in Flash. Current Entry Point: %x\n", S3SupportHob->PchS3PeimEntryPoint));
+
+ ASSERT(FALSE);
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ // Load the HOB data from PEI execution which contains the entry point of the PCHS3Peim from Flash
+ *ImageEntryPoint = S3SupportHob->PchS3PeimEntryPoint;
+
+ DEBUG ((EFI_D_INFO, "PchS3Image is Located in Flash at Entry Point: %x\n", S3SupportHob->PchS3PeimEntryPoint));
+ DEBUG ((EFI_D_INFO, "LoadPchS3ImageEntryPoint() End\n"));
+
+ return Status;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.cif b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.cif
new file mode 100644
index 0000000..cbd8f6a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchS3Support"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\S3Support\Dxe"
+ RefName = "PchS3Support"
+[files]
+"PchS3Support.sdl"
+"PchS3Support.mak"
+"PchS3Support.c"
+"PchS3Support.h"
+"PchS3Support.dxs"
+"PchS3Support.inf"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.dxs b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.dxs
new file mode 100644
index 0000000..8c346bd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.dxs
@@ -0,0 +1,45 @@
+/** @file
+ Dispatch dependency expression file for the PchS3Support driver.
+
+@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 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_CONSUMER (Spi)
+#endif
+
+//DEPENDENCY_START
+// EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID AND
+// EFI_SPI_DATA_PROTOCOL_GUID
+//DEPENDENCY_END
+DEPENDENCY_START
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID
+DEPENDENCY_END \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h
new file mode 100644
index 0000000..817f786
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.h
@@ -0,0 +1,126 @@
+/** @file
+ Header file for PCH S3 Support driver
+
+@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
+**/
+#ifndef _PCH_S3_SUPPORT_DRIVER_H_
+#define _PCH_S3_SUPPORT_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 Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_PRODUCER (PchS3Support)
+#include EFI_GUID_DEFINITION (S3SupportHob)
+#include EFI_PROTOCOL_CONSUMER (Spi)
+
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_PCH_S3_IMAGE_GUID \
+ { \
+ 0x271dd6f2, 0x54cb, 0x45e6, 0x85, 0x85, 0x8c, 0x92, 0x3c, 0x1a, 0xc7, 0x6 \
+ }
+#else
+#define EFI_PCH_S3_IMAGE_GUID \
+ { \
+ 0x271dd6f2, 0x54cb, 0x45e6, \
+ { \
+ 0x85, 0x85, 0x8c, 0x92, 0x3c, 0x1a, 0xc7, 0x6 \
+ } \
+ }
+#endif
+
+extern EFI_GUID gEfiSpiProtocolGuid;
+
+//
+// Function prototypes
+//
+
+/**
+ Set an item to be dispatched at S3 resume time. At the same time, the entry point
+ of the PCH S3 support image is returned to be used in subsequent boot script save
+ call
+
+ @param[in] This Pointer to the protocol instance.
+ @param[in] InputDispatchItem The item to be dispatched.
+ @param[out] S3DispatchEntryPoint The entry point of the PCH S3 support image.
+
+ @retval EFI_STATUS Successfully completed.
+ @retval EFI_OUT_OF_RESOURCES Out of resources.
+**/
+EFI_STATUS
+EFIAPI
+PchS3SetDispatchItem (
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL *This,
+ IN EFI_PCH_S3_DISPATCH_ITEM *InputDispatchItem,
+ OUT EFI_PHYSICAL_ADDRESS *S3DispatchEntryPoint
+ );
+
+/**
+ Perform the EFI_PCH_S3_SUPPORT_SMM_PROTOCOL IO Trap to invoke DispatchArray data copy and
+ IO Trap Unregister.
+
+ @param[in] This Pointer to the protocol instance.
+
+ @retval EFI_SUCCESS Successfully completed.
+**/
+EFI_STATUS
+EFIAPI
+S3SupportReadyToLock(
+ IN EFI_PCH_S3_SUPPORT_PROTOCOL *This
+ );
+
+/**
+ Initialize the Pch S3 Custom Script memory area. This will later be transferred to SMRAM.
+
+ @param[in] VOID
+
+ @retval None
+**/
+EFI_STATUS
+InitializePchS3CustomScriptMemory (
+ VOID
+ );
+
+/**
+ Load the entry point address of the PCHS3Peim from the HOB that it generated during the PEI phase of POST
+
+ @param[out] ImageEntryPoint The ImageEntryPoint after success loading
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+LoadPchS3ImageEntryPoint (
+ OUT UINT32 *ImageEntryPoint
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.inf b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.inf
new file mode 100644
index 0000000..c65847f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.inf
@@ -0,0 +1,103 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+#@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 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 = PchS3Support
+FILE_GUID = C7EA9787-CA0A-43b4-B1E5-25EF87391F8D
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchS3Support.h
+ PchS3Support.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ $(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/S3SupportHob
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchS3Support
+#
+# 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/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
+
+[libraries.common]
+ EfiScriptLib
+ EfiCommonLib
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeHobLib
+ EdkIIGlueBasePciLibPciExpress
+ EfiDriverLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueUefiLib
+ EfiGuidLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchS3Support.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchS3SupportEntryPoint
+ 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/S3Support/Dxe/PchS3Support.mak b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.mak
new file mode 100644
index 0000000..cabc751
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.mak
@@ -0,0 +1,115 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, 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/S3Support/Dxe/PchS3Support.mak 1 5/21/15 2:53a Dennisliu $
+#
+# $Revision: 1 $
+#
+# $Date: 5/21/15 2:53a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/S3Support/Dxe/PchS3Support.mak $
+#
+# 1 5/21/15 2:53a Dennisliu
+# [TAG] EIP217847
+# [Category] Improvement
+# [Description] [PCH] Shark Bay-M/DT Reference Code Production Version
+# 1.9.1
+# [Files] PchS3Support.sdl
+# PchS3Support.mak
+# PchS3Support.c
+# PchS3Support.h
+# PchS3Support.dxs
+# PchS3Support.inf
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchS3Support Driver
+#---------------------------------------------------------------------------
+EDK : PchS3Support
+PchS3Support : $(BUILD_DIR)\PchS3Support.mak PchS3SupportBin
+
+
+$(BUILD_DIR)\PchS3Support.mak : $(PchS3Support_DIR)\$(@B).cif $(PchS3Support_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchS3Support_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchS3Support_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchS3Support_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=PchS3SupportEntryPoint"\
+ /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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+
+PchS3Support_LIB_LINKS =\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EFISCRIPTLIB) $(EFIPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(PchS3SupportCommonDxeLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EFIDRIVERLIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+
+
+PchS3SupportBin: $(PchS3Support_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchS3Support.mak all \
+ "MY_INCLUDES=$(PchS3Support_INCLUDES)"\
+ "MY_DEFINES=$(PchS3Support_DEFINES)"\
+ GUID=08F2C63B-08DE-4ccd-8670-ACFE644A1C48\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchS3Support_DIR)\PchS3Support.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.sdl b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.sdl
new file mode 100644
index 0000000..15c9702
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Dxe/PchS3Support.sdl
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, 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/S3Support/Dxe/PchS3Support.sdl 1 5/21/15 2:53a Dennisliu $
+#
+# $Revision: 1 $
+#
+# $Date: 5/21/15 2:53a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/S3Support/Dxe/PchS3Support.sdl $
+#
+# 1 5/21/15 2:53a Dennisliu
+# [TAG] EIP217847
+# [Category] Improvement
+# [Description] [PCH] Shark Bay-M/DT Reference Code Production Version
+# 1.9.1
+# [Files] PchS3Support.sdl
+# PchS3Support.mak
+# PchS3Support.c
+# PchS3Support.h
+# PchS3Support.dxs
+# PchS3Support.inf
+#
+#*************************************************************************
+TOKEN
+ Name = "PchS3Support_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchS3Support support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchS3Support_DIR"
+End
+
+MODULE
+ Help = "Includes PchS3Support.mak to Project"
+ File = "PchS3Support.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchS3Support.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c
new file mode 100644
index 0000000..7e7149e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.c
@@ -0,0 +1,563 @@
+/** @file
+ This is the PEIM that performs the S3 resume tasks.
+
+@copyright
+ Copyright (c) 2008 - 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 "PchS3Peim.h"
+#include "S3SupportHob.h"
+
+//
+// GUID Definitions
+//
+EFI_GUID gS3SupportHobGuid = S3_SUPPORT_HOB_GUID;
+EFI_GUID gS3SupportSmramDataGuid = EFI_PCH_S3_SUPPORT_DATA_GUID;
+EFI_GUID gS3DataHobGuid = S3_DATA_HOB_GUID;
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mSmmAccessCallbackList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiSmmAccessPpiGuid,
+ CreateS3DataHob
+};
+
+
+
+/**
+ PCH S3 PEIM entry point. This Entry Point is entered for three separate reasons.
+ 1. It is entered via dispatcher in standard POST in order to create a HOB for
+ the DXE module to find it's EntryPoint.
+ 2. It is entered via dispatcher in S3 Resume in order to find the Dispatch Script
+ in SMRAM and copy it to a HOB in Boot Services memory.
+ 3. It is entered in response to an invocation from the Boot Script Dispatch Opcode.
+
+ In all three cases it is critical that this code is executed directly from Flash and
+ not from a location in memory.
+
+
+ @param[in] FfsHeader Header for FFS
+ @param[in] PeiServices PEI Services table pointer
+
+ @retval EFI_SUCCESS Successfully completed
+**/
+EFI_STATUS
+EFIAPI
+InitializePchS3Peim (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINT32 ParameterSize;
+ UINT32 TypeSize;
+ UINT32 Size;
+ EFI_PCH_S3_DISPATCH_ARRAY *DispatchArray;
+ EFI_PCH_S3_DISPATCH_ITEM *DispatchItem;
+ S3_SUPPORT_HOB *S3SupportHob;
+ S3_DATA_HOB *GuidHob;
+ PEI_SMM_ACCESS_PPI *SmmAccessPpi;
+
+ DEBUG ((EFI_D_INFO, "InitializePchS3Peim() Start\n"));
+
+ Status = EFI_SUCCESS;
+
+ GuidHob = (S3_DATA_HOB *)GetFirstGuidHob (&gS3DataHobGuid);
+
+ ///
+ /// Search for the S3 Data Hob
+ /// Not finding the Hob indicates that this is the initial pass through this code for any particular POST (S3, S4, S5 or other)
+ ///
+ if (GuidHob == NULL)
+ {
+ //
+ // If we are entering the entry point for the first time on a specific boot (regardless of mode),
+ // then we need to generate a HOB with the entry point information in order to pass the data to DXE
+ // for entry into the Boot Script.
+ //
+ DEBUG ((EFI_D_INFO, "PCH S3 Data HOB didn't exist\n"));
+ DEBUG ((EFI_D_INFO, "Attempt to create the PchS3Peim S3 Support Hob\n"));
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof (S3_SUPPORT_HOB),
+ &S3SupportHob
+ );
+ if (!EFI_ERROR (Status)) {
+ S3SupportHob->Header.Name = gS3SupportHobGuid;
+ S3SupportHob->PchS3PeimEntryPoint = (UINTN) _ModuleEntryPoint;
+ DEBUG ((EFI_D_INFO, "PCH S3 Hob Created - %g\n", &gS3SupportHobGuid));
+ }
+
+ DEBUG ((EFI_D_INFO, "Collect data from SMRAM for PCH S3 Data Script\n"));
+
+ ///
+ /// Creation of the S3 Data Hob is only needed on S3. However, the boot mode can't be trusted
+ /// until after Memory Initialization has been completed because of RapidStart (FFS).
+ /// As a result, we will check boot mode inside of the CreateS3DataHob function after the SmmAccessPpi
+ /// is available.
+ ///
+ Status = PeiServicesLocatePpi (
+ &gPeiSmmAccessPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&SmmAccessPpi
+ );
+ if (Status == EFI_SUCCESS)
+ {
+
+ ///
+ /// Then this is our first call on S3 resume
+ /// Find the PCH S3 Boot Script within SMRAM and create the HOB used for executing the Script
+ ///
+ Status = CreateS3DataHob (PeiServices, NULL, SmmAccessPpi);
+ DEBUG ((EFI_D_INFO, "CreateS3DataHob, result=%r\n", Status));
+
+ }
+ else
+ {
+ ///
+ /// Register for notify if SMM_ACCESS isn't yet available.
+ /// We can't have a module dependency on SMM_ACCESS because the module
+ /// must be called on both Normal Boot and S3 resume. SMM_ACCESS
+ /// PPI isn't published on Normal Boot, however.
+ ///
+ DEBUG ((EFI_D_INFO, "SMM Access protocol not yet available -> Register for notification later.\n"));
+
+ //
+ // Register notify to set default variable once variable service is ready.
+ //
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mSmmAccessCallbackList);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ }
+ return Status;
+ }
+ else
+ {
+ DEBUG ((EFI_D_INFO, "PchS3Peim S3 Data Hob located. Proceed with Dispatch.\n"));
+
+ ///
+ /// Setup the DispatchArray variable to point at the Hob
+ ///
+ DispatchArray = (EFI_PCH_S3_DISPATCH_ARRAY *)(VOID *)&GuidHob->S3DispatchDataArray;
+ }
+
+ DEBUG ((EFI_D_INFO, "Dispatch Array Located -> 0x%x\n", DispatchArray));
+ DEBUG ((EFI_D_INFO, "Dispatch Item Located (Current NextDispatchItem entry) -> 0x%x\n", DispatchArray->NextDispatchItem));
+
+ DispatchItem = (EFI_PCH_S3_DISPATCH_ITEM *)DispatchArray->NextDispatchItem;
+
+ DEBUG ((EFI_D_INFO, "Dispatch Item Type -> 0x%x\n", DispatchItem->ItemType.Value));
+
+ ///
+ /// Calculate the size required;
+ /// ** Always round up to be 8 byte aligned as the script is initially created from 64-bit code in DXE
+ ///
+ TypeSize = QWORD_ALIGNED_SIZE (EFI_PCH_S3_DISPATCH_ITEM_TYPE);
+
+ switch (DispatchItem->ItemType.Value) {
+ case PchS3ItemTypeSendCodecCommand:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND);
+ Status = PchS3SendCodecCommand ((EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND *)&DispatchItem->Parameter);
+ break;
+
+ case PchS3ItemTypeInitPcieRootPortDownstream:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM);
+ Status = PchS3InitPcieRootPortDownstream ((EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM *)&DispatchItem->Parameter);
+ if (Status == EFI_NOT_FOUND) {
+ ///
+ /// EFI_NOT_FOUND is not an error here
+ ///
+ Status = EFI_SUCCESS;
+ }
+ break;
+
+ case PchS3ItemTypePcieSetPm:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_PCIE_SET_PM);
+ Status = PchS3PcieSetPm ((EFI_PCH_S3_PARAMETER_PCIE_SET_PM *)&DispatchItem->Parameter);
+ if (Status == EFI_NOT_FOUND) {
+ ///
+ /// EFI_NOT_FOUND is not an error here
+ ///
+ Status = EFI_SUCCESS;
+ }
+ break;
+
+ case PchS3ItemTypeProgramIobp:
+ ParameterSize = QWORD_ALIGNED_SIZE(EFI_PCH_S3_PARAMETER_PROG_IOBP);
+ Status = PchS3ProgramIobp ((EFI_PCH_S3_PARAMETER_PROG_IOBP *)&DispatchItem->Parameter);
+ break;
+
+ default:
+ ParameterSize = 0;
+ DEBUG ((EFI_D_INFO, "Parameter not found\n"));
+
+ ASSERT (FALSE);
+ break;
+ }
+
+ ///
+ /// Advance the Execution Position
+ ///
+ Size = ParameterSize + TypeSize;
+ DispatchArray->NextDispatchItem += Size;
+
+ if ((UINTN)DispatchArray->NextDispatchItem > (UINTN)((UINT8*)DispatchArray + DispatchArray->MaximumBufferSize)) {
+ ///
+ /// We are beyond end, wrap for the next S3 resume path
+ ///
+ DispatchArray->NextDispatchItem = (UINT8*)DispatchArray + QWORD_ALIGNED_SIZE(EFI_PCH_S3_DISPATCH_ARRAY);
+ }
+
+ DEBUG ((EFI_D_INFO, "InitializePchS3Peim() End\n"));
+
+ return Status;
+}
+
+/**
+This routine is used to search SMRAM and get SmramCpuData point.
+
+@param[in] PeiServices - PEI services global pointer
+@param[in] SmmAccessPpi - SmmAccess PPI instance
+
+@retval SmramCpuData - The pointer of CPU information in SMRAM.
+**/
+EFI_STATUS
+CreateS3DataHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Interface
+ )
+{
+ EFI_SMRAM_DESCRIPTOR *SmramRanges;
+ UINTN SmramRangeCount;
+ UINTN Size;
+ EFI_STATUS Status;
+ UINT32 Address;
+ EFI_PCH_S3_DISPATCH_ARRAY *S3DispatchArray;
+ PEI_SMM_ACCESS_PPI *SmmAccessPpi;
+ BOOLEAN Found;
+ UINTN Index;
+ S3_DATA_HOB *GuidHob;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG ((EFI_D_INFO, "CreateS3DataHob() Start\n"));
+
+ ///
+ /// Now that we know we have a valid Boot Mode.
+ /// Check it to see if we need to process the S3 Data Hob Request
+ ///
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "PchS3Peim S3 Boot Mode not available.\n"));
+ return Status;
+ }
+
+ DEBUG ((EFI_D_INFO, "PchS3Peim S3 Boot Mode Check: %x\n", BootMode));
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ //
+ // Only Create the S3 Data Hob on S3 resume
+ //
+ return Status;
+ }
+
+ SmmAccessPpi = (PEI_SMM_ACCESS_PPI *)Interface;
+
+ Found = FALSE;
+ S3DispatchArray = NULL;
+
+ ///
+ /// Open all SMM regions
+ ///
+ Index = 0;
+ do {
+ Status = SmmAccessPpi->Open (PeiServices, SmmAccessPpi, Index);
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+ ///
+ /// Get all SMRAM range
+ ///
+ Size = 0;
+ Status = SmmAccessPpi->GetCapabilities (PeiServices, SmmAccessPpi, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ Status = PeiServicesAllocatePool (
+ Size,
+ (VOID **)&SmramRanges
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = SmmAccessPpi->GetCapabilities (PeiServices, SmmAccessPpi, &Size, SmramRanges);
+ ASSERT_EFI_ERROR (Status);
+
+ Size /= sizeof (*SmramRanges);
+ SmramRangeCount = Size;
+
+ ///
+ /// Assume TSEG is the last range of SMRAM in SmramRanges
+ ///
+ SmramRanges += SmramRangeCount - 1;
+
+ ///
+ /// Search SMRAM on page alignment for the SMM PCH S3 SMRAM Data signature
+ ///
+ for (Address = (UINT32)(SmramRanges->CpuStart + SmramRanges->PhysicalSize - EFI_PAGE_SIZE);
+ Address >= (UINT32)SmramRanges->CpuStart;
+ Address -= EFI_PAGE_SIZE
+ ) {
+ S3DispatchArray = (EFI_PCH_S3_DISPATCH_ARRAY *)(UINTN)Address;
+ if (CompareGuid (&S3DispatchArray->PchS3CustomScriptGuid, &gS3SupportSmramDataGuid)) {
+ ///
+ /// Find it
+ ///
+ Found = TRUE;
+ break;
+ }
+ }
+
+ ///
+ /// Close all SMM regions
+ ///
+ Index = 0;
+ do {
+ Status = SmmAccessPpi->Close (PeiServices, SmmAccessPpi, Index);
+ Index++;
+ } while (!EFI_ERROR (Status));
+
+
+ if (!Found)
+ {
+ DEBUG ((EFI_D_INFO, "S3 Dispatch Data Not Found!\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Generate Hob from SMRAM Data
+ ///
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ EFI_PAGE_SIZE,
+ &GuidHob
+ );
+
+ if (!EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_INFO, "PchS3Peim S3 Data Hob created: Address - 0x%x\n", (UINTN)GuidHob));
+
+ GuidHob->Header.Name = gS3DataHobGuid;
+ CopyMem (&GuidHob->S3DispatchDataArray, S3DispatchArray, S3DispatchArray->MaximumBufferSize);
+
+ ///
+ /// Reset the NextDispatchItem to the beginning of the buffer for playback.
+ ///
+ S3DispatchArray = (EFI_PCH_S3_DISPATCH_ARRAY *)(UINTN)&GuidHob->S3DispatchDataArray;
+ S3DispatchArray->NextDispatchItem = (UINT8 *)S3DispatchArray + QWORD_ALIGNED_SIZE(EFI_PCH_S3_DISPATCH_ARRAY);
+
+ }
+
+ DEBUG ((EFI_D_INFO, "CreateS3DataHob() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+
+#define AZALIA_MAX_LOOP_TIME 10
+#define AZALIA_WAIT_PERIOD 100
+
+/**
+ 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
+**/
+static
+EFI_STATUS
+CodecStatusPolling (
+ 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 Codec command on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_DEVICE_ERROR Device status error, operation failed
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PchS3SendCodecCommand (
+ EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND *Parameter
+ )
+{
+ UINT32 HdaBar;
+ UINT32 *CodecCommandData;
+ EFI_STATUS Status;
+
+ HdaBar = Parameter->HdaBar;
+ CodecCommandData = &Parameter->CodecCmdData;
+
+ DEBUG ((EFI_D_INFO, "Going to SendCodecCommand: %08x! \n", *CodecCommandData));
+ Status = CodecStatusPolling (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 = CodecStatusPolling (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));
+ DEBUG ((EFI_D_ERROR, "SendCodecCommand: SendCodecCommand:%08x fail! \n"));
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Perform Init Root Port Downstream devices on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3InitPcieRootPortDownstream (
+ EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM *Parameter
+ )
+{
+ EFI_STATUS Status;
+
+ Status = PchPcieInitRootPortDownstreamDevices (
+ Parameter->RootPortBus,
+ Parameter->RootPortDevice,
+ Parameter->RootPortFunc,
+ Parameter->TempBusNumberMin,
+ Parameter->TempBusNumberMax,
+ NULL
+ );
+ ///
+ /// 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.
+ ///
+ return Status;
+}
+
+/**
+ Perform Root Port Downstream devices PCIE ASPM and LTR override on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3PcieSetPm (
+ EFI_PCH_S3_PARAMETER_PCIE_SET_PM *Parameter
+ )
+{
+ EFI_STATUS Status;
+ PCH_PCIE_DEVICE_ASPM_OVERRIDE *DevAspmOverride;
+ PCH_PCIE_DEVICE_LTR_OVERRIDE *DevLtrOverride;
+ PCH_PCIE_PWR_OPT *S3PchPwrOptPcie;
+ BOOLEAN L1SubstatesSupported;
+ BOOLEAN LtrSupported;
+
+ DevAspmOverride = (PCH_PCIE_DEVICE_ASPM_OVERRIDE *) (UINTN) Parameter->DevAspmOverrideAddr;
+ DevLtrOverride = (PCH_PCIE_DEVICE_LTR_OVERRIDE *) (UINTN) Parameter->DevLtrOverrideAddr;
+ S3PchPwrOptPcie = (PCH_PCIE_PWR_OPT *) (UINTN) Parameter->PchPwrOptPcie;
+ Status = PcieSetPm (
+ Parameter->RootPortBus,
+ Parameter->RootPortDevice,
+ Parameter->RootPortFunc,
+ Parameter->RootPortAspm,
+ Parameter->NumOfDevAspmOverride,
+ DevAspmOverride,
+ Parameter->TempBusNumberMin,
+ Parameter->TempBusNumberMax,
+ Parameter->NumOfDevLtrOverride,
+ DevLtrOverride,
+ S3PchPwrOptPcie,
+ &L1SubstatesSupported,
+ Parameter->L1SubstatesConfig,
+ Parameter->PolicyRevision,
+ Parameter->FirstRPToSetPm,
+ Parameter->L1SupportedInAllEnabledPorts,
+ Parameter->ClkreqSupportedInAllEnabledPorts,
+ &LtrSupported
+ );
+ ///
+ /// 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.
+ ///
+ return Status;
+}
+
+/**
+ Perform PCH IOBP programming on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3ProgramIobp (
+ EFI_PCH_S3_PARAMETER_PROG_IOBP *Parameter
+ )
+{
+ EFI_STATUS Status;
+
+ Status = ProgramIobp (
+ Parameter->RootComplexBar,
+ Parameter->Address,
+ Parameter->AndMask,
+ Parameter->OrMask
+ );
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif
new file mode 100644
index 0000000..d19743c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchS3Peim"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\S3Support\Pei"
+ RefName = "PchS3Peim"
+[files]
+"PchS3Peim.sdl"
+"PchS3Peim.mak"
+"PchS3Peim.h"
+"PchS3Peim.c"
+"PchS3Peim.dxs"
+"PchS3Peim.inf"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs
new file mode 100644
index 0000000..fbeaa9b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.dxs
@@ -0,0 +1,41 @@
+/** @file
+ Dispatch dependency expression file for the PchS3Peim driver.
+
+@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 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"
+
+#include "Common/EdkIIGlueDefinitionChangesPeim.h"
+#include EFI_PPI_DEFINITION (BootMode)
+
+#endif
+
+DEPENDENCY_START
+ PEI_MASTER_BOOT_MODE_PEIM_PPI
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h
new file mode 100644
index 0000000..133904a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.h
@@ -0,0 +1,106 @@
+/** @file
+ This is the PEIM that performs the S3 resume tasks.
+
+@copyright
+ Copyright (c) 2008 - 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
+**/
+#ifndef _PCH_S3_PEIM_H_
+#define _PCH_S3_PEIM_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 "EdkIIGluePeim.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "PchPlatformPolicy.h"
+#include "PchPciExpressHelpersLib.h"
+#include EFI_PROTOCOL_CONSUMER (PchS3Support)
+#include EFI_PPI_DEPENDENCY (Variable)
+#include EFI_PPI_DEPENDENCY (SmmAccess)
+
+#endif
+
+#define EFI_PCH_S3_STALL_INTERVAL 50 ///< us
+
+/**
+This routine is used to search SMRAM and get SmramCpuData point.
+
+@param[in] PeiServices - PEI services global pointer
+@param[in] SmmAccessPpi - SmmAccess PPI instance
+
+@retval SmramCpuData - The pointer of CPU information in SMRAM.
+**/
+EFI_STATUS
+CreateS3DataHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Interface
+ );
+
+/**
+ Send Codec command on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_DEVICE_ERROR Device status error, operation failed
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+PchS3SendCodecCommand (
+ EFI_PCH_S3_PARAMETER_SEND_CODEC_COMMAND *Parameter
+ );
+
+/**
+ Perform Init Root Port Downstream devices on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3InitPcieRootPortDownstream (
+ EFI_PCH_S3_PARAMETER_INIT_PCIE_ROOT_PORT_DOWNSTREAM *Parameter
+ );
+
+/**
+ Perform Root Port Downstream devices PCIE ASPM and LTR override on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3PcieSetPm (
+ EFI_PCH_S3_PARAMETER_PCIE_SET_PM *Parameter
+ );
+
+/**
+ Perform PCH IOBP programming on S3 resume
+
+ @param[in] Parameter Parameters passed in from DXE
+
+ @retval EFI_STATUS
+**/
+EFI_STATUS
+PchS3ProgramIobp (
+ EFI_PCH_S3_PARAMETER_PROG_IOBP *Parameter
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf
new file mode 100644
index 0000000..498fde8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.inf
@@ -0,0 +1,100 @@
+## @file
+# Component description file for PchS3 PEIM
+# This is the PEIM that performs the S3 resume tasks as instructed by
+# PCH Init DXE driver. This PEIM is NOT dispatched by PEI Core, but is rather
+# dispatched by the S3 Boot Script Engine. It is the responsibility of PCH
+# Init DXE driver to load this PEIM and register its entry point to the
+# Boot Script engine. This PEIM consumes the PCH Init Variable.
+#
+#@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 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 = PchS3Peim
+FILE_GUID = 271DD6F2-54CB-45e6-8585-8C923C1AC706
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchS3Peim.h
+ PchS3Peim.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchS3Support
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Guid/S3SupportHob
+
+#
+# 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
+#
+# 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]
+ PchPlatformLib
+ PchPciExpressHelpersLib
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGluePeiHobLib
+ EdkPpiLib
+ IntelPchSampleCodePpiLib
+ PeiLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchS3Peim.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchS3Peim
+ C_FLAGS = $(C_FLAGS) -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__
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak
new file mode 100644
index 0000000..aac60c4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.mak
@@ -0,0 +1,52 @@
+#---------------------------------------------------------------------------
+# Create PchS3Pei module
+#---------------------------------------------------------------------------
+EDK : PchS3Peim
+PchS3Peim : $(BUILD_DIR)\PchS3Peim.mak PchS3PeimBin
+
+
+$(BUILD_DIR)\PchS3Peim.mak : $(PchS3Peim_DIR)\$(@B).cif $(PchS3Peim_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchS3Peim_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchS3Peim_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchS3Peim_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchS3Peim"\
+ /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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_PEI_HOB_LIB__ \
+
+PchS3Peim_LIB_LINKS=\
+ $(IntelPchPpiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB) \
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(WdtCommonPeiLib_LIB)\
+ $(EDKFRAMEWORKPPILIB)\
+ $(EdkIIGluePeiHobLib_LIB)\
+ $(IntelSaSampleCodePpiLib_LIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchPciExpressHelpersPeiLib_LIB)\
+ $(PEILIB)\
+
+PchS3PeimBin: $(PchS3Peim_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchS3Peim.mak all \
+ "MY_INCLUDES=$(PchS3Peim_INCLUDES)"\
+ "MY_DEFINES=$(PchS3Peim_DEFINES)"\
+ GUID=271DD6F2-54CB-45e6-8585-8C923C1AC706\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchS3Peim_DIR)\PchS3Peim.dxs\
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX\
+ COMPRESS=0 \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl
new file mode 100644
index 0000000..13198b4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Pei/PchS3Peim.sdl
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, 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/S3Support/Pei/PchS3Peim.sdl 1 5/21/15 2:56a Dennisliu $
+#
+# $Revision: 1 $
+#
+# $Date: 5/21/15 2:56a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/S3Support/Pei/PchS3Peim.sdl $
+#
+# 1 5/21/15 2:56a Dennisliu
+# [TAG] EIP217847
+# [Category] Improvement
+# [Description] [PCH] Shark Bay-M/DT Reference Code Production Version
+# 1.9.1
+# [Files] PchS3Peim.sdl
+# PchS3Peim.mak
+# PchS3Peim.h
+# PchS3Peim.c
+# PchS3Peim.dxs
+# PchS3Peim.inf
+#
+#*************************************************************************
+TOKEN
+ Name = "PchS3Peim_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchS3Peim support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchS3Peim_DIR"
+End
+
+MODULE
+ File = "PchS3Peim.mak"
+ Help = "Includes PchS3Peim.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchS3Peim.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c
new file mode 100644
index 0000000..b08699d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.c
@@ -0,0 +1,156 @@
+/** @file
+ PCH S3 Support Protocol SMM Driver Entry
+
+@copyright
+ Copyright (c) 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 "S3SupportSmm.h"
+
+
+//
+// Global Variables
+//
+UINT16 mS3SupportIoTrapAddress;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *mPchIoTrap;
+EFI_HANDLE mImageHandle;
+EFI_PCH_S3_SUPPORT_SMM_PROTOCOL *mPchS3SupportSmmProtocol;
+EFI_HANDLE mPchIoTrapHandle;
+
+/**
+ An IO Trap SMI callback to copy the DispatchArray data to SMRAM and unregister the IO Trap.
+
+ @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
+S3SupportSmmExitPmAuthCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_STATUS Status;
+
+ DEBUG ((EFI_D_INFO, "S3SupportSmmExitPmAuthCallback() Start\n"));
+
+ ///
+ /// Allocate SMRAM memory for the PCH S3 Custom Dispatch Script
+ ///
+ Status = mSmst->SmmAllocatePages (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ mPchS3SupportSmmProtocol->ProtocolSize,
+ &Address
+ );
+ DEBUG ((EFI_D_INFO, "SMRAM Memory Allocation Failed - S3SupportSmmExitPmAuthCallback()\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Copy S3 Support Data from Boot Services memory to SMRAM
+ ///
+ CopyMem ((VOID *)Address, mPchS3SupportSmmProtocol->DispatchArray, mPchS3SupportSmmProtocol->ProtocolSize * EFI_PAGE_SIZE);
+
+ ///
+ /// Unregister the IO Trap as the copy to SMRAM is only allowed once
+ ///
+ Status = mPchIoTrap->UnRegister (
+ mPchIoTrap,
+ &mPchIoTrapHandle
+ );
+ DEBUG ((EFI_D_INFO, "IO Trap Unregister Failed - S3SupportSmmExitPmAuthCallback()\n"));
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Clear the NextDispatchItem in the Boot Services Memory so as to cause an error
+ /// if an entity tries to use the Protocol to add more data after the copy to SMRAM.
+ ///
+ mPchS3SupportSmmProtocol->DispatchArray->NextDispatchItem = NULL;
+
+ DEBUG ((EFI_D_INFO, "S3SupportSmmExitPmAuthCallback() End\n"));
+
+ return;
+}
+
+/**
+ 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
+S3SupportSmmEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+
+ DEBUG ((EFI_D_INFO, "S3SupportSmmEntryPoint() Start\n"));
+
+ mImageHandle = NULL;
+
+ ///
+ /// Locate SmmBase protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **)&mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate the PCH S3 SMM Support protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiPchS3SupportSmmProtocolGuid, NULL, (void **)&mPchS3SupportSmmProtocol);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate the PCH Trap dispatch protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, &mPchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ PchIoTrapContext.Type = WriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = 0;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ S3SupportSmmExitPmAuthCallback,
+ &PchIoTrapContext,
+ &mPchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mPchS3SupportSmmProtocol->PchS3SupportIoTrap = PchIoTrapContext.Address;
+
+ DEBUG ((EFI_D_INFO, "Pch S3 Support IO Trap Address = 0x%x\n", PchIoTrapContext.Address));
+ DEBUG ((EFI_D_INFO, "S3SupportSmmEntryPoint() End\n"));
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.cif b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.cif
new file mode 100644
index 0000000..9bee2a2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "S3SupportSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\S3Support\Smm"
+ RefName = "S3SupportSmm"
+[files]
+"S3SupportSmm.sdl"
+"S3SupportSmm.mak"
+"S3SupportSmm.c"
+"S3SupportSmm.h"
+"S3SupportSmm.dxs"
+"S3SupportSmm.inf"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.dxs b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.dxs
new file mode 100644
index 0000000..b8218d4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.dxs
@@ -0,0 +1,46 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 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 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_PROTOCOL_DEPENDENCY (PchS3Support)
+
+
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID AND
+ EFI_PCH_S3_SUPPORT_SMM_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h
new file mode 100644
index 0000000..1ac0dc7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.h
@@ -0,0 +1,60 @@
+/** @file
+ Header file for PCH SMM Handler
+
+@copyright
+ Copyright (c) 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
+**/
+
+#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"
+
+///
+/// Driver Consumed Protocol Prototypes
+///
+#include EFI_PROTOCOL_DEPENDENCY (PchS3Support)
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (SmmSxDispatch)
+#include EFI_PROTOCOL_CONSUMER (ExitPmAuth)
+
+
+#endif
+
+/**
+ An IO Trap SMI callback to copy the DispatchArray data to SMRAM and unregister the IO Trap.
+
+ @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
+S3SupportSmmExitPmAuthCallback (
+ EFI_EVENT Event,
+ VOID *ParentImageHandle
+);
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.inf b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.inf
new file mode 100644
index 0000000..b45f322
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.inf
@@ -0,0 +1,95 @@
+## @file
+# Component description file for Pch Initialization driver
+#
+#@copyright
+# Copyright (c) 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 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 = S3SupportSmm
+FILE_GUID = BFBEDBD4-1B7E-42f5-A528-4351E860F120
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ S3SupportSmm.c
+ S3SupportSmm.h
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+[includes.common]
+ $(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/S3SupportHob
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchS3Support
+#
+# 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/Framework/Protocol
+#
+# 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)/SampleCode/Include
+
+[libraries.common]
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeHobLib
+ EdkProtocolLib
+ EfiScriptLib
+ EfiGuidLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=S3SupportSmm.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=S3SupportSmmEntryPoint
+ 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__ \
+ -D __EDKII_GLUE_DXE_HOB_LIB__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.mak b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.mak
new file mode 100644
index 0000000..c91012e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.mak
@@ -0,0 +1,94 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, 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/S3Support/Smm/S3SupportSmm.mak 1 5/21/15 3:01a Dennisliu $Revision:
+#
+# $Date: 5/21/15 3:01a $Log:
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create S3SupportSmm Driver
+#---------------------------------------------------------------------------
+EDK : S3SupportSmm
+S3SupportSmm : $(BUILD_DIR)\S3SupportSmm.mak S3SupportSmmBin
+
+
+$(BUILD_DIR)\S3SupportSmm.mak : $(S3SupportSmm_DIR)\$(@B).cif $(S3SupportSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(S3SupportSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+S3SupportSmm_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+S3SupportSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=S3SupportSmmEntryPoint"\
+ /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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+S3SupportSmm_LIB_LINKS =\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EFISCRIPTLIB) $(EFIPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(PchS3SupportCommonDxeLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+ $(EFIDRIVERLIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+
+S3SupportSmmBin: $(S3SupportSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\S3SupportSmm.mak all \
+ "MY_INCLUDES=$(S3SupportSmm_INCLUDES)"\
+ "MY_DEFINES=$(S3SupportSmm_DEFINES)"\
+ GUID=BFBEDBD4-1B7E-42f5-A528-4351E860F120\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(S3SupportSmm_DIR)\S3SupportSmm.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.sdl b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.sdl
new file mode 100644
index 0000000..1a812ec
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/S3Support/Smm/S3SupportSmm.sdl
@@ -0,0 +1,57 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, 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/S3Support/Smm/S3SupportSmm.sdl 1 5/21/15 3:01a Dennisliu $Revision:
+#
+# $Date: 5/21/15 3:01a $Log:
+#
+#*************************************************************************
+TOKEN
+ Name = "S3SupportSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable S3SupportSmm support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "S3SupportSmm_DIR"
+End
+
+MODULE
+ Help = "Includes S3SupportSmm.mak to Project"
+ File = "S3SupportSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\S3SupportSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/Sensor.asl b/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/Sensor.asl
new file mode 100644
index 0000000..3b61882
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/Sensor.asl
@@ -0,0 +1,103 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the SandyBridge *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+ //--------------------
+ // Intel Sensor Solution
+ //--------------------
+ Name (_ADR, Zero)
+ Name (_UID, One)
+
+ Method (_STA, 0, NotSerialized)
+ {
+ // check for device enabled in BIOS setup, 1 = enabled
+ If(LNotEqual(And(SDS0,0x01), 0x01)) {
+ Return (0x00) // device is disabled in BIOS setup
+ }
+
+ // check the GPIO mode select, 1 = Sensor Hub
+ // verify the Sensor Hub _HID
+ If(LAnd(LEqual(\_SB.RDGP(44), 0x01),LEqual(_HID, "INT33D1"))) {
+ Return(0xF) // device is Sensor Hub and Sensor Hub mode is selected
+ }
+
+ // check the GPIO mode select, 0 = DFU
+ // verify the DFU _HID
+ If(LAnd(LEqual(\_SB.RDGP(44), 0x00),LEqual(_HID, "INT33D7"))) {
+ Return(0xF) // device is DFU and DFU mode is selected
+ }
+
+ Return(0x00)
+ }
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x40, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C0", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {28} //Route to PIRQM
+ })
+
+ Return (SBFI)
+ }
+
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl b/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl
new file mode 100644
index 0000000..b344520
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/AcpiTables/Dsdt/SerialIoDevices.asl
@@ -0,0 +1,1527 @@
+/**************************************************************************;
+;* *;
+;* Intel Confidential *;
+;* *;
+;* Intel Corporation - ACPI Reference Code for the SandyBridge *;
+;* Family of Customer Reference Boards. *;
+;* *;
+;* *;
+;* 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 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
+--*/
+
+Scope (\_SB.PCI0)
+{
+ External(\_SB.PCI0.SDHC.WI01.PS0X, MethodObj)
+ External(\_SB.PCI0.SDHC.WI01.PS3X, MethodObj)
+ External(\_SB.PCI0.I2C1.TPD7.PS0X, MethodObj)
+ External(\_SB.PCI0.I2C1.TPD8.PS0X, MethodObj)
+
+
+} // end scope \_SB.PCI0
+
+Scope(\_SB.PCI0.I2C0)
+{
+
+ //--------------------
+ // Audio Codec device
+ // Realtek
+ //--------------------
+ Device (ACD0)
+ {
+ // I2C/I2S Audio Codec (Realtek as default)
+ Name (_ADR, 0x1C)
+ Name (_HID, "INT33CA")
+ Name (_CID, "INT33CA")
+ Name (_DDN, "Intel(R) Smart Sound Technology Audio Codec - INT33CA" )
+ Name (_UID, 1)
+
+ // Parameter values for Realtek codec
+ Name (MCLK, Zero)
+ Name (SCLK, 0x9)
+ Name (SSPM, Zero)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ I2CSerialBus(
+ 0x1C, //SlaveAddress: bus address
+ , //SlaveMode: default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ , //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C0", //ResourceSource: I2C bus controller name
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, ExclusiveAndWake, , ,) {37} //Route to PIRQx - jack detection
+ })
+
+ Name(EOD, 1)
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ Method (_SRS, 0x1, Serialized)
+ {
+ Store (1, EOD)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (LOr(LNotEqual(CODS, Zero), LNotEqual(ADSD, Zero)))
+ {
+ Return(0x0) // Codec Selection != Realtek or ADSP disabled - Not present
+ }
+ If (AND(EOD, 0x1, EOD))
+ {
+ Return(0xf) // Enabled 1111
+ }
+ Else
+ {
+ Return(0xd) // Disabled 1101
+ }
+ }
+
+ Method (_DIS, 0x0, NotSerialized)
+ {
+ Store(0, EOD)
+ }
+ } // Device (ACD0)
+
+ //--------------------
+ // Audio Codec device
+ // Cirrus Logic
+ //--------------------
+ Device (ACD1)
+ {
+ Name (_ADR, 0x4A)
+ Name (_HID, "INT33C9")
+ Name (_CID, "INT33C9")
+ Name (_DDN, "Intel(R) Smart Sound Technology Audio Codec - INT33C9" )
+ Name (_UID, 1)
+
+ // Parameter values for Cirrus codec
+ Name (MCLK, 0x6)
+ Name (SCLK, Zero)
+ Name (SSPM, One)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ I2CSerialBus(
+ 0x4A, //SlaveAddress: bus address
+ , //SlaveMode: default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ , //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C0", //ResourceSource: I2C bus controller name
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+ })
+
+ Name(EOD, 1)
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Store (1, EOD)
+ Return (RBUF)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (LOr(LNotEqual(CODS, One), LNotEqual(ADSD, Zero)))
+ {
+ Return(0x0) // Codec Selection != Cirrus or ADSP disabled - Not present
+ }
+ If (AND(EOD, 0x1, EOD))
+ {
+ Return(0xf) // Enabled 1111
+ }
+ Else
+ {
+ Return(0xd) // Disabled 1101
+ }
+ }
+
+ Method (_DIS, 0x0, NotSerialized)
+ {
+ Store(0, EOD)
+ }
+ } // Device (ACD1)
+
+ //--------------------
+ // Audio Codec device
+ // IDT
+ //--------------------
+ Device (ACD2)
+ {
+ Name (_ADR, 0x69)
+ Name (_HID, "INT33CB")
+ Name (_CID, "INT33CB")
+ Name (_DDN, "Intel(R) Smart Sound Technology Audio Codec - INT33CB" )
+ Name (_UID, 1)
+
+ // Parameter values for IDT codec
+ Name (MCLK, 0x18)
+ Name (SCLK, 0x9)
+ Name (SSPM, Zero)
+
+ Name (RBUF, ResourceTemplate ()
+ {
+ I2CSerialBus(
+ 0x69, //SlaveAddress: bus address
+ , //SlaveMode: default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ , //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C0", //ResourceSource: I2C bus controller name
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionInputOnly, "\\_SB.PCI0.GPI0", ) {0x33} // GPIO51 for HP detection
+ GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionInputOnly, "\\_SB.PCI0.GPI0", ) {0x35} // GPIO53 for Mic detection
+
+ Interrupt(ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, , ,) {35} // GPIO51 - HP jack detection
+ Interrupt(ResourceConsumer, Edge, ActiveHigh, ExclusiveAndWake, , ,) {37} // GPIO53 - Mic jack detection
+ })
+
+ Name(EOD, 1)
+ Method (_CRS, 0x0, NotSerialized)
+ {
+ Return (RBUF)
+ }
+
+ Method (_SRS, 0x1, Serialized)
+ {
+ Store (1, EOD)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If (LOr(LNotEqual(CODS, 2), LNotEqual(ADSD, Zero)))
+ {
+ Return(0x0) // Codec Selection != IDT or ADSP disabled - Not present
+ }
+ If (AND(EOD, 0x1, EOD))
+ {
+ Return(0xf) // Enabled 1111
+ }
+ Else
+ {
+ Return(0xd) // Disabled 1101
+ }
+ }
+
+ Method (_DIS, 0x0, NotSerialized)
+ {
+ Store(0, EOD)
+ }
+ } // Device (ACD2)
+
+ //--------------------
+ // Intel Sensor Hub
+ //--------------------
+ Device (SHUB)
+ {
+ Name (_HID, "INT33D1")
+ Name (_CID, "PNP0C50")
+ Include ("Sensor.asl")
+ } // Device (SHUB)
+
+ //--------------------
+ // Intel DFU Device
+ //--------------------
+ Device (DFUD)
+ {
+ Name (_HID, "INT33D7")
+ Include ("Sensor.asl")
+ } // Device DFUD
+
+ Device (TPD4)
+ {
+ Name (_ADR, Zero)
+ Name (_HID, "MSFT1111")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS0,0x04), 0x04)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x60, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C0", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {28} //Route to PIRQM
+ })
+
+ Return (SBFI)
+ }
+
+ Method (_PRW, 0) {
+ Return(Package(){0x0E,4}) // can wakeup from S4 state
+ }
+
+ Method (_S3W, 0) {
+ Return(3)
+ }
+
+ Method (_S4W, 0) {
+ Return(3)
+ }
+
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("TPD4 Ctrlr D0")
+ //
+ // Set GPI_INV to normal
+ //
+ \_SB.WTIN(14,0)
+
+ //
+ // Set GPI_OWN to GPIO
+ //
+ Store(1,\GO14)
+ }
+
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("TPD4 Ctrlr D3")
+ //
+ // Set GPI_INV to Inverted
+ //
+ \_SB.WTIN(14,1)
+
+ //
+ // Set GPI_OWN to ACPI
+ //
+ Store(0,\GO14)
+ }
+ } // Device (TPD4)
+
+
+} // end Scope(\_SB.PCI0.I2C0)
+
+
+ //----------------------------
+ // Serial IO I2C1 Controller
+ //----------------------------
+Scope(\_SB.PCI0.I2C1)
+{
+
+
+ //------------------------
+ // Atmel Touch Panel
+ //------------------------
+ Device (TPL0)
+ {
+ Name (_ADR, Zero)
+ Name (_HID, "ATML1000")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0000)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ // Note: _STA in ATML1000 and ATML2000 must be identical. These devices
+ // communicate with the same HW.
+
+ If(LEqual(And(SDS1,0x0001), 0x0001)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x4C, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {34} //Interrupt from touch screen routed to GPIO50-->PIRQS
+ })
+
+ Return (SBFI)
+ }
+ } // Device (TPL0)
+
+ //------------------------
+ // Atmel Touch Panel FW Update
+ //------------------------
+ Device (TPFU)
+ {
+ Name (_ADR, Zero)
+ Name (_HID, "ATML2000")
+ Name (_CID, "PNP0C02")
+ Name (_UID, 10)
+
+ Method (_STA, 0, NotSerialized)
+ {
+ // Note: _STA in ATML1000 and ATML2000 must be identical. These devices
+ // communicate with the same HW.
+
+ If(LAnd(And(SDS1,0x0001),And(APFU,0x0001))) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x26, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ I2cSerialBus (
+ 0x27, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+ })
+
+ Return (SBFI)
+ }
+ } // Device (TPFU)
+
+ //------------------------
+ // ELAN Touch Panel
+ //------------------------
+ Device (TPL1)
+ {
+ Name (_HID, "ELAN1001")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0002), 0x0002)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x10, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {34} //Interrupt from touch screen routed to GPIO50-->PIRQS
+ })
+
+ Return (SBFI)
+ }
+ } // Device (TPL1)
+
+
+ //------------------------------
+ // NTRIG Digitizer Touch Panel
+ //------------------------------
+ Device (TPL2)
+ {
+ Name (_ADR, One)
+ Name (_HID, "NTRG0001")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0020), 0x0020)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x07, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {34} //Interrupt from touch screen routed to GPIO50-->PIRQS
+ })
+
+ Return (SBFI)
+
+ }
+ } // Device (TPL2)
+
+ //------------------------
+ // EETI Touch Panel
+ //------------------------
+ Device (TPL3)
+ {
+ Name (_ADR, One)
+ Name (_HID, "EETI7900")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x000F)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0040), 0x0040)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x2A, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,) {34} //Interrupt from touch screen routed to GPIO50-->PIRQS
+ })
+
+
+ Return (SBFI)
+
+ }
+ } // Device (TPL3)
+
+
+ //------------------------
+ // ELAN Touch Pad
+ //------------------------
+ Device (TPD0)
+ {
+ Name (_ADR, One)
+ Name (_HID, "ELAN1000")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0004), 0x0004)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x15, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3)
+ }
+
+ Return (SBFI)
+
+
+ }
+ } // Device (TPD0)
+
+ //------------------------
+ // Synaptics touchpad
+ //------------------------
+ Device (TPD1)
+ {
+ Name (_ADR, One)
+ Name (_HID, "MSFT0001")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0020)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0008), 0x0008)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x20, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3)
+ }
+
+ Return (SBFI)
+ }
+ } // Device (TPD1)
+
+ //------------------------
+ // Alps touchpad
+ //------------------------
+ Device (TPD2)
+ {
+ Name (_ADR, One)
+ Name (_HID, "ALP0001")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0080), 0x0080)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x2A, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3)
+ }
+
+ Return (SBFI)
+ }
+ } // Device (TPD2)
+
+ //------------------------
+ // Cypress touchpad
+ //------------------------
+ Device (TPD3)
+ {
+ Name (_ADR, One)
+ Name (_HID, "CYP0001")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 4) // required to put the device to D3 Cold during S0 idle
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0100), 0x0100)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x24, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, Exclusive, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3)
+ }
+
+ Return (SBFI)
+ }
+ } // Device (TPD3)
+
+ //------------------------
+ // ELAN Precision Touch Pad
+ //------------------------
+ Device (TPD7)
+ {
+ Name (_ADR, One)
+ Name (_HID, "ELAN1010")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 3) // PTP will be in D3hot during CS, and wake capable
+
+ Method (_S3W, 0) {
+ If(LEqual(S0ID, 0)) {
+ Return (3)
+ } Else {
+ Return (0)
+ }
+ }
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0001)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ // Get the right SDS value
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x0800), 0x0800)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x15, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, ExclusiveAndWake, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3)
+
+ If(LEqual(S0ID, 0)) {
+ CreateByteField (SBFI, INT0._SHR, VAL4) // Change to exclusive
+ And(VAL4, 0xE7, VAL4) //Exclusive
+ }
+ }
+
+ Return (SBFI)
+
+
+ }
+
+ Method (_PRW, 0) {
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ Return(Package(){0x0D, 3}) // can wakeup from S4 state
+ }
+ Return(Package(){Zero, Zero})
+ }
+
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("TPD7 Ctrlr D0")
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ \_SB.WTIN(13, 0) // Set GPI_INV to normal
+ Store(1, \GO13) // Set GPI_OWN to GPIO
+ }
+
+ If(CondRefOf(\_SB.PCI0.I2C1.TPD7.PS0X))
+ {
+ \_SB.PCI0.I2C1.TPD7.PS0X()
+ }
+ }
+
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("TPD7 Ctrlr D3")
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ \_SB.WTIN(13, 1) // Set GPI_INV to Inverted
+ Store(0, \GO13) // Set GPI_OWN to ACPI
+ }
+ }
+ } // Device (TPD7)
+
+ //------------------------
+ // Synaptics Precision touchpad
+ //------------------------
+ Device (TPD8)
+ {
+ Name (_ADR, One)
+ Name (_HID, "SYNA2393")
+ Name (_CID, "PNP0C50")
+ Name (_UID, One)
+
+ Name (_S0W, 3) // PTP will be in D3hot during CS, and wake capable
+
+ Method (_S3W, 0) {
+ If(LEqual(S0ID, 0)) {
+ Return (3)
+ } Else {
+ Return (0)
+ }
+ }
+
+ Method(_DSM, 0x4, NotSerialized)
+ {
+ // DSM UUID for HIDI2C. Do Not change.
+ If(LEqual(Arg0, ToUUID("3CDFF6F7-4267-4555-AD05-B30A3D8938DE")))
+ {
+ // Function 0 : Query Function
+ If(LEqual(Arg2, Zero))
+ {
+ // Revision 1
+ If(LEqual(Arg1, One))
+ {
+ Return(Buffer(One) { 0x03 })
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+ // Function 1 : HID Function
+ If(LEqual(Arg2, One))
+ {
+ // HID Descriptor Address (IHV Specific)
+ Return(0x0020)
+ }
+ }
+ Else
+ {
+ Return(Buffer(One) { 0x00 })
+ }
+ }
+
+ // Get the right SDS value
+ Method (_STA, 0, NotSerialized)
+ {
+ If(LEqual(And(SDS1,0x1000), 0x1000)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+
+ Method (_CRS, 0, Serialized)
+ {
+ Name (SBFI, ResourceTemplate ()
+ {
+ I2cSerialBus (
+ 0x20, //SlaveAddress: bus address
+ ControllerInitiated, //SlaveMode: Default to ControllerInitiated
+ 400000, //ConnectionSpeed: in Hz
+ AddressingMode7Bit, //Addressing Mode: default to 7 bit
+ "\\_SB.PCI0.I2C1", //ResourceSource: I2C bus controller name
+ , //ResourceSourceIndex: defaults to 0
+ , //ResourceUsage: Defaults to ResourceConsumer
+ , //Descriptor Name: creates name for offset of resource descriptor
+ ) //VendorData
+
+ Interrupt(ResourceConsumer, Level, ActiveLow, ExclusiveAndWake, , ,INT0) {39} //Interrupt from Touchpad routed to GPIO55 - IOxAPIC PIRQX
+ })
+
+ If(LEqual(GR13, 1)) {
+ CreateByteField (SBFI, INT0._INT, VAL3) // Extended Interrupt Descriptor
+ Store(27, VAL3) //PIRQ
+
+ If(LEqual(S0ID, 0)) {
+ CreateByteField (SBFI, INT0._SHR, VAL4) // Change to exclusive
+ And(VAL4, 0xE7, VAL4) //Exclusive
+ }
+ }
+
+ Return (SBFI)
+ }
+
+ Method (_PRW, 0) {
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ Return(Package(){0x0D,3}) // can wakeup from S4 state
+ }
+ Return(Package(){Zero, Zero})
+ }
+
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("TPD8 Ctrlr D0")
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ \_SB.WTIN(13, 0) // Set GPI_INV to normal
+ Store(1, \GO13) // Set GPI_OWN to GPIO
+ }
+
+ If(CondRefOf(\_SB.PCI0.I2C1.TPD8.PS0X))
+ {
+ \_SB.PCI0.I2C1.TPD8.PS0X()
+ }
+ }
+
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("TPD8 Ctrlr D3")
+ If(LAnd(LEqual(S0ID, 0),LEqual(GR13, 1))) {
+ \_SB.WTIN(13, 1) // Set GPI_INV to Inverted
+ Store(0, \GO13) // Set GPI_OWN to ACPI
+ }
+ }
+ } // Device (TPD8)
+ } // Device (I2C1)
+
+ //----------------------------
+ // Serial IO SPI0 Controller
+ //----------------------------
+Scope(\_SB.PCI0.SPI0)
+{
+
+
+} // end Scope(\_SB.PCI0.SPI0)
+
+ //----------------------------
+ // Serial IO SPI1 Controller
+ //----------------------------
+Scope(\_SB.PCI0.SPI1)
+{
+
+} // end Scope(\_SB.PCI0.SPI1)
+
+ //-----------------------------
+ // Serial IO UART0 Controller
+ //-----------------------------
+Scope(\_SB.PCI0.UA00)
+{
+
+ //
+ // Bluetooth controller using serial interface
+ //
+ Device(BTH0)
+ {
+ Name(_HID, "INT33E0")
+
+ Method(_CRS, 0x0, NotSerialized)
+ {
+ Name(UBUF, ResourceTemplate ()
+ {
+ UARTSerialBus(
+ 115200, //InitialBaudRate: in bits per second
+ DataBitsEight, //BitsPerByte: default to DataBitsEight (optional)
+ StopBitsOne, //StopBits: defaults to StopBitsOne (optional)
+ 0xc0, //LinesInUse: 8 1-bit flags to declare line enabled
+ , //IsBigEndian: default to LittleEndian (optional)
+ ParityTypeNone, //Parity: defaults to ParityTypeNone (optional)
+ FlowControlHardware, //FlowControl: defaults to FlowControlNone (optional)
+ 32, //ReceiveBufferSize
+ 32, //TransmitBufferSize
+ "\\_SB.PCI0.UA00", //ResourceSource: UART bus controller name
+ , //ResourceSourceIndex: defaults to 0 (optional)
+ , //ResourceUsage: defaults to ResourceConsumer (optional)
+ , //DescriptorName: creates name for offset of resource descriptor
+ ) //VendorData
+ })
+
+ Return (UBUF)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(And(SDS4,0x01), 0x01)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+ } // Device BTH0
+
+ } // end Scope(\_SB.PCI0.UART0)
+
+ //-----------------------------
+ // Serial IO UART1 Controller
+ //-----------------------------
+Scope(\_SB.PCI0.UA01)
+ {
+
+ //
+ // Bluetooth controller using serial interface
+ //
+ Device(BTH1)
+ {
+ Name(_HID, "INT33E0")
+
+ Method(_CRS, 0x0, NotSerialized)
+ {
+ Name(UBUF, ResourceTemplate ()
+ {
+ UARTSerialBus(
+ 115200, //InitialBaudRate: in bits per second
+ DataBitsEight, //BitsPerByte: default to DataBitsEight (optional)
+ StopBitsOne, //StopBits: defaults to StopBitsOne (optional)
+ 0xc0, //LinesInUse: 8 1-bit flags to declare line enabled
+ , //IsBigEndian: default to LittleEndian (optional)
+ ParityTypeNone, //Parity: defaults to ParityTypeNone (optional)
+ FlowControlHardware, //FlowControl: defaults to FlowControlNone (optional)
+ 32, //ReceiveBufferSize
+ 32, //TransmitBufferSize
+ "\\_SB.PCI0.UA01", //ResourceSource: UART bus controller name
+ , //ResourceSourceIndex: defaults to 0 (optional)
+ , //ResourceUsage: defaults to ResourceConsumer (optional)
+ , //DescriptorName: creates name for offset of resource descriptor
+ ) //VendorData
+ Interrupt(ResourceConsumer, Level, ActiveLow, SharedAndWake, , , ) {25} // GPIO9 - PIRQ J(APIC pin 25) for BT Wake
+ GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0", ) {87} // for RF Kill
+ })
+
+ Return (UBUF)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(And(SDS5,0x01), 0x01)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+ } // Device BTH1
+
+ //
+ // BroadCom Bluetooth controller using serial interface
+ //
+ Device(BTH2)
+ {
+ Method(_HID, 0, NotSerialized) {
+ if (LEqual(BCV4, 0)) {
+ Return("BCM2E20")
+ } else {
+ Return("BCM2E40")
+ }
+ }
+
+ Method(_CRS, 0x0, NotSerialized)
+ {
+ Name(UBUF, ResourceTemplate ()
+ {
+ UARTSerialBus(
+ 115200, //InitialBaudRate: in bits per second
+ , //BitsPerByte: default to DataBitsEight (optional)
+ , //StopBits: defaults to StopBitsOne (optional)
+ 0xc0, //LinesInUse: 8 1-bit flags to declare line enabled
+ , //IsBigEndian: default to LittleEndian (optional)
+ , //Parity: defaults to ParityTypeNone (optional)
+ FlowControlHardware, //FlowControl: defaults to FlowControlNone (optional)
+ 32, //ReceiveBufferSize
+ 32, //TransmitBufferSize
+ "\\_SB.PCI0.UA01", //ResourceSource: UART bus controller name
+ , //ResourceSourceIndex: defaults to 0 (optional)
+ , //ResourceUsage: defaults to ResourceConsumer (optional)
+ , //DescriptorName: creates name for offset of resource descriptor
+ ) //VendorData
+ Interrupt(ResourceConsumer, Edge, ActiveLow, Exclusive, , , ) {25} // GPIO9 - PIRQ J(APIC pin 25) for BT Wake
+ GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0", ) {57} // for BT_DEV_WAKE
+ GpioIo(Exclusive, PullDefault, 0, 0, IoRestrictionOutputOnly, "\\_SB.PCI0.GPI0", ) {87} // for RF Kill
+ })
+ Return (UBUF)
+ }
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ If(LEqual(And(SDS5,0x02), 0x02)) {
+ Return (0x0F)
+ } Else {
+ Return (0x00)
+ }
+ }
+ Name (_S0W, 2) // required to put the device to D2 during S0 idle
+ } // Device BTH2
+
+
+ } // end Scope(\_SB.PCI0.UART1)
+
+ //--------------------------------
+ // Serial IO SDIO Host Controller
+ //--------------------------------
+Scope(\_SB.PCI0.SDHC)
+{
+
+ Device (WI01)
+ {
+ Name (_ADR, 1)
+ Name (_DDN, "SDIO Wifi device Function 1" )
+
+ Method (_STA, 0x0, NotSerialized)
+ {
+ Return (0x0F)
+ }
+
+ Method (_RMV, 0, NotSerialized)
+ {
+ Return (0x0)
+ }
+
+ Name (_S4W, 2) // required per guidance from MS (SDIO Wifi device power states doc)
+ Name (_S0W, 2) // required to put the Wifi device to D2 during S0 idle
+ // D0 Method for WiFi
+ Method(_PS0,0,Serialized)
+ {
+ ADBG("WiFi1 Enter D0")
+ If(CondRefOf(\_SB.PCI0.SDHC.WI01.PS0X))
+ {
+ \_SB.PCI0.SDHC.WI01.PS0X()
+ }
+ }
+ // D2 Method for WiFi
+ Method(_PS2,0,Serialized)
+ {
+ ADBG("WiFi1 Enter D2")
+ }
+ // D3 Method for WiFi
+ Method(_PS3,0,Serialized)
+ {
+ ADBG("WiFi1 Enter D3")
+ If(CondRefOf(\_SB.PCI0.SDHC.WI01.PS3X))
+ {
+ \_SB.PCI0.SDHC.WI01.PS3X()
+ }
+ }
+ //Method(_DSW, 3){
+ //ADBG("Wifi1 _DSW")
+ //}
+ //
+ Name (RBUF, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadWrite, 0x00000000, 0x0000000, BARC) // SW LTR Registers
+ Interrupt(ResourceConsumer, Level, ActiveLow, SharedAndWake, , , ) {38}
+ })
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ CreateDWordField(^^RBUF, ^^BARA._BAS, AVAL)
+ if(LNotEqual(AVAL, 0)) {
+ CreateDWordField(^RBUF, ^BARC._LEN, WLN0)
+ Store(0xC, WLN0)
+ CreateDWordField(^RBUF, ^BARC._BAS, WVAL)
+ Add(AVAL, 0x1008, WVAL)
+ }
+ Return (RBUF)
+ }
+ }
+} // end Scope(\_SB.PCI0.SDHC)
+
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c
new file mode 100644
index 0000000..020f152
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.c
@@ -0,0 +1,188 @@
+/** @file
+ PCH BIOS Write Protect 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 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
+**/
+#include "PchBiosWriteProtect.h"
+
+///
+/// Global variables
+///
+EFI_SMM_ICHN_DISPATCH_PROTOCOL *mIchnDispatch;
+EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL *mPchIoTrap;
+UINTN mPciD31F0RegBase;
+
+/**
+ This hardware SMI handler will be run every time the BIOS Write Enable bit is set.
+
+ @param[in] DispatchHandle Not used
+ @param[in] DispatchContext Not used
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchBiosWpCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ ///
+ /// Disable BIOSWE bit to protect BIOS
+ ///
+ MmioAnd8 ((UINTN) (mPciD31F0RegBase + R_PCH_LPC_BIOS_CNTL), (UINT8) ~B_PCH_LPC_BIOS_CNTL_BIOSWE);
+}
+
+/**
+ Register an IchnBiosWp callback function to handle TCO BIOSWR SMI
+ SMM_BWP and BLE bits will be set here
+
+ @param[in] DispatchHandle Not used
+ @param[in] CallbackContext Information about the IO trap that occurred
+
+ @retval None
+**/
+VOID
+EFIAPI
+PchBiosLockIoTrapCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_IO_TRAP_DISPATCH_CALLBACK_CONTEXT *CallbackContext
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext;
+ EFI_HANDLE IchnHandle;
+
+ ///
+ /// Do not run the callback function if it is not Write cycle trapped or the wrtie data
+ /// is not PCH_BWP_SIGNATURE,
+ ///
+ if ((CallbackContext->Type != WriteTrap) || (CallbackContext->WriteData != PCH_BWP_SIGNATURE)) {
+ return;
+ }
+
+ if (mIchnDispatch == NULL) {
+ return;
+ }
+
+ IchnHandle = NULL;
+
+ ///
+ /// Set SMM_BWP bit before registering IchnBiosWp
+ ///
+ MmioOr8 ((UINTN) (mPciD31F0RegBase + R_PCH_LPC_BIOS_CNTL), (UINT8) B_PCH_LPC_BIOS_CNTL_SMM_BWP);
+
+ ///
+ /// Register an IchnBiosWp callback function to handle TCO BIOSWR SMI
+ ///
+ IchnContext.Type = IchnBiosWp;
+ Status = mIchnDispatch->Register (
+ mIchnDispatch,
+ PchBiosWpCallback,
+ &IchnContext,
+ &IchnHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+/**
+ Entry point for Pch Bios Write Protect driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchBiosWriteProtect (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ EFI_HANDLE PchIoTrapHandle;
+ EFI_SMM_IO_TRAP_DISPATCH_REGISTER_CONTEXT PchIoTrapContext;
+
+ ///
+ /// Locate PCH Platform Policy protocol
+ ///
+ Status = gBS->LocateProtocol (&gDxePchPlatformPolicyProtocolGuid, NULL, (VOID **) &PchPlatformPolicy);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Failed to locate PCH Policy protocol.\n"));
+ return Status;
+ }
+
+ if ((PchPlatformPolicy->LockDownConfig->BiosLock == PCH_DEVICE_ENABLE)) {
+ mPciD31F0RegBase = MmPciAddress (
+ 0,
+ 0,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+
+ ///
+ /// Get the ICHn protocol
+ ///
+ mIchnDispatch = NULL;
+ Status = gBS->LocateProtocol (&gEfiSmmIchnDispatchProtocolGuid, NULL, (VOID **) &mIchnDispatch);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Locate the PCH IO TRAP Dispatch protocol
+ ///
+ PchIoTrapHandle = NULL;
+ Status = gBS->LocateProtocol (&gEfiSmmIoTrapDispatchProtocolGuid, NULL, (VOID **) &mPchIoTrap);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Register BIOS Lock IO Trap SMI handler
+ ///
+ PchIoTrapContext.Type = WriteTrap;
+ PchIoTrapContext.Length = 4;
+ PchIoTrapContext.Address = PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress;
+ PchIoTrapContext.Context = NULL;
+ PchIoTrapContext.MergeDisable = FALSE;
+ Status = mPchIoTrap->Register (
+ mPchIoTrap,
+ PchBiosLockIoTrapCallback,
+ &PchIoTrapContext,
+ &PchIoTrapHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_ERROR, "PchBiosLockIoTrapAddress = 0x%x\n", PchIoTrapContext.Address));
+
+ if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress == 0) &&
+ (PchIoTrapContext.Address == 0)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Invalid PchIoTrapContext.Address!!!\n"));
+ ASSERT (FALSE);
+ } else {
+ if ((PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != 0) &&
+ (PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress != PchIoTrapContext.Address)) {
+ DEBUG ((EFI_D_ERROR | EFI_D_INFO, "Invalid PchIoTrapContext.Address!!!\n"));
+ ASSERT (FALSE);
+ } else {
+ PchPlatformPolicy->LockDownConfig->PchBiosLockIoTrapAddress = PchIoTrapContext.Address;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.dxs b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.dxs
new file mode 100644
index 0000000..47c8ea9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.dxs
@@ -0,0 +1,48 @@
+/** @file
+ Dependency expression source file.
+
+@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 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 (PchPlatformPolicy)
+#include EFI_PROTOCOL_DEFINITION (SmmBase)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIchnDispatch)
+#include EFI_PROTOCOL_DEPENDENCY (SmmIoTrapDispatch)
+
+#endif
+
+DEPENDENCY_START
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL_GUID AND
+ EFI_SMM_IO_TRAP_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.h
new file mode 100644
index 0000000..fedc210
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.h
@@ -0,0 +1,36 @@
+/** @file
+ Header file for the Pch Bios Write Protect 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 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
+**/
+#ifndef _PCH_BIOS_WRITE_PROTECT_H_
+#define _PCH_BIOS_WRITE_PROTECT_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+
+//
+// Driver Dependency Protocols
+//
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include EFI_PROTOCOL_CONSUMER (SmmBase)
+#include EFI_PROTOCOL_CONSUMER (SmmIchnDispatch)
+#include EFI_PROTOCOL_CONSUMER (SmmIoTrapDispatch)
+#endif
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.inf b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.inf
new file mode 100644
index 0000000..552d188
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/BiosWriteProtect/Smm/PchBiosWriteProtect.inf
@@ -0,0 +1,94 @@
+## @file
+# Component description file for the PchBiosWriteProtect 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 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 = PchBiosWriteProtect
+FILE_GUID = 2EE81ACB-64B2-41ae-8635-7030D16C4AA8
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchBiosWriteProtect.h
+ PchBiosWriteProtect.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchBiosWriteProtect.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchBiosWriteProtect
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Guid/SmbusArpMap/SmbusArpMap.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Guid/SmbusArpMap/SmbusArpMap.h
new file mode 100644
index 0000000..32f4ee0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Guid/SmbusArpMap/SmbusArpMap.h
@@ -0,0 +1,29 @@
+/** @file
+ GUID for use in describing SMBus devices that were ARPed during PEI.
+
+@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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#ifndef _EFI_SMBUS_ARP_MAP_GUID_H_
+#define _EFI_SMBUS_ARP_MAP_GUID_H_
+
+#define EFI_SMBUS_ARP_MAP_GUID \
+ { \
+ 0x707be83e, 0x0bf6, 0x40a5, 0xbe, 0x64, 0x34, 0xc0, 0x3a, 0xa0, 0xb8, 0xe2 \
+ }
+
+extern EFI_GUID gEfiSmbusArpMapGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h
new file mode 100644
index 0000000..cc5111b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/Acpi3_0.h
@@ -0,0 +1,681 @@
+/** @file
+ ACPI 3.0 definitions from the ACPI Specification Revision 3.0 September 2, 2004
+
+@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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#ifndef _ACPI_3_0_H_
+#define _ACPI_3_0_H_
+
+//
+// Statements that include other files
+//
+#include "Tiano.h"
+#include "Acpi.h"
+
+//
+// Ensure proper structure formats
+//
+#pragma pack(1)
+//
+// ACPI Specification Revision
+//
+#define EFI_ACPI_3_0_REVISION 0x03 // @bug: Not in spec yet.
+//
+// @bug: OEM values need to be moved somewhere else, probably read from data hub
+// and produced by a platform specific driver.
+//
+//
+// ACPI 3.0 Generic Address Space definition
+//
+typedef struct {
+ UINT8 AddressSpaceId;
+ UINT8 RegisterBitWidth;
+ UINT8 RegisterBitOffset;
+ UINT8 AccessSize;
+ UINT64 Address;
+} EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE;
+
+//
+// Generic Address Space Address IDs
+//
+#define EFI_ACPI_3_0_SYSTEM_MEMORY 0
+#define EFI_ACPI_3_0_SYSTEM_IO 1
+#define EFI_ACPI_3_0_PCI_CONFIGURATION_SPACE 2
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER 3
+#define EFI_ACPI_3_0_SMBUS 4
+#define EFI_ACPI_3_0_FUNCTIONAL_FIXED_HARDWARE 0x7F
+
+//
+// Generic Address Space Access Sizes
+//
+#define EFI_ACPI_3_0_UNDEFINED 0
+#define EFI_ACPI_3_0_BYTE 1
+#define EFI_ACPI_3_0_WORD 2
+#define EFI_ACPI_3_0_DWORD 3
+#define EFI_ACPI_3_0_QWORD 4
+
+//
+// ACPI 3.0 table structures
+//
+//
+// Root System Description Pointer Structure
+//
+typedef struct {
+ UINT64 Signature;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT8 Revision;
+ UINT32 RsdtAddress;
+ UINT32 Length;
+ UINT64 XsdtAddress;
+ UINT8 ExtendedChecksum;
+ UINT8 Reserved[3];
+} EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER;
+
+//
+// RSD_PTR Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION 0x02 // ACPISpec30 (Revision 3.0 September 2, 2004) says current value is 2
+//
+// Common table header, this prefaces all ACPI tables, including FACS, but
+// excluding the RSD PTR structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+} EFI_ACPI_3_0_COMMON_HEADER;
+
+//
+// Root System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT32 table pointers.
+//
+//
+// RSDT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Extended System Description Table
+// No definition needed as it is a common description table header followed by a
+// variable number of UINT64 table pointers.
+//
+//
+// XSDT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Fixed ACPI Description Table Structure (FADT)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 FirmwareCtrl;
+ UINT32 Dsdt;
+ UINT8 Reserved0;
+ UINT8 PreferredPmProfile;
+ UINT16 SciInt;
+ UINT32 SmiCmd;
+ UINT8 AcpiEnable;
+ UINT8 AcpiDisable;
+ UINT8 S4BiosReq;
+ UINT8 PstateCnt;
+ UINT32 Pm1aEvtBlk;
+ UINT32 Pm1bEvtBlk;
+ UINT32 Pm1aCntBlk;
+ UINT32 Pm1bCntBlk;
+ UINT32 Pm2CntBlk;
+ UINT32 PmTmrBlk;
+ UINT32 Gpe0Blk;
+ UINT32 Gpe1Blk;
+ UINT8 Pm1EvtLen;
+ UINT8 Pm1CntLen;
+ UINT8 Pm2CntLen;
+ UINT8 PmTmrLen;
+ UINT8 Gpe0BlkLen;
+ UINT8 Gpe1BlkLen;
+ UINT8 Gpe1Base;
+ UINT8 CstCnt;
+ UINT16 PLvl2Lat;
+ UINT16 PLvl3Lat;
+ UINT16 FlushSize;
+ UINT16 FlushStride;
+ UINT8 DutyOffset;
+ UINT8 DutyWidth;
+ UINT8 DayAlrm;
+ UINT8 MonAlrm;
+ UINT8 Century;
+ UINT16 IaPcBootArch;
+ UINT8 Reserved1;
+ UINT32 Flags;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE ResetReg;
+ UINT8 ResetValue;
+ UINT8 Reserved2[3];
+ UINT64 XFirmwareCtrl;
+ UINT64 XDsdt;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm1bCntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPm2CntBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XPmTmrBlk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe0Blk;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE XGpe1Blk;
+} EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE;
+
+//
+// FADT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION 0x04
+
+//
+// Fixed ACPI Description Table Preferred Power Management Profile
+//
+#define EFI_ACPI_3_0_PM_PROFILE_UNSPECIFIED 0
+#define EFI_ACPI_3_0_PM_PROFILE_DESKTOP 1
+#define EFI_ACPI_3_0_PM_PROFILE_MOBILE 2
+#define EFI_ACPI_3_0_PM_PROFILE_WORKSTATION 3
+#define EFI_ACPI_3_0_PM_PROFILE_ENTERPRISE_SERVER 4
+#define EFI_ACPI_3_0_PM_PROFILE_SOHO_SERVER 5
+#define EFI_ACPI_3_0_PM_PROFILE_APPLIANCE_PC 6
+#define EFI_ACPI_3_0_PM_PROFILE_PERFORMANCE_SERVER 7
+
+//
+// Fixed ACPI Description Table Boot Architecture Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_LEGACY_DEVICES (1 << 0)
+#define EFI_ACPI_3_0_8042 (1 << 1)
+#define EFI_ACPI_3_0_VGA_NOT_PRESENT (1 << 2)
+
+//
+// Fixed ACPI Description Table Fixed Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_WBINVD (1 << 0)
+#define EFI_ACPI_3_0_WBINVD_FLUSH (1 << 1)
+#define EFI_ACPI_3_0_PROC_C1 (1 << 2)
+#define EFI_ACPI_3_0_P_LVL2_UP (1 << 3)
+#define EFI_ACPI_3_0_PWR_BUTTON (1 << 4)
+#define EFI_ACPI_3_0_SLP_BUTTON (1 << 5)
+#define EFI_ACPI_3_0_FIX_RTC (1 << 6)
+#define EFI_ACPI_3_0_RTC_S4 (1 << 7)
+#define EFI_ACPI_3_0_TMR_VAL_EXT (1 << 8)
+#define EFI_ACPI_3_0_DCK_CAP (1 << 9)
+#define EFI_ACPI_3_0_RESET_REG_SUP (1 << 10)
+#define EFI_ACPI_3_0_SEALED_CASE (1 << 11)
+#define EFI_ACPI_3_0_HEADLESS (1 << 12)
+#define EFI_ACPI_3_0_CPU_SW_SLP (1 << 13)
+#define EFI_ACPI_3_0_PCI_EXP_WAK (1 << 14)
+#define EFI_ACPI_3_0_USE_PLATFORM_CLOCK (1 << 15)
+#define EFI_ACPI_3_0_S4_RTC_STS_VALID (1 << 16)
+#define EFI_ACPI_3_0_REMOTE_POWER_ON_CAPABLE (1 << 17)
+#define EFI_ACPI_3_0_FORCE_APIC_CLUSTER_MODEL (1 << 18)
+#define EFI_ACPI_3_0_FORCE_APIC_PHYSICAL_DESTINATION_MODE (1 << 19)
+
+//
+// Firmware ACPI Control Structure
+//
+typedef struct {
+ UINT32 Signature;
+ UINT32 Length;
+ UINT32 HardwareSignature;
+ UINT32 FirmwareWakingVector;
+ UINT32 GlobalLock;
+ UINT32 Flags;
+ UINT64 XFirmwareWakingVector;
+ UINT8 Version;
+ UINT8 Reserved[31];
+} EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE;
+
+//
+// FACS Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_VERSION 0x01
+
+//
+// Firmware Control Structure Feature Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_S4BIOS_F (1 << 0)
+
+//
+// Differentiated System Description Table,
+// Secondary System Description Table
+// and Persistent System Description Table,
+// no definition needed as they are common description table header followed by a
+// definition block.
+//
+#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02
+#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_REVISION 0x02
+
+//
+// Multiple APIC Description Table header definition. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 LocalApicAddress;
+ UINT32 Flags;
+} EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER;
+
+//
+// MADT Revision (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION 0x02
+
+//
+// Multiple APIC Flags
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_PCAT_COMPAT (1 << 0)
+
+//
+// Multiple APIC Description Table APIC structure types
+// All other values between 0x09 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC 0x00
+#define EFI_ACPI_3_0_IO_APIC 0x01
+#define EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE 0x02
+#define EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE 0x03
+#define EFI_ACPI_3_0_LOCAL_APIC_NMI 0x04
+#define EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE 0x05
+#define EFI_ACPI_3_0_IO_SAPIC 0x06
+#define EFI_ACPI_3_0_LOCAL_SAPIC 0x07
+#define EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES 0x08
+
+//
+// APIC Structure Definitions
+//
+//
+// Processor Local APIC Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 ApicId;
+ UINT32 Flags;
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_STRUCTURE;
+
+//
+// Local APIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_LOCAL_APIC_ENABLED (1 << 0)
+
+//
+// IO APIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 IoApicAddress;
+ UINT32 GlobalSystemInterruptBase;
+} EFI_ACPI_3_0_IO_APIC_STRUCTURE;
+
+//
+// Interrupt Source Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 Bus;
+ UINT8 Source;
+ UINT32 GlobalSystemInterrupt;
+ UINT16 Flags;
+} EFI_ACPI_3_0_INTERRUPT_SOURCE_OVERRIDE_STRUCTURE;
+
+//
+// Platform Interrupt Sources Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT8 InterruptType;
+ UINT8 ProcessorId;
+ UINT8 ProcessorEid;
+ UINT8 IoSapicVector;
+ UINT32 GlobalSystemInterrupt;
+ UINT32 PlatformInterruptSourceFlags;
+ UINT8 CpeiProcessorOverride;
+ UINT8 Reserved[31];
+} EFI_ACPI_3_0_PLATFORM_INTERRUPT_APIC_STRUCTURE;
+
+//
+// MPS INTI flags.
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_POLARITY (3 << 0)
+#define EFI_ACPI_3_0_TRIGGER_MODE (3 << 2)
+
+//
+// Non-Maskable Interrupt Source Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT32 GlobalSystemInterrupt;
+} EFI_ACPI_3_0_NON_MASKABLE_INTERRUPT_SOURCE_STRUCTURE;
+
+//
+// Local APIC NMI Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT16 Flags;
+ UINT8 LocalApicLint;
+} EFI_ACPI_3_0_LOCAL_APIC_NMI_STRUCTURE;
+
+//
+// Local APIC Address Override Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Reserved;
+ UINT64 LocalApicAddress;
+} EFI_ACPI_3_0_LOCAL_APIC_ADDRESS_OVERRIDE_STRUCTURE;
+
+//
+// IO SAPIC Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 IoApicId;
+ UINT8 Reserved;
+ UINT32 GlobalSystemInterruptBase;
+ UINT64 IoSapicAddress;
+} EFI_ACPI_3_0_IO_SAPIC_STRUCTURE;
+
+//
+// Local SAPIC Structure
+// This struct followed by a null-terminated ASCII string - ACPI Processor UID String
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 AcpiProcessorId;
+ UINT8 LocalSapicId;
+ UINT8 LocalSapicEid;
+ UINT8 Reserved[3];
+ UINT32 Flags;
+ UINT32 ACPIProcessorUIDValue;
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_SAPIC_STRUCTURE;
+
+//
+// Platform Interrupt Sources Structure
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Flags;
+ UINT8 InterruptType;
+ UINT8 ProcessorId;
+ UINT8 ProcessorEid;
+ UINT8 IoSapicVector;
+ UINT32 GlobalSystemInterrupt;
+ UINT32 PlatformInterruptSourceFlags;
+} EFI_ACPI_3_0_PLATFORM_INTERRUPT_SOURCES_STRUCTURE;
+
+//
+// Platform Interrupt Source Flags.
+// All other bits are reserved and must be set to 0.
+//
+#define EFI_ACPI_3_0_CPEI_PROCESSOR_OVERRIDE (1 << 0)
+
+//
+// Smart Battery Description Table (SBST)
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 WarningEnergyLevel;
+ UINT32 LowEnergyLevel;
+ UINT32 CriticalEnergyLevel;
+} EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE;
+
+//
+// SBST Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SMART_BATTERY_DESCRIPTION_TABLE_REVISION 0x01
+
+//
+// Embedded Controller Boot Resources Table (ECDT)
+// The table is followed by a null terminated ASCII string that contains
+// a fully qualified reference to the name space object.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcControl;
+ EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE EcData;
+ UINT32 Uid;
+ UINT8 GpeBit;
+} EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE;
+
+//
+// ECDT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_REVISION 0x01
+
+//
+// System Resource Affinity Table (SRAT. The rest of the table
+// must be defined in a platform specific manner.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT32 Reserved1; // Must be set to 1
+ UINT64 Reserved2;
+} EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_HEADER;
+
+//
+// SRAT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_REVISION 0x02
+
+//
+// SRAT structure types.
+// All other values between 0x02 an 0xFF are reserved and
+// will be ignored by OSPM.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY 0x00
+#define EFI_ACPI_3_0_MEMORY_AFFINITY 0x01
+
+//
+// Processor Local APIC/SAPIC Affinity Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT8 ProximityDomain7To0;
+ UINT8 ApicId;
+ UINT32 Flags;
+ UINT8 LocalSapicEid;
+ UINT8 ProximityDomain31To8[3];
+ UINT8 Reserved[4];
+} EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_AFFINITY_STRUCTURE;
+
+//
+// Local APIC/SAPIC Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_PROCESSOR_LOCAL_APIC_SAPIC_ENABLED (1 << 0)
+
+//
+// Memory Affinity Structure Definition
+//
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT32 ProximityDomain;
+ UINT16 Reserved1;
+ UINT32 AddressBaseLow;
+ UINT32 AddressBaseHigh;
+ UINT32 LengthLow;
+ UINT32 LengthHigh;
+ UINT32 Reserved2;
+ UINT32 Flags;
+ UINT64 Reserved3;
+} EFI_ACPI_3_0_MEMORY_AFFINITY_STRUCTURE;
+
+//
+// Memory Flags. All other bits are reserved and must be 0.
+//
+#define EFI_ACPI_3_0_MEMORY_ENABLED (1 << 0)
+#define EFI_ACPI_3_0_MEMORY_HOT_PLUGGABLE (1 << 1)
+#define EFI_ACPI_3_0_MEMORY_NONVOLATILE (1 << 2)
+
+//
+// System Locality Distance Information Table (SLIT).
+// The rest of the table is a matrix.
+//
+typedef struct {
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT64 NumberOfSystemLocalities;
+} EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_HEADER;
+
+//
+// SLIT Version (as defined in ACPI 3.0 spec.)
+//
+#define EFI_ACPI_3_0_SYSTEM_LOCALITY_DISTANCE_INFORMATION_TABLE_REVISION 0x01
+
+//
+// Known table signatures
+//
+//
+// "RSD PTR " Root System Description Pointer
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_POINTER_SIGNATURE 0x2052545020445352
+
+//
+// "APIC" Multiple APIC Description Table
+//
+#define EFI_ACPI_3_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE 0x43495041
+
+//
+// "DSDT" Differentiated System Description Table
+//
+#define EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445344
+
+//
+// "ECDT" Embedded Controller Boot Resources Table
+//
+#define EFI_ACPI_3_0_EMBEDDED_CONTROLLER_BOOT_RESOURCES_TABLE_SIGNATURE 0x54444345
+
+//
+// "FACP" Fixed ACPI Description Table
+//
+#define EFI_ACPI_3_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE 0x50434146
+
+//
+// "FACS" Firmware ACPI Control Structure
+//
+#define EFI_ACPI_3_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE 0x53434146
+
+//
+// "PSDT" Persistent System Description Table
+//
+#define EFI_ACPI_3_0_PERSISTENT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445350
+
+//
+// "RSDT" Root System Description Table
+//
+#define EFI_ACPI_3_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445352
+
+//
+// "SBST" Smart Battery Specification Table
+//
+#define EFI_ACPI_3_0_SMART_BATTERY_SPECIFICATION_TABLE_SIGNATURE 0x54534253
+
+//
+// "SLIT" System Locality Information Table
+//
+#define EFI_ACPI_3_0_SYSTEM_LOCALITY_INFORMATION_TABLE_SIGNATURE 0x54494C53
+
+//
+// "SRAT" System Resource Affinity Table
+//
+#define EFI_ACPI_3_0_SYSTEM_RESOURCE_AFFINITY_TABLE_SIGNATURE 0x54415253
+
+//
+// "SSDT" Secondary System Description Table
+//
+#define EFI_ACPI_3_0_SECONDARY_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445353
+
+//
+// "XSDT" Extended System Description Table
+//
+#define EFI_ACPI_3_0_EXTENDED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE 0x54445358
+
+//
+// "BOOT" MS Simple Boot Spec
+//
+#define EFI_ACPI_3_0_SIMPLE_BOOT_FLAG_TABLE_SIGNATURE 0x544F4F42
+
+//
+// "CPEP" Corrected Platform Error Polling Table
+// See
+//
+#define EFI_ACPI_3_0_CORRECTED_PLATFORM_ERROR_POLLING_TABLE_SIGNATURE 0x50455043
+
+//
+// "DBGP" MS Debug Port Spec
+//
+#define EFI_ACPI_3_0_DEBUG_PORT_TABLE_SIGNATURE 0x50474244
+
+//
+// "ETDT" Event Timer Description Table
+//
+#define EFI_ACPI_3_0_EVENT_TIMER_DESCRIPTION_TABLE_SIGNATURE 0x54445445
+
+//
+// "HPET" IA-PC High Precision Event Timer Table
+//
+#define EFI_ACPI_3_0_HIGH_PRECISION_EVENT_TIMER_TABLE_SIGNATURE 0x54455048
+
+//
+// "MCFG" PCI Express Memory Mapped Configuration Space Base Address Description Table
+//
+#define EFI_ACPI_3_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE 0x4746434D
+
+//
+// "SPCR" Serial Port Concole Redirection Table
+//
+#define EFI_ACPI_3_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE 0x52435053
+
+//
+// "SPMI" Server Platform Management Interface Table
+//
+#define EFI_ACPI_3_0_SERVER_PLATFORM_MANAGEMENT_INTERFACE_TABLE_SIGNATURE 0x494D5053
+
+//
+// "TCPA" Trusted Computing Platform Alliance Capabilities Table
+//
+#define EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE 0x41504354
+
+//
+// "WDRT" Watchdog Resource Table
+//
+#define EFI_ACPI_3_0_WATCHDOG_RESOURCE_TABLE_SIGNATURE 0x41504354 0x54524457
+
+#pragma pack()
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/PchAslUpdateLib.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/PchAslUpdateLib.h
new file mode 100644
index 0000000..64bc613
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Include/PchAslUpdateLib.h
@@ -0,0 +1,166 @@
+/** @file
+ ASL dynamic update library definitions.
+ This library provides dymanic update to various ASL structures.
+ There may be different libraries for different environments (PEI, BS, RT, SMM).
+ Make sure you meet the requirements for the library (protocol dependencies, use
+ restrictions, etc).
+
+@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
+**/
+#ifndef _ASL_UPDATE_LIB_H_
+#define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include "Acpi3_0.h"
+
+#include EFI_PROTOCOL_DEPENDENCY (AcpiSupport)
+#include EFI_PROTOCOL_DEPENDENCY (AcpiTable)
+
+//
+// AML parsing definitions
+//
+#define AML_NAME_OP 0x08
+#define AML_BUFFER_OP 0x11
+#define AML_DMA_FIXED_DESC_OP 0x55
+#define AML_DEVICE_OP 0x825B
+#define AML_MEMORY32_FIXED_OP 0x86
+#define AML_DWORD_OP 0x87
+#define AML_INTERRUPT_DESC_OP 0x89
+#define AML_RESRC_TEMP_END_TAG 0x0079
+
+/**
+ Initialize the ASL update library state.
+ This must be called prior to invoking other library functions.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+InitializePchAslUpdateLib (
+ VOID
+ );
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature The signature of Operation Region that we want to update.
+ @param[in] Buffer source of data to be written over original aml
+ @param[in] Length length of data to be overwritten
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode(
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This function locates an ACPI structure and updates it.
+ This function knows how to update operation regions and BUFA/BUFB resource structures.
+
+ This function may not be implemented in all instantiations of this library.
+
+ @param[in] AslSignature The signature of Operation Region that we want to update.
+ @param[in] BufferName signature of the Buffer inside OpRegion that we want to update
+ @param[in] MacroAmlEncoding type of entry inside Buffer.
+ @param[in] MacroEntryNumber number of entry of the above type
+ @param[in] Offset offset (in bytes) inside entry where update will be performed
+ @param[in] Buffer source of data to be written over original aml
+ @param[in] Length length of data to be overwritten
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+UpdateResourceTemplateAslCode (
+ IN UINT32 AslSignature,
+ IN UINT32 BufferName,
+ IN UINT8 MacroAmlEncoding,
+ IN UINT8 MacroEntryNumber,
+ IN UINT8 Offset,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI table using the .
+ It is really only useful for finding tables that only have a single instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+ Matches are determined by finding the table with ACPI table that has
+ a matching signature and version.
+
+ @param[in] TableId Pointer to an ASCII string containing the Signature to match
+ @param[in out] Table Updated with a pointer to the table
+ @param[in out] Handle AcpiSupport protocol table handle for the table found
+ @param[in out] Version On input, the version of the table desired,
+ on output, the versions the table belongs to
+ (see AcpiSupport protocol for details)
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ );
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI SSDT table.
+ The table is located by searching for a matching OEM Table ID field.
+ Partial match searches are supported via the TableIdSize parameter.
+
+ @param[in] TableId Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize Length of the TableId to match. Table ID are 8 bytes long, this function
+ will consider it a match if the first TableIdSize bytes match
+ @param[in out] Table Updated with a pointer to the table
+ @param[in out] Handle AcpiSupport protocol table handle for the table found
+ @param[in out] Version See AcpiSupport protocol, GetAcpiTable function for use
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ );
+
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @param[in] Buffer Pointer to buffer to checksum
+ @param[in] Size Number of bytes to checksum
+ @param[in] ChecksumOffset Offset to place the checksum result in
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFI_BOOTSERVICE
+AcpiChecksum (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINTN ChecksumOffset
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.c
new file mode 100644
index 0000000..919ab50
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.c
@@ -0,0 +1,474 @@
+/** @file
+ Boot service DXE ASL update library implementation.
+
+ These functions in this file can be called during DXE and cannot be called during runtime
+ or in SMM which should use a RT or SMM library.
+
+ This library uses the ACPI Support protocol.
+
+@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
+
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#endif
+#include "PchAslUpdateLib.h"
+
+//
+// Function implemenations
+//
+static EFI_ACPI_SUPPORT_PROTOCOL *mAcpiSupport = NULL;
+static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL;
+
+/**
+ Initialize the ASL update library state.
+ This must be called prior to invoking other library functions.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+InitializePchAslUpdateLib (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate ACPI tables
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiSupportGuid, NULL, (VOID **) &mAcpiSupport);
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
+ return Status;
+}
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+UpdateNameAslCode(
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINT8 Index;
+ UINTN Handle;
+ UINT8 DataSize;
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Index = 0;
+
+ do {
+ Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **) &Table, &Version, &Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (Table->Signature != EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE);
+
+ ///
+ /// Point to the beginning of the DSDT table
+ ///
+ Index = 0;
+ CurrPtr = (UINT8 *) Table;
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if(*(DsdtPointer-1) == AML_NAME_OP){
+ ///
+ /// Check if size of new and old data is the same
+ ///
+ DataSize = *(DsdtPointer+4);
+ if ((Length == 1 && DataSize == 0xA) ||
+ (Length == 2 && DataSize == 0xB) ||
+ (Length == 4 && DataSize == 0xC) ) {
+ CopyMem (DsdtPointer+5, Buffer, Length);
+ } else if (Length == 1 && ((*(UINT8*)Buffer) == 0 || (*(UINT8*)Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+ CopyMem (DsdtPointer+4, Buffer, Length);
+ } else {
+ FreePool (Table);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+#ifdef AMI_OVERRIDE_FOR_ACPI
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+#endif //AMI_OVERRIDE_FOR_ACPI
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This procedure will update a Resource Descriptor Macro in
+ Resrouce Template buffer list.
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] BufferName - signature of the Buffer inside OpRegion that we want to update
+ @param[in] MacroAmlEncoding - type of entry inside Buffer.
+ @param[in] MacroEntryNumber - number of entry of the above type
+ @param[in] Offset - offset (in bytes) inside entry where update will be performed
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+UpdateResourceTemplateAslCode (
+ IN UINT32 AslSignature,
+ IN UINT32 BufferName,
+ IN UINT8 MacroAmlEncoding,
+ IN UINT8 MacroEntryNumber,
+ IN UINT8 Offset,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ EFI_ACPI_TABLE_VERSION Version;
+ UINT8 *CurrPtr;
+ UINT8 *Operation;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINT8 Index;
+ UINTN Handle;
+ UINT32 AslLength;
+ BOOLEAN EntryFound;
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Index = 0;
+ AslLength = 0;
+ EntryFound = FALSE;
+
+ do {
+ Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **)&Table, &Version, &Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (Table->Signature != EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE);
+
+ ///
+ /// Point to the beginning of the DSDT table
+ ///
+ Index = 0;
+ CurrPtr = (UINT8 *) Table;
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Read the Device Object block length
+ ///
+ if (*(UINT16 *)(DsdtPointer - 3) == AML_DEVICE_OP) {
+ AslLength = *(DsdtPointer - 1);
+ } else if (*(UINT16 *)(DsdtPointer - 4) == AML_DEVICE_OP) {
+ AslLength = *(UINT16 *)(DsdtPointer - 2);
+ AslLength = (AslLength & 0x0F) + ((AslLength & 0x0FF00) >> 4);
+ } else if (*(UINT16 *)(DsdtPointer - 5) == AML_DEVICE_OP) {
+ AslLength = *(UINT32 *)(DsdtPointer - 3) & 0x00FFFFFFFF;
+ AslLength = (AslLength & 0x0F) + ((AslLength & 0x0000FF00) >> 4) + ((AslLength & 0x00FF0000) >> 4);
+ } else if (*(UINT16 *)(DsdtPointer - 6) == AML_DEVICE_OP) {
+ AslLength = *(UINT32 *)(DsdtPointer - 4);
+ AslLength = (AslLength & 0x0F) + ((AslLength & 0x0000FF00) >> 4) + ((AslLength & 0x00FF0000) >> 4) + ((AslLength & 0xFF000000) >> 4);
+ } else {
+ continue; //Search for next instance
+ }
+
+ ///
+ /// Conditional match. Search AML Encoding in Device.
+ ///
+ for (Operation = DsdtPointer; Operation <= DsdtPointer + AslLength; Operation++) {
+ ///
+ /// Look for Name Encoding
+ ///
+ while(Operation <= DsdtPointer + AslLength) {
+ if(*Operation == AML_NAME_OP){
+ ///
+ /// Found Name AML Encoding
+ ///
+ Operation++;
+ if(*(UINT32 *)(Operation) == BufferName) {
+ ///
+ /// Found RBUF Resource Template object name
+ ///
+ break;
+ }
+ }
+ Operation++;
+ }
+
+ if(Operation > DsdtPointer + AslLength ){
+ continue; //Search for next instance
+ }
+
+ ///
+ /// Now look for the Resource Template Object buffer opcode
+ ///
+ while((*Operation) != AML_BUFFER_OP) {
+ Operation++;
+ if(Operation > DsdtPointer + AslLength){
+ FreePool (Table);
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ ///
+ /// Now look for the Macro to be updated until
+ /// (1) it is found OR (2) reach end of resource template
+ ///
+ while(*(UINT16 *)(Operation) != AML_RESRC_TEMP_END_TAG) {
+ if((*Operation == MacroAmlEncoding)) {
+ ///
+ /// We found a matching encoding however, the buffer list may have "n" number
+ /// of same encoding entries. Let's narrow down to the "n"th entry.
+ ///
+ Index++;
+ if(Index == MacroEntryNumber) {
+ ///
+ /// Get to the starting offset & end offset
+ ///
+ Operation += Offset;
+
+ ///
+ /// Fixup the value at the offset
+ ///
+ CopyMem ((VOID *) Operation, (VOID *) (Buffer), Length);
+
+ ///
+ /// Update the modified ACPI table
+ ///
+#ifdef AMI_OVERRIDE_FOR_ACPI
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+#endif //AMI_OVERRIDE_FOR_ACPI
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ Operation++;
+ }
+
+ if(Operation > DsdtPointer + AslLength) {
+ FreePool (Table);
+ return EFI_NOT_FOUND;
+ }
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI table.
+ It is really only useful for finding tables that only have a single instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+
+ @param[in] Signature - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+ @param[in, out] Version - The version of the table desired
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+ EFI_ACPI_TABLE_VERSION DesiredVersion;
+
+ DesiredVersion = *Version;
+ ///
+ /// Locate table with matching ID
+ ///
+ Index = 0;
+ do {
+ Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **)Table, Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while ((*Table)->Signature != Signature || !(*Version & DesiredVersion));
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI SSDT table.
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ will consider it a match if the first TableIdSize bytes match
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+ @param[in, out] Version - See AcpiSupport protocol, GetAcpiTable function for use
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle,
+ IN OUT EFI_ACPI_TABLE_VERSION *Version
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Index = 0;
+ do {
+ Status = mAcpiSupport->GetAcpiTable (mAcpiSupport, Index, (VOID **)Table, Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (CompareMem (&(*Table)->OemTableId, TableId, TableIdSize));
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
+
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @param[in] Buffer Pointer to buffer to checksum
+ @param[in] Size Number of bytes to checksum
+ @param[in] ChecksumOffset Offset to place the checksum result in
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINTN ChecksumOffset
+ )
+{
+ UINT8 Sum;
+ UINT8 *Ptr;
+
+ Sum = 0;
+ ///
+ /// Initialize pointer
+ ///
+ Ptr = Buffer;
+
+ ///
+ /// set checksum to 0 first
+ ///
+ Ptr[ChecksumOffset] = 0;
+
+ ///
+ /// add all content of buffer
+ ///
+ while (Size--) {
+ Sum = (UINT8) (Sum + (*Ptr++));
+ }
+ ///
+ /// set checksum
+ ///
+ Ptr = Buffer;
+ Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.cif b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.cif
new file mode 100644
index 0000000..79bdb6e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PchAslUpdateLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SampleCode\Library\AslUpdate\Dxe\"
+ RefName = "PchAslUpdateLib"
+[files]
+"PchAslUpdateLib.sdl"
+"PchAslUpdateLib.mak"
+"PchAslUpdateLib.c"
+"PchAslUpdateLib.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.inf b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.inf
new file mode 100644
index 0000000..c0a0509
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.inf
@@ -0,0 +1,66 @@
+## @file
+# Provides services to update ASL tables.
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchAslUpdateLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ PchAslUpdateLib.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/Dxe/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/Include
+
+#
+# Edk II Glue Library, some hearder are included by R9 header so have to include
+#
+
+ $(EFI_SOURCE)
+ $(EFI_SOURCE)/Framework
+ $(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
+
+[libraries.common]
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+
+[nmake.common]
+
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak
new file mode 100644
index 0000000..5f59035
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak
@@ -0,0 +1,83 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (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/PchSampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak 1 7/02/12 9:37a Victortu $
+#
+# $Revision: 1 $
+#
+# $Date: 7/02/12 9:37a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.mak $
+#
+# 1 7/02/12 9:37a Victortu
+# PchAslUpdateLib initially releases.
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PchAslUpdateLib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PchAslUpdateLib
+
+$(PchAslUpdateLib_LIB) : PchAslUpdateLib
+
+PchAslUpdateLib : $(BUILD_DIR)\PchAslUpdateLib.mak PchAslUpdateLibBin
+
+$(BUILD_DIR)\PchAslUpdateLib.mak : $(PchAslUpdateLib_DIR)\$(@B).cif $(PchAslUpdateLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchAslUpdateLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchAslUpdateLib_INCLUDES=\
+ $(EDK_INCLUDES) \
+ $(EdkIIGlueLib_INCLUDES)\
+ /I$(INTEL_PCH_DIR)\SampleCode\Include
+
+PchAslUpdateLib_DEFINES = \
+ $(MY_DEFINES)\
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__\
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__\
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__
+
+PchAslUpdateLib_LIBS=\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+PchAslUpdateLibBin: $(PchAslUpdateLib_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchAslUpdateLib.mak all \
+ "MY_INCLUDES=$(PchAslUpdateLib_INCLUDES)" \
+ "MY_DEFINES=$(PchAslUpdateLib_DEFINES)"\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.sdl b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.sdl
new file mode 100644
index 0000000..c52b5a8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Library/AslUpdate/Dxe/PchAslUpdateLib.sdl
@@ -0,0 +1,29 @@
+TOKEN
+ Name = PchAslUpdateLib_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchAslUpdateLib support in Project"
+End
+
+MODULE
+ Help = "Includes PchAslUpdateLib.mak to Project"
+ File = "PchAslUpdateLib.mak"
+End
+
+PATH
+ Name = "PchAslUpdateLib_DIR"
+End
+
+ELINK
+ Name = "PchAslUpdateLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchAslUpdateLib.lib"
+ Parent = "PchAslUpdateLib_LIB"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.c
new file mode 100644
index 0000000..8845a6d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.c
@@ -0,0 +1,427 @@
+/** @file
+ This file is SampleCode for Intel PCH Common Platform Policy initialzation.
+
+@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 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
+
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include "EdkIIGlueBase.h"
+#include "PchPlatformPolicy.h"
+#include "PchPlatformLib.h"
+#include "PchRegs.h"
+#endif
+
+/**
+ Initilize Intel USB Common Platform Policy
+
+ @param[in] PchUsbConfig Usb platform policy structure.
+
+ @retval NONE
+**/
+VOID
+InitPchUsbConfig (
+ IN PCH_USB_CONFIG *PchUsbConfig
+ )
+{
+ UINTN PortIndex;
+ UINT16 LpcDeviceId;
+ PCH_SERIES PchSeries;
+
+ if (PchUsbConfig == NULL) {
+ return;
+ }
+
+ PchSeries = GetPchSeries();
+ LpcDeviceId = MmioRead16 (MmPciAddress (0, 0, PCI_DEVICE_NUMBER_PCH_LPC, PCI_FUNCTION_NUMBER_PCH_LPC, 0) + R_PCH_LPC_DEVICE_ID);
+
+ //
+ // EHCI Host Controller Enable/Disable
+ //
+ PchUsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_ENABLE;
+
+ //
+ // Automatically disable EHCI when XHCI Mode is Enabled to save power.
+ //
+ if (PchUsbConfig->Usb30Settings.Mode == PCH_XHCI_MODE_ON) {
+ PchUsbConfig->Usb20Settings[0].Enable = PCH_DEVICE_DISABLE;
+ if (PchSeries == PchH) {
+ PchUsbConfig->Usb20Settings[1].Enable = PCH_DEVICE_DISABLE;
+ }
+ }
+ //
+ // Set to Enable if BIOS has its own xHCI driver
+ //
+ PchUsbConfig->Usb30Settings.PreBootSupport = PCH_DEVICE_ENABLE;
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 13.1 xHCI controller options in Reference Code
+ /// Please refer to Table 13-1 in PCH BIOS Spec for USB Port Operation with no xHCI
+ /// pre-boot software.
+ /// Please refer to Table 13-2 in PCH BIOS Spec for USB Port Operation with xHCI
+ /// pre-boot software.
+ ///
+ /// The xHCI modes that available in BIOS are:
+ /// Disabled - forces only USB 2.0 to be supported in the OS. The xHCI controller is turned off
+ /// and hidden from the PCI space.
+ /// Enabled - allows USB 3.0 to be supported in the OS. The xHCI controller is turned on. The
+ /// shareable ports are routed to the xHCI controller. OS needs to provide drivers
+ /// to support USB 3.0.
+ /// Auto - This mode uses ACPI protocol to provide an option that enables the xHCI controller
+ /// and reroute USB ports via the _OSC ACPI method call. Note, this mode switch requires
+ /// special OS driver support for USB 3.0.
+ /// Smart Auto - This mode is similar to Auto, but it adds the capability to route the ports to xHCI
+ /// or EHCI according to setting used in previous boots (for non-G3 boot) in the pre-boot
+ /// environment. This allows the use of USB 3.0 devices prior to OS boot. Note, this mode
+ /// switch requires special OS driver support for USB 3.0 and USB 3.0 software available
+ /// in the pre-boot enviroment.
+ ///
+ /// Manual Mode - For validation and experimental purposes only. Do not create setup option for end-user BIOS.
+ ///
+ /// Recommendations:
+ /// - If BIOS supports xHCI pre-boot driver then use Smart Auto mode as default
+ /// - If BIOS does not support xHCI pre-boot driver then use AUTO mode as default
+ ///
+ if (PchUsbConfig->Usb30Settings.PreBootSupport == PCH_DEVICE_ENABLE) {
+ PchUsbConfig->Usb30Settings.Mode = PCH_XHCI_MODE_SMARTAUTO;
+ } else {
+ PchUsbConfig->Usb30Settings.Mode = PCH_XHCI_MODE_AUTO;
+ }
+
+ //
+ // Manual Mode is for validation and experimental purposes only.
+ // Do not create setup option for end-user BIOS.
+ //
+ PchUsbConfig->Usb30Settings.ManualMode = PCH_DEVICE_DISABLE;
+
+ //
+ // XhciIdleL1 can be set to disable for LPT-LP Ax stepping to workaround USB3 hot plug will fail after 1 hot plug removal.
+ //
+ PchUsbConfig->Usb30Settings.XhciIdleL1 = PCH_DEVICE_ENABLE;
+
+ //
+ // Btcg is for enabling/disabling trunk clock gating.
+ //
+ PchUsbConfig->Usb30Settings.Btcg = PCH_DEVICE_ENABLE;
+
+ for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) {
+ PchUsbConfig->Usb30Settings.ManualModeUsb20PerPinRoute[PortIndex] = 0;
+ }
+
+ for (PortIndex = 0; PortIndex < GetPchXhciMaxUsb3PortNum (); PortIndex++) {
+ PchUsbConfig->Usb30Settings.ManualModeUsb30PerPinEnable[PortIndex] = PCH_DEVICE_DISABLE;
+ }
+
+ //
+ // Use by AMT/MEBx to enable USB-R support.
+ //
+ PchUsbConfig->Ehci1Usbr = PCH_DEVICE_DISABLE;
+ PchUsbConfig->Ehci2Usbr = PCH_DEVICE_DISABLE;
+
+ //
+ // UsbPrecondition = Enable , Force USB Init happen in PEI as part of 2Sec Fast Boot bios optimization
+ // UsbPrecondition = Disable, USB Init happen in DXE just like traditionally where it happen.
+ //
+ PchUsbConfig->UsbPrecondition = PCH_DEVICE_DISABLE;
+
+ //
+ // USB Per-Port Control is use to Enable/Disable individual port.
+ //
+ PchUsbConfig->UsbPerPortCtl = PCH_DEVICE_DISABLE;
+
+ PchUsbConfig->PortSettings[0].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[1].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[2].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[3].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[4].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[5].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[6].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[7].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[8].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[9].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[10].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[11].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[12].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->PortSettings[13].Enable = PCH_DEVICE_ENABLE;
+
+ PchUsbConfig->Port30Settings[0].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Port30Settings[1].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Port30Settings[2].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Port30Settings[3].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Port30Settings[4].Enable = PCH_DEVICE_ENABLE;
+ PchUsbConfig->Port30Settings[5].Enable = PCH_DEVICE_ENABLE;
+
+ //
+ // USB Port Over Current Pins mapping, please set as per board layout.
+ //
+ PchUsbConfig->Usb20OverCurrentPins[ 0] = PchUsbOverCurrentPin0;
+ PchUsbConfig->Usb20OverCurrentPins[ 1] = PchUsbOverCurrentPin0;
+ PchUsbConfig->Usb20OverCurrentPins[ 2] = PchUsbOverCurrentPin1;
+ PchUsbConfig->Usb20OverCurrentPins[ 3] = PchUsbOverCurrentPin1;
+ PchUsbConfig->Usb20OverCurrentPins[ 4] = PchUsbOverCurrentPin2;
+ PchUsbConfig->Usb20OverCurrentPins[ 5] = PchUsbOverCurrentPin2;
+ PchUsbConfig->Usb20OverCurrentPins[ 6] = PchUsbOverCurrentPin3;
+ PchUsbConfig->Usb20OverCurrentPins[ 7] = PchUsbOverCurrentPin3;
+ PchUsbConfig->Usb20OverCurrentPins[ 8] = PchUsbOverCurrentPin4;
+ PchUsbConfig->Usb20OverCurrentPins[ 9] = PchUsbOverCurrentPin4;
+ PchUsbConfig->Usb20OverCurrentPins[10] = PchUsbOverCurrentPin5;
+ PchUsbConfig->Usb20OverCurrentPins[11] = PchUsbOverCurrentPin5;
+ PchUsbConfig->Usb20OverCurrentPins[12] = PchUsbOverCurrentPin6;
+ PchUsbConfig->Usb20OverCurrentPins[13] = PchUsbOverCurrentPin6;
+
+ PchUsbConfig->Usb30OverCurrentPins[0] = PchUsbOverCurrentPin0;
+ PchUsbConfig->Usb30OverCurrentPins[1] = PchUsbOverCurrentPin0;
+ PchUsbConfig->Usb30OverCurrentPins[2] = PchUsbOverCurrentPin1;
+ PchUsbConfig->Usb30OverCurrentPins[3] = PchUsbOverCurrentPin1;
+ PchUsbConfig->Usb30OverCurrentPins[4] = PchUsbOverCurrentPin2;
+ PchUsbConfig->Usb30OverCurrentPins[5] = PchUsbOverCurrentPin2;
+
+ //
+ // USB 2.0 D+/D- trace length in inchs*10 or 1000mils/10 measurement eg. 12.3" = 0x123
+ // Please set as per board layout.
+ //
+ PchUsbConfig->PortSettings[ 0].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 1].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 2].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 3].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 4].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 5].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 6].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 7].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 8].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[ 9].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[10].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[11].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[12].Usb20PortLength = 0x100;
+ PchUsbConfig->PortSettings[13].Usb20PortLength = 0x100;
+
+ //
+ // Port Location
+ //
+ PchUsbConfig->PortSettings[ 0].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 1].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 2].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 3].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 4].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 5].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 6].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 7].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 8].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[ 9].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[10].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[11].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[12].Location = PchUsbPortLocationFrontPanel;
+ PchUsbConfig->PortSettings[13].Location = PchUsbPortLocationFrontPanel;
+
+/*
+ Guideline:
+ This algorithm is move from chipset level code to board level code to allow OEM more flexibility
+ to tune the value for individual board layout electrical characteristics to pass the USB 2.0 Eye Diagram Test.
+
+ IF Board=LPT-H Desktop
+ For BIT[10:08] Usb20EyeDiagramTuningParam1 (PERPORTTXISET)
+ IF Back Panel
+ SET to 4
+ ELSE
+ SET to 3
+ ENDIF
+
+ For BIT[13:11] Usb20EyeDiagramTuningParam2 (PERPORTPETXISET)
+ IF Back Panel
+ IF Trace Length < 8"
+ SET to 2
+ ELSE IF Trace Length < 13"
+ SET to 3
+ ELSE
+ SET to 4
+ ENDIF
+ ELSE
+ SET to 2
+ ENDIF
+
+ For BIT[14]
+ Always SET to 0
+
+ END LPT-H Desktop
+
+ IF Board=LPT-H Mobile
+ For BIT[10:08] Usb20EyeDiagramTuningParam1 (PERPORTTXISET)
+ IF Interal Topology
+ SET to 5
+ ELSE IF Dock
+ SET to 4
+ ELSE
+ IF Trace Length < 7"
+ SET to 5
+ ELSE
+ SET to 6
+ ENDIF
+ ENDIF
+
+ For BIT[13:11] Usb20EyeDiagramTuningParam2 (PERPORTPETXISET)
+ IF Interal Topology
+ SET to 2
+ ELSE IF Dock
+ IF Trace Length < 5"
+ SET to 1
+ ELSE
+ SET to 2
+ ENDIF
+ ELSE
+ IF Trace Length < 10"
+ SET to 2
+ ELSE
+ SET to 3
+ ENDIF
+ ENDIF
+
+ For BIT[14]
+ Always SET to 0
+ END LPT-H Mobile
+
+ IF Board=LPT-LP
+ For BIT[10:08] Usb20EyeDiagramTuningParam1 (PERPORTTXISET)
+ IF Back Panel OR MiniPciE
+ IF Trace Length < 7"
+ SET to 5
+ ELSE
+ SET to 6
+ ENDIF
+ ELSE IF Dock
+ SET to 4
+ ELSE
+ SET to 5
+ ENDIF
+
+ For BIT[13:11] Usb20EyeDiagramTuningParam2 (PERPORTPETXISET)
+ IF Back Panel OR MiniPciE
+ IF Trace Length < 10"
+ SET to 2
+ ELSE
+ SET to 3
+ ENDIF
+ ELSE IF Dock
+ IF Trace Length < 5"
+ SET to 1
+ ELSE
+ SET to 2
+ ENDIF
+ ELSE
+ SET to 2
+ ENDIF
+
+ For BIT[14]
+ Always SET to 0
+ END LPT-LP
+*/
+
+ //
+ // USB 2.0 trace length signal strength
+ //
+/*
+ IF Board=LPT-H Mobile
+
+ END LPT-H Mobile
+*/
+
+ if (PchSeries == PchH) {
+ if (IS_PCH_LPT_LPC_DEVICE_ID_DESKTOP (LpcDeviceId)) {
+ for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) {
+ if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; //Back Panel
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 3; //Front Panel
+ }
+
+ if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x80) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 7.9"
+ } else if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x130) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 8"-12.9"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 4; //Back Panel, 13" onward
+ }
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Front Panel
+ }
+ }
+ } else if (IS_PCH_LPT_LPC_DEVICE_ID_MOBILE (LpcDeviceId)) {
+ for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) {
+ if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology
+ } else if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock
+ } else {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward
+ }
+ }
+
+ if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationInternalTopology) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology
+ } else if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward
+ }
+ } else {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward
+ }
+ }
+ }
+ }
+ } else if (PchSeries == PchLp) {
+ for (PortIndex = 0; PortIndex < GetPchUsbMaxPhysicalPortNum (); PortIndex++) {
+ if ((PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) ||
+ (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x70) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; //Back Panel, less than 7"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 6; //Back Panel, 7" onward
+ }
+ } else if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 4; // Dock
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam1 = 5; // Internal Topology
+ }
+
+ if ((PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationBackPanel) ||
+ (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationMiniPciE)) {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x100) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Back Panel, less than 10"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 3; //Back Panel, 10" onward
+ }
+ } else if (PchUsbConfig->PortSettings[PortIndex].Location == PchUsbPortLocationDock) {
+ if (PchUsbConfig->PortSettings[PortIndex].Usb20PortLength < 0x50) {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 1; //Dock, less than 5"
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; //Dock, 5" onward
+ }
+ } else {
+ PchUsbConfig->PortSettings[PortIndex].Usb20EyeDiagramTuningParam2 = 2; // Internal Topology
+ }
+ }
+ }
+
+ return;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.h
new file mode 100644
index 0000000..daf1750
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Common/PchPolicyInitCommon.h
@@ -0,0 +1,33 @@
+/** @file
+ Header file for Common PchPolicyInit Library
+
+@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
+**/
+#ifndef _PCH_POLICY_INIT_COMMON_H_
+#define _PCH_POLICY_INIT_COMMON_H_
+
+/**
+ This function performs PCH USB Platform Policy initialzation
+
+ @param[in] UsbConfig Pointer to PCH_USB_CONFIG data buffer.
+
+ @retval NONE
+**/
+VOID
+InitPchUsbConfig (
+ IN PCH_USB_CONFIG *UsbConfig
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.c
new file mode 100644
index 0000000..5deee40
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.c
@@ -0,0 +1,490 @@
+/** @file
+ This file is SampleCode for Intel PCH DXE Platform Policy initialzation.
+
+@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 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
+
+**/
+#include "PchPolicyInitDxe.h"
+#include "..\Common\PchPolicyInitCommon.h"
+
+#define SW_SMI_BIOS_LOCK 0xA9
+#define PCI_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x00
+#define PCI_CLASS_NETWORK_OTHER 0x80
+
+DXE_PCH_PLATFORM_POLICY_PROTOCOL mPchPolicyData = { 0 };
+PCH_DEVICE_ENABLING mPchDeviceEnabling = { 0 };
+PCH_USB_CONFIG mPchUsbConfig = { 0 };
+PCH_PCI_EXPRESS_CONFIG mPchPciExpressConfig = { 0 };
+PCH_SATA_CONFIG mPchSataConfig = { 0 };
+PCH_AZALIA_CONFIG mPchAzaliaConfig = { 0 };
+PCH_SMBUS_CONFIG mPchSmbusConfig = { 0 };
+PCH_MISC_PM_CONFIG mPchMiscPmConfig = { 0 };
+PCH_IO_APIC_CONFIG mPchIoApicConfig = { 0 };
+PCH_DEFAULT_SVID_SID mPchDefaultSvidSid = { 0 };
+PCH_LOCK_DOWN_CONFIG mPchLockDownConfig = { 0 };
+PCH_THERMAL_CONFIG mPchThermalConfig = { 0 };
+PCH_LPC_HPET_CONFIG mPchHpetConfig = { 0 };
+PCH_LPC_SIRQ_CONFIG mSerialIrqConfig = { 0 };
+PCH_DMI_CONFIG mPchDmiConfig = { 0 };
+PCH_PWR_OPT_CONFIG mPchPwrOptConfig = { 0 };
+PCH_MISC_CONFIG mPchMiscConfig = { 0 };
+PCH_AUDIO_DSP_CONFIG mAudioDspConfig = { 0 };
+PCH_SERIAL_IO_CONFIG mSerialIoConfig = { 0 };
+
+UINT8 mSmbusRsvdAddresses[4] = {
+ 0xA0,
+ 0xA2,
+ 0xA4,
+ 0xA6
+};
+
+PCH_PCIE_DEVICE_ASPM_OVERRIDE mDevAspmOverride[] = {
+ //
+ // Intel PRO/Wireless
+ //
+ {0x8086, 0x422b, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x422c, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x4238, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x4239, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel WiMAX/WiFi Link
+ //
+ {0x8086, 0x0082, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0085, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0083, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0084, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0086, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0087, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0088, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0089, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x008F, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0090, 0xff, 0xff, 0xff, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Crane Peak WLAN NIC
+ //
+ {0x8086, 0x08AE, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x08AF, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Crane Peak w/BT WLAN NIC
+ //
+ {0x8086, 0x0896, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0897, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Kelsey Peak WiFi, WiMax
+ //
+ {0x8086, 0x0885, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0886, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Centrino Wireless-N 105
+ //
+ {0x8086, 0x0894, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0895, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Centrino Wireless-N 135
+ //
+ {0x8086, 0x0892, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0893, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Centrino Wireless-N 2200
+ //
+ {0x8086, 0x0890, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0891, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Centrino Wireless-N 2230
+ //
+ {0x8086, 0x0887, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x0888, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel Centrino Wireless-N 6235
+ //
+ {0x8086, 0x088E, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x088F, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel CampPeak 2 Wifi
+ //
+ {0x8086, 0x08B5, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ {0x8086, 0x08B6, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF},
+ //
+ // Intel WilkinsPeak 1 Wifi
+ //
+ {0x8086, 0x08B3, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003},
+ {0x8086, 0x08B3, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003},
+ {0x8086, 0x08B4, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003},
+ {0x8086, 0x08B4, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003},
+ //
+ // Intel Wilkins Peak 2 Wifi
+ //
+ {0x8086, 0x08B1, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003},
+ {0x8086, 0x08B1, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003},
+ {0x8086, 0x08B2, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2AndL1SubstatesOverride, 0x0154, 0x00000003},
+ {0x8086, 0x08B2, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1SubstatesOverride, 0x0158, 0x00000003},
+ //
+ // Intel Wilkins Peak PF Wifi
+ //
+ {0x8086, 0x08B0, 0xff, PCI_CLASS_NETWORK, PCI_CLASS_NETWORK_OTHER, PchPcieAspmL1, PchPcieL1L2Override, 0xFFFF, 0xFFFFFFFF}
+
+};
+
+//
+// Function implementations
+//
+
+/**
+ Initilize Intel PCH DXE Platform Policy
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+PchPolicyInitDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINT8 PortIndex;
+ UINTN Index;
+ PCH_SERIES PchSeries;
+ PchSeries = GetPchSeries();
+ //
+ // General intialization
+ //
+ mPchPolicyData.Revision = DXE_PCH_PLATFORM_POLICY_PROTOCOL_REVISION_7;
+ mPchPolicyData.BusNumber = 0;
+
+ mPchPolicyData.DeviceEnabling = &mPchDeviceEnabling;
+ mPchPolicyData.UsbConfig = &mPchUsbConfig;
+ mPchPolicyData.PciExpressConfig = &mPchPciExpressConfig;
+ mPchPolicyData.SataConfig = &mPchSataConfig;
+ mPchPolicyData.AzaliaConfig = &mPchAzaliaConfig;
+ mPchPolicyData.SmbusConfig = &mPchSmbusConfig;
+ mPchPolicyData.MiscPmConfig = &mPchMiscPmConfig;
+ mPchPolicyData.IoApicConfig = &mPchIoApicConfig;
+ mPchPolicyData.DefaultSvidSid = &mPchDefaultSvidSid;
+ mPchPolicyData.LockDownConfig = &mPchLockDownConfig;
+ mPchPolicyData.ThermalConfig = &mPchThermalConfig;
+ mPchPolicyData.HpetConfig = &mPchHpetConfig;
+ mPchPolicyData.SerialIrqConfig = &mSerialIrqConfig;
+ mPchPolicyData.DmiConfig = &mPchDmiConfig;
+ mPchPolicyData.PwrOptConfig = &mPchPwrOptConfig;
+ mPchPolicyData.MiscConfig = &mPchMiscConfig;
+ mPchPolicyData.AudioDspConfig = &mAudioDspConfig;
+ mPchPolicyData.SerialIoConfig = &mSerialIoConfig;
+
+ ///
+ /// PCH BIOS Spec Rev 0.5.0 Section 3.6 Flash Security Recommendations,
+ /// Intel strongly recommends that BIOS sets the BIOS Interface Lock Down bit. Enabling this bit
+ /// will mitigate malicious software attempts to replace the system BIOS option ROM with its own code.
+ /// We always enable this as a platform policy.
+ ///
+ mPchLockDownConfig.BiosInterface = PCH_DEVICE_ENABLE;
+ mPchLockDownConfig.GlobalSmi = PCH_DEVICE_ENABLE;
+ mPchLockDownConfig.GpioLockDown = PCH_DEVICE_DISABLE;
+ mPchLockDownConfig.RtcLock = PCH_DEVICE_ENABLE;
+ ///
+ /// While BiosLock is enabled, BIOS can only be modified from SMM after ExitPmAuth.
+ ///
+ mPchLockDownConfig.BiosLock = PCH_DEVICE_DISABLE;
+ ///
+ /// If PchBiosLockIoTrapAddress is 0, BIOS will allocate available IO address with
+ /// 256 byte range from GCD and pass it to PchBiosLockIoTrapAddress.
+ ///
+ mPchLockDownConfig.PchBiosLockIoTrapAddress = 0;
+ ///
+ /// Initialize policy to default values when variable isn't found.
+ ///
+ mPchDeviceEnabling.Lan = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.Azalia = 2;
+ mPchDeviceEnabling.Sata = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.Smbus = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.PciClockRun = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.Display = 1;
+ mPchDeviceEnabling.Crid = PCH_DEVICE_DISABLE;
+ mPchDeviceEnabling.SerialIoDma = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoI2c0 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoI2c1 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoSpi0 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoSpi1 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoUart0 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoUart1 = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.SerialIoSdio = PCH_DEVICE_ENABLE;
+ mPchDeviceEnabling.AudioDsp = PCH_DEVICE_DISABLE;
+
+ ///
+ /// Init USB related setting
+ ///
+ InitPchUsbConfig (&mPchUsbConfig);
+
+ ///
+ /// PCI Express related settings from setup variable
+ ///
+ mPchPciExpressConfig.RootPortClockGating = PCH_DEVICE_ENABLE;
+ mPchPciExpressConfig.TempRootPortBusNumMin = 2;
+ mPchPciExpressConfig.TempRootPortBusNumMax = 4;
+
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ mPchPciExpressConfig.RootPort[PortIndex].Enable = PCH_DEVICE_ENABLE;
+ mPchPciExpressConfig.RootPort[PortIndex].FunctionNumber = PortIndex;
+ mPchPciExpressConfig.RootPort[PortIndex].PhysicalSlotNumber = PortIndex;
+ mPchPciExpressConfig.RootPort[PortIndex].Aspm = 4;
+ mPchPciExpressConfig.RootPort[PortIndex].SlotImplemented = 1;
+ mPchPciExpressConfig.RootPort[PortIndex].L1Substates = 3;
+
+ }
+ mPchPciExpressConfig.RootPort[7].HotPlug = 1;
+ mPchPciExpressConfig.NumOfDevAspmOverride = sizeof (mDevAspmOverride) / sizeof (PCH_PCIE_DEVICE_ASPM_OVERRIDE);
+ mPchPciExpressConfig.DevAspmOverride = mDevAspmOverride;
+ mPchPciExpressConfig.EnableSubDecode = 0;
+ mPchPciExpressConfig.PchPcieSbdePort = 0;
+ mPchPciExpressConfig.RootPortFunctionSwapping = 1;
+
+ for (PortIndex = 0; PortIndex < GetPchMaxSataPortNum (); PortIndex++) {
+ mPchSataConfig.PortSettings[PortIndex].Enable = PCH_DEVICE_ENABLE;
+ mPchSataConfig.PortSettings[PortIndex].HotPlug = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].InterlockSw = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].External = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].SpinUp = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].SolidStateDrive = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].DevSlp = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].EnableDitoConfig = PCH_DEVICE_DISABLE;
+ mPchSataConfig.PortSettings[PortIndex].DmVal = 15;
+ mPchSataConfig.PortSettings[PortIndex].DitoVal = 625;
+ }
+
+ mPchSataConfig.RaidAlternateId = PCH_DEVICE_DISABLE;
+ mPchSataConfig.Raid0 = PCH_DEVICE_ENABLE;
+ mPchSataConfig.Raid1 = PCH_DEVICE_ENABLE;
+ mPchSataConfig.Raid10 = PCH_DEVICE_ENABLE;
+ mPchSataConfig.Raid5 = PCH_DEVICE_ENABLE;
+ mPchSataConfig.Irrt = PCH_DEVICE_ENABLE;
+ mPchSataConfig.OromUiBanner = PCH_DEVICE_ENABLE;
+ mPchSataConfig.HddUnlock = PCH_DEVICE_ENABLE;
+ mPchSataConfig.LedLocate = PCH_DEVICE_ENABLE;
+ mPchSataConfig.IrrtOnly = PCH_DEVICE_ENABLE;
+ mPchSataConfig.SmartStorage = PCH_DEVICE_ENABLE;
+ mPchSataConfig.OromUiDelay = PchSataOromDelay2sec;
+ mPchSataConfig.TestMode = PCH_DEVICE_DISABLE;
+ mPchSataConfig.SalpSupport = PCH_DEVICE_ENABLE;
+ mPchSataConfig.LegacyMode = PCH_DEVICE_DISABLE;
+ mPchSataConfig.SpeedSupport = PchSataSpeedSupportDefault;
+
+ ///
+ /// AzaliaConfig
+ ///
+ mPchAzaliaConfig.Pme = PCH_DEVICE_DISABLE;
+ mPchAzaliaConfig.ResetWaitTimer = 300;
+ mPchAzaliaConfig.DS = 1;
+ mPchAzaliaConfig.DA = 0;
+
+ ///
+ /// Reserved SMBus Address
+ ///
+ mPchSmbusConfig.NumRsvdSmbusAddresses = 4;
+ mPchSmbusConfig.RsvdSmbusAddressTable = mSmbusRsvdAddresses;
+
+ ///
+ /// MiscPm Configuration
+ ///
+ mPchMiscPmConfig.PchDeepSxPol = PchDeepSxPolDisable;
+ mPchMiscPmConfig.WakeConfig.PmeB0S5Dis = PCH_DEVICE_DISABLE;
+ mPchMiscPmConfig.WakeConfig.WolEnableOverride = PCH_DEVICE_DISABLE;
+ mPchMiscPmConfig.WakeConfig.Gp27WakeFromDeepSx = PCH_DEVICE_ENABLE;
+ mPchMiscPmConfig.WakeConfig.PcieWakeFromDeepSx = PCH_DEVICE_DISABLE;
+ mPchMiscPmConfig.PowerResetStatusClear.MeWakeSts = PCH_DEVICE_ENABLE;
+ mPchMiscPmConfig.PowerResetStatusClear.MeHrstColdSts = PCH_DEVICE_ENABLE;
+ mPchMiscPmConfig.PowerResetStatusClear.MeHrstWarmSts = PCH_DEVICE_ENABLE;
+
+ mPchMiscPmConfig.PchSlpS3MinAssert = PchSlpS350ms;
+ mPchMiscPmConfig.PchSlpS4MinAssert = PchSlpS44s;
+ mPchMiscPmConfig.PchSlpSusMinAssert = PchSlpSus4s;
+ mPchMiscPmConfig.PchSlpAMinAssert = PchSlpA2s;
+ mPchMiscPmConfig.PchPwrCycDur = 4; // 4-5 seconds (PCH default setting)
+ mPchMiscPmConfig.SlpStrchSusUp = PCH_DEVICE_DISABLE;
+ mPchMiscPmConfig.SlpLanLowDc = PCH_DEVICE_DISABLE;
+
+ ///
+ /// Io Apic configuration
+ ///
+ mPchIoApicConfig.BdfValid = 1;
+ mPchIoApicConfig.BusNumber = 0xF0;
+ mPchIoApicConfig.DeviceNumber = 0x1F;
+ mPchIoApicConfig.FunctionNumber = 0x00;
+ mPchIoApicConfig.IoApicEntry24_39 = PCH_DEVICE_ENABLE;
+
+ ///
+ /// Default Svid Sdid configuration
+ ///
+ mPchDefaultSvidSid.SubSystemVendorId = V_PCH_INTEL_VENDOR_ID;
+ mPchDefaultSvidSid.SubSystemId = V_PCH_DEFAULT_SID;
+
+ ///
+ /// Thermal configuration - Initialize policy to default values when variable isn't found.
+ ///
+ mPchThermalConfig.ThermalAlertEnable.TselLock = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalAlertEnable.TscLock = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalAlertEnable.TsmicLock = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalAlertEnable.PhlcLock = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalThrottling.TTLevels.SuggestedSetting = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalThrottling.TTLevels.PchCrossThrottling = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalThrottling.DmiHaAWC.SuggestedSetting = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalThrottling.SataTT.SuggestedSetting = PCH_DEVICE_ENABLE;
+ mPchThermalConfig.ThermalDeviceEnable = PCH_DEVICE_DISABLE;
+ ///
+ /// The value in this field is valid only if it is between 00h and 17Fh.
+ /// 0x17F is the hottest temperature and 0x000 is the lowest temperature
+ ///
+ mPchThermalConfig.PchHotLevel = 0x000;
+
+ ///
+ /// HEPT Configuration
+ ///
+ mPchHpetConfig.BdfValid = 1;
+ for (Index = 0; Index < PCH_HPET_BDF_MAX; Index++) {
+ mPchHpetConfig.Hpet[Index].BusNumber = 0xF0;
+ mPchHpetConfig.Hpet[Index].DeviceNumber = 0x0F;
+ mPchHpetConfig.Hpet[Index].FunctionNumber = 0x00;
+ }
+ ///
+ /// Initialize Serial IRQ Config
+ ///
+ mSerialIrqConfig.SirqEnable = TRUE;
+ mSerialIrqConfig.StartFramePulse = PchSfpw4Clk;
+ mSerialIrqConfig.SirqMode = PchContinuousMode;
+
+ ///
+ /// DMI related settings
+ ///
+ mPchDmiConfig.DmiAspm = PCH_DEVICE_ENABLE;
+ mPchDmiConfig.DmiExtSync = PCH_DEVICE_DISABLE;
+ mPchDmiConfig.DmiIot = PCH_DEVICE_DISABLE;
+
+ ///
+ /// Power Optimizer related settings
+ ///
+ mPchPwrOptConfig.PchPwrOptDmi = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.PchPwrOptGbe = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.PchPwrOptXhci = PCH_DEVICE_DISABLE;
+ mPchPwrOptConfig.PchPwrOptEhci = PCH_DEVICE_DISABLE;
+ mPchPwrOptConfig.PchPwrOptSata = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.MemCloseStateEn = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.InternalObffEn = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.ExternalObffEn = PCH_DEVICE_DISABLE; // De-feature OBFF from LPT-H/LPT-LP.
+ mPchPwrOptConfig.NumOfDevLtrOverride = 0;
+ mPchPwrOptConfig.DevLtrOverride = NULL;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrEnable = PCH_DEVICE_ENABLE;
+ //
+ // De-feature OBFF from LPT-H/LPT-LP.
+ // Doesn't enable Obff policy anymore.
+ //
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].ObffEnable = PCH_DEVICE_DISABLE;
+ }
+ mPchPwrOptConfig.LegacyDmaDisable = PCH_DEVICE_DISABLE;
+ for (PortIndex = 0; PortIndex < GetPchMaxPciePortNum (); PortIndex++) {
+ if (PchSeries == PchLp) {
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency = 0x1003;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency = 0x1003;
+ }
+ if (PchSeries == PchH) {
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrMaxSnoopLatency = 0x0846;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrMaxNoSnoopLatency = 0x0846;
+ }
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].LtrConfigLock = PCH_DEVICE_ENABLE;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].SnoopLatencyOverrideMode = 2;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].SnoopLatencyOverrideMultiplier = 2;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].SnoopLatencyOverrideValue = 60;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideMode = 2;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideMultiplier = 2;
+ mPchPwrOptConfig.PchPwrOptPcie[PortIndex].NonSnoopLatencyOverrideValue = 60;
+ }
+
+ ///
+ /// Misc. Config
+ ///
+ /// FviSmbiosType is the SMBIOS OEM type (0x80 to 0xFF) defined in SMBIOS Type 14 - Group
+ /// Associations structure - item type. FVI structure uses it as SMBIOS OEM type to provide
+ /// version information. The default value is type 221.
+ ///
+ mPchMiscConfig.FviSmbiosType = 0xDD;
+
+ ///
+ /// DCI (Direct Connect Interface) Configuration
+ ///
+ mPchMiscConfig.DciEn = PCH_DEVICE_DISABLE;
+
+ ///
+ /// Audio Dsp Configuration
+ ///
+ mAudioDspConfig.AudioDspD3PowerGating = PCH_DEVICE_ENABLE;
+ mAudioDspConfig.AudioDspAcpiMode = 1; //1: ACPI mode, 0: PCI mode
+ mAudioDspConfig.AudioDspAcpiInterruptMode = 1; //1: ACPI mode, 0: PCI mode
+ mAudioDspConfig.AudioDspBluetoothSupport = PCH_DEVICE_DISABLE; // Bluetooth SCO disabled
+
+ ///
+ /// Serial IO Configuration
+ ///
+ mSerialIoConfig.SerialIoMode = PchSerialIoIsAcpi;
+ switch(PchStepping()) {
+ default:
+ mSerialIoConfig.SerialIoInterruptMode = PchSerialIoIsAcpi;
+ break;
+ }
+ mSerialIoConfig.Ddr50Support = PCH_DEVICE_DISABLE;
+
+ mSerialIoConfig.I2c0VoltageSelect = PchSerialIoIs18V;
+ mSerialIoConfig.I2c1VoltageSelect = PchSerialIoIs33V;
+
+
+ ///
+ /// Update policy by platform setting
+ ///
+ UpdateDxePchPlatformPolicy (&mPchPolicyData);
+
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Update Precondition option for S4 resume.
+ /// Skip Precondition for S4 resume in case this boot may not connect BIOS USB driver.
+ /// If BIOS USB driver will be connected always for S4, then disable below update.
+ /// To keep consistency during boot, must enabled or disabled below function in both PEI and DXE
+ /// PlatformPolicyInit driver.
+ ///
+ if (mPchUsbConfig.UsbPrecondition == TRUE) {
+ if (GetBootModeHob () == BOOT_ON_S4_RESUME) {
+ mPchUsbConfig.UsbPrecondition = FALSE;
+ DEBUG ((EFI_D_INFO, "BootMode is BOOT_ON_S4_RESUME, disable Precondition\n"));
+ }
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gDxePchPlatformPolicyProtocolGuid,
+ &mPchPolicyData,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.dxs b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.dxs
new file mode 100644
index 0000000..0140fb2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.dxs
@@ -0,0 +1,44 @@
+/** @file
+ Dependency expression source file.
+
+@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 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
+#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
+#include EFI_PROTOCOL_DEFINITION (PlatformInfo)
+#include EFI_PROTOCOL_DEFINITION (CpuIo)
+
+DEPENDENCY_START
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ PLATFORM_INFO_PROTOCOL_GUID AND
+ EFI_CPU_IO_PROTOCOL_GUID
+DEPENDENCY_END \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.h
new file mode 100644
index 0000000..ae0cbae
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.h
@@ -0,0 +1,56 @@
+/** @file
+ Header file for the PchPolicyInitDxe 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 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
+**/
+#ifndef _PCH_PLATFORM_POLICY_DXE_H_
+#define _PCH_PLATFORM_POLICY_DXE_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 EFI_PROTOCOL_PRODUCER (PchPlatformPolicy)
+#include "PchAccess.h"
+#include "PchPlatformPolicyUpdateDxeLib.h"
+#include "PchPlatformLib.h"
+#endif
+
+//
+// Functions
+//
+
+/**
+ Initilize Intel PCH DXE Platform Policy
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in, out] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+PchPolicyInitDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN OUT EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.inf b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.inf
new file mode 100644
index 0000000..3b883ab
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Dxe/PchPolicyInitDxe.inf
@@ -0,0 +1,82 @@
+## @file
+# Component description file for the PchPolicyInitDxe DXE driver.
+#
+#@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 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 = PchPolicyInitDxe
+FILE_GUID = 3BC42C6D-ABEC-41ba-8CCB-D8E0EF1CEF85
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchPolicyInitDxe.h
+ PchPolicyInitDxe.c
+ ../Common/PchPolicyInitCommon.c
+ ../Common/PchPolicyInitCommon.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ .
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Pcd
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include/Library
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Core/Dxe
+ $(EDK_SOURCE)/Foundation/Cpu/Pentium/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
+ $(PLATFORM_ECP_PACKAGE)/Include
+
+[libraries.common]
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkFrameworkProtocolLib
+ EdkIIGlueDxeHobLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ PlatformPolicyUpdateDxeLib
+ EdkIIGlueDxeServicesTableLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchPolicyInitDxe.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchPolicyInitDxeEntryPoint
+ C_FLAGS = $(C_FLAGS) -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_HOB_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.c
new file mode 100644
index 0000000..08e0cf7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.c
@@ -0,0 +1,250 @@
+/** @file
+ This file is SampleCode for Intel PCH PEI Platform Policy initialzation.
+
+@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 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
+
+**/
+#include "PchPolicyInitPei.h"
+#include "..\Common\PchPolicyInitCommon.h"
+#ifdef RAPID_START_FLAG
+#include "RapidStartCommonLib.h"
+#endif
+
+/**
+ This PEIM performs PCH PEI Platform Policy initialzation.
+
+ @param[in] FfsHeader Pointer to Firmware File System file header.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchPolicyInitPeiEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PchPlatformPolicyPpiDesc;
+ PCH_PLATFORM_POLICY_PPI *PchPlatformPolicyPpi;
+ PCH_GBE_CONFIG *GbeConfig;
+ PCH_THERMAL_MANAGEMENT *ThermalMgmt;
+ PCH_MEMORY_THROTTLING *MemoryThrottling;
+ PCH_HPET_CONFIG *HpetConfig;
+ PCH_SATA_CONTROL *SataConfig;
+ PCH_SATA_TRACE_CONFIG *SataTraceConfig;
+ PCH_PCIE_CONFIG *PcieConfig;
+ PCH_IOAPIC_CONFIG *IoApicConfig;
+ PCH_PLATFORM_DATA *PlatformData;
+ PCH_USB_CONFIG *UsbConfig;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ EFI_BOOT_MODE BootMode;
+#endif // USB_PRECONDITION_ENABLE_FLAG
+ UINT8 PortIndex;
+
+ PchPlatformPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ ASSERT (PchPlatformPolicyPpiDesc != NULL);
+ if (PchPlatformPolicyPpiDesc == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PchPlatformPolicyPpi = (PCH_PLATFORM_POLICY_PPI *) AllocateZeroPool (sizeof (PCH_PLATFORM_POLICY_PPI));
+ ASSERT (PchPlatformPolicyPpi != NULL);
+ if (PchPlatformPolicyPpi == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ GbeConfig = (PCH_GBE_CONFIG *) AllocateZeroPool (sizeof (PCH_GBE_CONFIG));
+ ASSERT (GbeConfig != NULL);
+ if (GbeConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ThermalMgmt = (PCH_THERMAL_MANAGEMENT *) AllocateZeroPool (sizeof (PCH_THERMAL_MANAGEMENT));
+ ASSERT (ThermalMgmt != NULL);
+ if (ThermalMgmt == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemoryThrottling = (PCH_MEMORY_THROTTLING *) AllocateZeroPool (sizeof (PCH_MEMORY_THROTTLING));
+ ASSERT (MemoryThrottling != NULL);
+ if (MemoryThrottling == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ HpetConfig = (PCH_HPET_CONFIG *) AllocateZeroPool (sizeof (PCH_HPET_CONFIG));
+ ASSERT (HpetConfig != NULL);
+ if (HpetConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SataConfig = (PCH_SATA_CONTROL *) AllocateZeroPool (sizeof (PCH_SATA_CONTROL));
+ ASSERT (SataConfig != NULL);
+ if (SataConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SataTraceConfig = (PCH_SATA_TRACE_CONFIG *) AllocateZeroPool (sizeof (PCH_SATA_TRACE_CONFIG));
+ ASSERT (SataTraceConfig != NULL);
+ if (SataTraceConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PcieConfig = (PCH_PCIE_CONFIG *) AllocateZeroPool (sizeof (PCH_PCIE_CONFIG));
+ ASSERT (PcieConfig != NULL);
+ if (PcieConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IoApicConfig = (PCH_IOAPIC_CONFIG *) AllocateZeroPool (sizeof (PCH_IOAPIC_CONFIG));
+ ASSERT (IoApicConfig != NULL);
+ if (IoApicConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PlatformData = (PCH_PLATFORM_DATA *) AllocateZeroPool (sizeof (PCH_PLATFORM_DATA));
+ ASSERT (PlatformData != NULL);
+ if (PlatformData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UsbConfig = (PCH_USB_CONFIG *) AllocateZeroPool (sizeof (PCH_USB_CONFIG));
+ ASSERT (UsbConfig != NULL);
+ if (UsbConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ PchPlatformPolicyPpi->Revision = PCH_PLATFORM_POLICY_PPI_REVISION_4;
+ PchPlatformPolicyPpi->BusNumber = 0;
+ PchPlatformPolicyPpi->Rcba = PCH_LPC_RCBA_BASE_ADDRESS;
+ PchPlatformPolicyPpi->PmBase = PCH_LPC_ACPI_BASE_ADDRESS;
+ PchPlatformPolicyPpi->GpioBase = PCH_LPC_GPIO_BASE_ADDRESS;
+ PchPlatformPolicyPpi->Port80Route = 0;
+
+ PchPlatformPolicyPpi->GbeConfig = GbeConfig;
+ PchPlatformPolicyPpi->ThermalMgmt = ThermalMgmt;
+ PchPlatformPolicyPpi->HpetConfig = HpetConfig;
+ PchPlatformPolicyPpi->SataConfig = SataConfig;
+ PchPlatformPolicyPpi->PcieConfig = PcieConfig;
+ PchPlatformPolicyPpi->IoApicConfig = IoApicConfig;
+ PchPlatformPolicyPpi->PlatformData = PlatformData;
+ PchPlatformPolicyPpi->UsbConfig = UsbConfig;
+
+ GbeConfig->EnableGbe = 1;
+ ThermalMgmt->MemoryThrottling = MemoryThrottling;
+ MemoryThrottling->Enable = PCH_DEVICE_DISABLE;
+ MemoryThrottling->TsGpioPinSetting[TsGpioC].PmsyncEnable = PCH_DEVICE_ENABLE;
+ MemoryThrottling->TsGpioPinSetting[TsGpioD].PmsyncEnable = PCH_DEVICE_ENABLE;
+ MemoryThrottling->TsGpioPinSetting[TsGpioC].C0TransmitEnable = PCH_DEVICE_ENABLE;
+ MemoryThrottling->TsGpioPinSetting[TsGpioD].C0TransmitEnable = PCH_DEVICE_ENABLE;
+ MemoryThrottling->TsGpioPinSetting[TsGpioC].PinSelection = 1;
+ MemoryThrottling->TsGpioPinSetting[TsGpioD].PinSelection = 0;
+
+ HpetConfig->Enable = 1;
+ HpetConfig->Base = PCH_HPET_BASE_ADDRESS;
+
+ SataConfig->SataMode = PchSataModeAhci;
+ SataConfig->SataTraceConfig = SataTraceConfig;
+
+ SataTraceConfig->TestMode = PCH_DEVICE_DISABLE;
+ for( PortIndex = 0; PortIndex < 6; PortIndex++ ) {
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].Enable = PCH_DEVICE_DISABLE;
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].Enable = PCH_DEVICE_DISABLE;
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].Enable = PCH_DEVICE_DISABLE;
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[0].RxEq = 0x0;
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[1].RxEq = 0x0;
+ SataTraceConfig->PortRxEq[PortIndex].GenSpeed[2].RxEq = 0x0;
+ }
+
+ PcieConfig->PcieSpeed[0] = PchPcieAuto;
+ PcieConfig->PcieSpeed[1] = PchPcieAuto;
+ PcieConfig->PcieSpeed[2] = PchPcieAuto;
+ PcieConfig->PcieSpeed[3] = PchPcieAuto;
+ PcieConfig->PcieSpeed[4] = PchPcieAuto;
+ PcieConfig->PcieSpeed[5] = PchPcieAuto;
+ PcieConfig->PcieSpeed[6] = PchPcieAuto;
+ PcieConfig->PcieSpeed[7] = PchPcieAuto;
+
+ IoApicConfig->IoApicId = 0x02;
+ IoApicConfig->ApicRangeSelect = 0x00;
+ IoApicConfig->IoApicEntry24_39 = PCH_DEVICE_ENABLE;
+
+ PlatformData->EcPresent = 0;
+ ///
+ /// PlatformData->SmmBwp value directly depends on the value of CpuConfig->Pfat
+ /// (found in CpuPolicyInitPei.c file)
+ /// If CpuConfig->Pfat is set to 1 (enabled) then
+ /// PlatformData->SmmBwp has to be set to 1 (enabled)
+ /// This is a PFAT Security requirement that needs to be addressed
+ /// If CpuConfig->Pfat is set to 0 (disabled) then
+ /// PlatformData->SmmBwp value don't care, it can be set to either
+ /// 1 (enabled) or 0 (disabled) based on customer implementation
+ ///
+ PlatformData->SmmBwp = 0;
+
+ ///
+ /// Temporary Memory Base Address for PCI devices to be used to initialize MMIO registers.
+ /// Minimum size is 64KB bytes.
+ ///
+ PlatformData->TempMemBaseAddr = PCH_TEMP_MEM_BASE_ADDRESS;
+
+ ///
+ /// Init USB related setting
+ ///
+ InitPchUsbConfig (UsbConfig);
+
+ PchPlatformPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PchPlatformPolicyPpiDesc->Guid = &gPchPlatformPolicyPpiGuid;
+
+ UpdatePeiPchPlatformPolicy (PeiServices, PchPlatformPolicyPpi);
+#ifdef RAPID_START_FLAG
+ if (RapidStartResumeCheck () == TRUE) {
+ ///
+ /// This is RapidStart resume, skip the UsbPrecondition feature in PEI phase
+ ///
+ PchPlatformPolicyPpi->UsbConfig->UsbPrecondition = 0;
+ }
+#endif
+
+
+ PchPlatformPolicyPpiDesc->Ppi = PchPlatformPolicyPpi;
+#ifdef USB_PRECONDITION_ENABLE_FLAG
+ ///
+ /// Update Precondition option for S4 resume.
+ /// Skip Precondition for S4 resume in case this boot may not connect BIOS USB driver.
+ /// If BIOS USB driver will be connected always for S4, then disable below update.
+ /// To keep consistency during boot, must enabled or disabled below function in both PEI and DXE
+ /// PlatformPolicyInit driver.
+ ///
+ if (UsbConfig->UsbPrecondition == TRUE) {
+ (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S4_RESUME) {
+ UsbConfig->UsbPrecondition = FALSE;
+ DEBUG ((EFI_D_INFO, "BootMode is BOOT_ON_S4_RESUME, disable Precondition\n"));
+ }
+ }
+#endif // USB_PRECONDITION_ENABLE_FLAG
+
+ ///
+ /// Install PCH Platform Policy PPI
+ ///
+ Status = (**PeiServices).InstallPpi (PeiServices, PchPlatformPolicyPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.dxs b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.dxs
new file mode 100644
index 0000000..806a8d6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.dxs
@@ -0,0 +1,40 @@
+/** @file
+ Dependency expression source file.
+
+@copyright
+ Copyright (c) 2010 - 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"
+#include EFI_PPI_DEPENDENCY (Variable)
+#endif
+
+DEPENDENCY_START
+ PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.h
new file mode 100644
index 0000000..3d155b3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.h
@@ -0,0 +1,60 @@
+/** @file
+ Header file for the PchPeiPolicy 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 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
+**/
+#ifndef _PCH_POLICY_INIT_PEI_H_
+#define _PCH_POLICY_INIT_PEI_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 "EdkIIGluePeim.h"
+#include EFI_PPI_PRODUCER (PchPlatformPolicy)
+#include "PchAccess.h"
+#include "PchPlatformPolicyUpdatePeiLib.h"
+#endif
+
+#define PCH_LPC_RCBA_BASE_ADDRESS 0xFED1C000
+#define PCH_LPC_ACPI_BASE_ADDRESS 0x1800
+#define PCH_LPC_GPIO_BASE_ADDRESS 0x800
+
+#define PCH_TEMP_MEM_BASE_ADDRESS 0xDFFF0000
+#define PCH_HPET_BASE_ADDRESS 0xFED00000
+
+//
+// Functions
+//
+
+/**
+ This PEIM performs PCH PEI Platform Policy initialzation.
+
+ @param[in] FfsHeader Pointer to Firmware File System file header.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The PPI is installed and initialized.
+ @retval EFI ERRORS The PPI is not successfully installed.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver
+**/
+EFI_STATUS
+EFIAPI
+PchPolicyInitPeiEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.inf b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.inf
new file mode 100644
index 0000000..37ab29d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchPolicyInit/Pei/PchPolicyInitPei.inf
@@ -0,0 +1,87 @@
+## @file
+# Component description file for the PchPolicyInitPei 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 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 = PchPolicyInitPei
+FILE_GUID = 20596BCC-EF0D-4772-AB71-C5102620A013
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchPolicyInitPei.h
+ PchPolicyInitPei.c
+ ../Common/PchPolicyInitCommon.c
+ ../Common/PchPolicyInitCommon.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.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)/Ppi/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_RAPID_START_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_RAPID_START_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_RAPID_START_ROOT)/Samplecode/Library/RapidStartCommonLib
+#
+# 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
+ $(PLATFORM_ECP_PACKAGE)/Include
+
+[libraries.common]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkPpiLib
+ PlatformPolicyUpdatePeiLib
+ RapidStartCommonLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchPolicyInitPei.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PchPolicyInitPeiEntryPoint
+ 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__
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/PchSampleCode.cif b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchSampleCode.cif
new file mode 100644
index 0000000..f3282bf
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/PchSampleCode.cif
@@ -0,0 +1,34 @@
+<component>
+ name = "PchSampleCode"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SampleCode\"
+ RefName = "PchSampleCode"
+[files]
+"Ppi\SmbusPolicy\SmbusPolicy.h"
+"Ppi\UsbController\UsbController.h"
+"Guid\SmbusArpMap\SmbusArpMap.h"
+"Protocol\SmmSmbus\SmmSmbus.h"
+"PchPolicyInit\Pei\PchPolicyInitPei.dxs"
+"PchPolicyInit\Pei\PchPolicyInitPei.c"
+"PchPolicyInit\Pei\PchPolicyInitPei.h"
+"PchPolicyInit\Pei\PchPolicyInitPei.inf"
+"PchPolicyInit\Dxe\PchPolicyInitDxe.dxs"
+"PchPolicyInit\Dxe\PchPolicyInitDxe.c"
+"PchPolicyInit\Dxe\PchPolicyInitDxe.h"
+"PchPolicyInit\Dxe\PchPolicyInitDxe.inf"
+"BiosWriteProtect\Smm\PchBiosWriteProtect.c"
+"BiosWriteProtect\Smm\PchBiosWriteProtect.dxs"
+"BiosWriteProtect\Smm\PchBiosWriteProtect.h"
+"BiosWriteProtect\Smm\PchBiosWriteProtect.inf"
+"Include\Acpi3_0.h"
+"Include\PchAslUpdateLib.h"
+"PchPolicyInit\Common\PchPolicyInitCommon.c"
+"PchPolicyInit\Common\PchPolicyInitCommon.h"
+"AcpiTables\Dsdt\SerialIoDevices.asl"
+"AcpiTables\Dsdt\Sensor.asl"
+"Ppi\IntelPchSampleCodePpiLib.inf"
+"Ppi\SmmAccess\SmmAccess.c"
+"Ppi\SmmAccess\SmmAccess.h"
+[parts]
+"PchAslUpdateLib"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/IntelPchSampleCodePpiLib.inf b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/IntelPchSampleCodePpiLib.inf
new file mode 100644
index 0000000..b72ede5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/IntelPchSampleCodePpiLib.inf
@@ -0,0 +1,45 @@
+## @file
+# Component description file for the PEI protocol library
+#
+#@copyright
+# Copyright (c) 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 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 = IntelPchSampleCodePpiLib
+COMPONENT_TYPE = LIBRARY
+
+[sources.common]
+ SmmAccess/SmmAccess.h
+ SmmAccess/SmmAccess.c
+
+[includes.common]
+ $(EFI_SOURCE)
+ $(EDK_SOURCE)/Foundation
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Include/IndustryStandard
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/SampleCode
+
+[nmake.common]
+C_STD_INCLUDE=
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h
new file mode 100644
index 0000000..b43803b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmbusPolicy/SmbusPolicy.h
@@ -0,0 +1,38 @@
+/** @file
+ Smbus Policy PPI as defined in EFI 2.0
+
+@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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#ifndef _PEI_SMBUS_POLICY_PPI_H
+#define _PEI_SMBUS_POLICY_PPI_H
+
+#define PEI_SMBUS_POLICY_PPI_GUID \
+ { \
+ 0x63b6e435, 0x32bc, 0x49c6, 0x81, 0xbd, 0xb7, 0xa1, 0xa0, 0xfe, 0x1a, 0x6c \
+ }
+
+EFI_FORWARD_DECLARATION (PEI_SMBUS_POLICY_PPI);
+
+struct _PEI_SMBUS_POLICY_PPI {
+ UINTN BaseAddress;
+ UINT32 PciAddress;
+ UINT8 NumRsvdAddress;
+ UINT8 *RsvdAddress;
+};
+
+extern EFI_GUID gPeiSmbusPolicyPpiGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c
new file mode 100644
index 0000000..85ab194
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.c
@@ -0,0 +1,25 @@
+/** @file
+ SmmAccess PPI GUID
+
+@copyright
+ Copyright (c) 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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#include "Tiano.h"
+#include "Pei.h"
+#include EFI_PPI_DEFINITION (SmmAccess)
+
+EFI_GUID gPeiSmmAccessPpiGuid = PEI_SMM_ACCESS_PPI_GUID;
+
+EFI_GUID_STRING(&gPeiSmmAccessPpiGuid, "SmmAccess", "SMM Access PPI");
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h
new file mode 100644
index 0000000..4873b1a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/SmmAccess/SmmAccess.h
@@ -0,0 +1,136 @@
+/** @file
+ This code abstracts the PEI core to provide SmmAccess services.
+
+@copyright
+ Copyright (c) 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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#ifndef _PEI_SMM_ACCESS_PPI_H_
+#define _PEI_SMM_ACCESS_PPI_H_
+
+#include EFI_GUID_DEFINITION (SmramMemoryReserve)
+
+#define PEI_SMM_ACCESS_PPI_GUID \
+ { \
+ 0x268f33a9, 0xcccd, 0x48be, 0x88, 0x17, 0x86, 0x5, 0x3a, 0xc3, 0x2e, 0xd6 \
+ }
+
+EFI_FORWARD_DECLARATION (PEI_SMM_ACCESS_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_OPEN) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI * This,
+ IN UINTN DescriptorIndex
+ )
+/**
+ This routine accepts a request to "open" a region of SMRAM. The
+ region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+ The use of "open" means that the memory is visible from all PEIM
+ and SMM agents.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+ @param[in] DescriptorIndex - Region of SMRAM to Open.
+
+ @retval EFI_SUCCESS - The region was successfully opened.
+ @retval EFI_DEVICE_ERROR - The region could not be opened because locked by
+ chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CLOSE) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI * This,
+ IN UINTN DescriptorIndex
+ )
+/**
+ This routine accepts a request to "close" a region of SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "close" means that the memory is only visible from SMM agents,
+ not from PEIM.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+ @param[in] DescriptorIndex - Region of SMRAM to Close.
+
+ @retval EFI_SUCCESS - The region was successfully closed.
+ @retval EFI_DEVICE_ERROR - The region could not be closed because locked by
+ chipset.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_LOCK) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI * This,
+ IN UINTN DescriptorIndex
+ )
+/**
+ This routine accepts a request to "lock" SMRAM. The
+ region could be legacy AB or TSEG near top of physical memory.
+ The use of "lock" means that the memory can no longer be opened
+ to PEIM.
+
+ @param[in] This - Pointer to the SMM Access Interface.
+ @param[in] DescriptorIndex - Region of SMRAM to Lock.
+
+ @retval EFI_SUCCESS - The region was successfully locked.
+ @retval EFI_DEVICE_ERROR - The region could not be locked because at least
+ one range is still open.
+ @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+;
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SMM_CAPABILITIES) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_ACCESS_PPI * This,
+ IN OUT UINTN *SmramMapSize,
+ IN OUT EFI_SMRAM_DESCRIPTOR * SmramMap
+ )
+/**
+ This routine services a user request to discover the SMRAM
+ capabilities of this platform. This will report the possible
+ ranges that are possible for SMRAM access, based upon the
+ memory controller capabilities.
+
+ @param[in] This - Pointer to the SMRAM Access Interface.
+ @param[in] SmramMapSize - Pointer to the variable containing size of the
+ buffer to contain the description information.
+ @param[in] SmramMap - Buffer containing the data describing the Smram
+ region descriptors.
+
+ @retval EFI_BUFFER_TOO_SMALL - The user did not provide a sufficient buffer.
+ @retval EFI_SUCCESS - The user provided a sufficiently-sized buffer.
+**/
+;
+
+struct _PEI_SMM_ACCESS_PPI {
+ PEI_SMM_OPEN Open;
+ PEI_SMM_CLOSE Close;
+ PEI_SMM_LOCK Lock;
+ PEI_SMM_CAPABILITIES GetCapabilities;
+ BOOLEAN LockState;
+ BOOLEAN OpenState;
+};
+
+extern EFI_GUID gPeiSmmAccessPpiGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/UsbController/UsbController.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/UsbController/UsbController.h
new file mode 100644
index 0000000..2fec82f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Ppi/UsbController/UsbController.h
@@ -0,0 +1,49 @@
+/** @file
+ Usb Controller PPI as defined in EFI 2.0
+
+ This code abstracts the PEI core to provide Usb Controller Info from Chipset.
+
+@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 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+**/
+#ifndef _PEI_USB_CONTROLLER_PPI_H_
+#define _PEI_USB_CONTROLLER_PPI_H_
+
+#define PEI_USB_CONTROLLER_PPI_GUID \
+ { \
+ 0x3bc1f6de, 0x693e, 0x4547, 0xa3, 0x0, 0x21, 0x82, 0x3c, 0xa4, 0x20, 0xb2 \
+ }
+
+#define PEI_EHCI_CONTROLLER 0x03
+
+EFI_FORWARD_DECLARATION (PEI_USB_CONTROLLER_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_GET_USB_CONTROLLER) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_CONTROLLER_PPI *This,
+ IN UINT8 UsbControllerId,
+ OUT UINTN *ControllerType,
+ OUT UINTN *BaseAddress
+ );
+
+struct _PEI_USB_CONTROLLER_PPI {
+ PEI_GET_USB_CONTROLLER GetUsbController;
+};
+
+extern EFI_GUID gPeiUsbControllerPpiGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SampleCode/Protocol/SmmSmbus/SmmSmbus.h b/ReferenceCode/Chipset/LynxPoint/SampleCode/Protocol/SmmSmbus/SmmSmbus.h
new file mode 100644
index 0000000..8b792ac
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SampleCode/Protocol/SmmSmbus/SmmSmbus.h
@@ -0,0 +1,50 @@
+/** @file
+ SmmSmbus Protocol
+
+@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 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
+**/
+#ifndef __EFI_SMM_SMBUS_PROTOCOL_H__
+#define __EFI_SMM_SMBUS_PROTOCOL_H__
+
+///
+/// GUID for the SmmSmbus Protocol
+///
+/// EDK and EDKII have different GUID formats
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+
+#define EFI_SMM_SMBUS_PROTOCOL_GUID \
+ { \
+ 0x72e40094, 0x2ee1, 0x497a, 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc \
+ }
+#else
+#define EFI_SMM_SMBUS_PROTOCOL_GUID \
+ { \
+ 0x72e40094, 0x2ee1, 0x497a, \
+ { \
+ 0x8f, 0x33, 0x4c, 0x93, 0x4a, 0x9e, 0x9c, 0xc \
+ } \
+ }
+
+#endif
+//
+// Resuse the DXE definition, and use another GUID.
+//
+typedef EFI_SMBUS_HC_PROTOCOL SMM_SMBUS_HC_PROTOCOL;
+
+extern EFI_GUID gEfiSmmSmbusProtocolGuid;
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.c b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.c
new file mode 100644
index 0000000..c53575c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.c
@@ -0,0 +1,943 @@
+/** @file
+ This driver module produces IDE_CONTROLLER_INIT protocol for serial ATA
+ driver and will be used by IDE Bus driver to support chipset dependent timing
+ information, config SATA control/status registers. This driver
+ is responsible for early initialization of serial ATA controller.
+
+ Serial ATA spec requires SATA controller compatible with parallel IDE
+ controller. That's why lots of code here is the same with IDE controller
+ driver. However, We need this driver to optimize timing settings for SATA
+ device and set SATA config/error/status registers.
+
+@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 o f 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 "SataController.h"
+
+///
+/// SATA controller Driver GUID
+///
+EFI_GUID gSataControllerDriverGuid = PCH_SATA_CONTROLLER_DRIVER_GUID;
+
+///
+/// EFI_DRIVER_BINDING_PROTOCOL instance
+///
+EFI_DRIVER_BINDING_PROTOCOL mSataControllerDriverBinding = {
+ SataControllerSupported,
+ SataControllerStart,
+ SataControllerStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+//
+// Internal function definitions
+//
+EFI_STATUS
+CalculateBestPioMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisPioMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ );
+
+EFI_STATUS
+CalculateBestUdmaMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisUDmaMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ );
+
+/**
+ Chipset SATA Driver EntryPoint function. It follows the standard EFI driver
+ model. It's called by StartImage() of DXE Core
+
+ @param[in] ImageHandle While the driver image loaded be the ImageLoader(),
+ an image handle is assigned to this driver binary,
+ all activities of the driver is tied to this ImageHandle
+ @param[in] SystemTable A pointer to the system table, for all BS(Boo Services) and
+ RT(Runtime Services)
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializeSataControllerDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This function checks to see if the driver supports a device specified by
+ "Controller handle" parameter. It is called by DXE Core StartImage() or
+ ConnectController() routines. The driver uses 'device path' and/or
+ 'services' from the Bus I/O abstraction attached to the controller handle
+ to determine if the driver support this controller handle.
+ Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all
+ devices (or, controller) and assigns GUIDs to them.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested.
+ @param[in] RemainingDevicePath A pointer to the device path. Ignored by device
+ driver but used by bus driver
+
+ @retval EFI_SUCCESS The device is supported
+ @exception EFI_UNSUPPORTED The device is not supported
+**/
+EFI_STATUS
+EFIAPI
+SataControllerSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SataDeviceIdFound;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 PciData;
+
+ ///
+ /// SATA Controller is a device driver, and should ingore the
+ /// "RemainingDevicePath" according to EFI spec
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ ///
+ /// EFI_ALREADY_STARTED is also an error
+ ///
+ return Status;
+ }
+ ///
+ /// Close the protocol because we don't use it here
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ ///
+ /// Now test the EfiPciIoProtocol
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Now further check the PCI header: Base class (offset 0x0B) and
+ /// Sub Class (offset 0x0A). This controller should be an SATA controller
+ ///
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciData),
+ &PciData
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points.
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ ///
+ /// Examine SATA PCI Configuration table fields
+ ///
+ SataDeviceIdFound = FALSE;
+ ///
+ /// When found is storage device and provided by Intel then detect for right device Ids
+ ///
+ if (PciData.Hdr.VendorId == V_PCH_SATA_VENDOR_ID) {
+ if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE)) {
+ if ((PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_IDE)) {
+ if (IS_PCH_LPT_SATA_IDE_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_AHCI) {
+ if (IS_PCH_LPT_SATA_AHCI_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_RAID) {
+ if (IS_PCH_LPT_SATA_RAID_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!SataDeviceIdFound) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+/**
+ This routine is called right after the .Supported() is called and returns
+ EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
+ are closed.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested. Parameter
+ passed by the caller
+ @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by
+ device driver
+
+ @retval EFI_SUCCESS The device is started
+ @retval Other values Something error happened
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ PCI_TYPE00 PciData;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ UINT64 CommandVal;
+
+ DEBUG ((EFI_D_INFO, "SataControllerStart() Start\n"));
+
+ SataPrivateData = NULL;
+ ///
+ /// Now test and open the EfiPciIoProtocol
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ ///
+ /// Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
+ /// Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
+ /// that the protocol has been opened and should be treated as a
+ /// normal condition and the program proceeds. The Protocol will not
+ /// opened 'again' by this call.
+ /// Status != ALREADY_STARTED - Error status, terminate program execution
+ ///
+ if (EFI_ERROR (Status)) {
+ ///
+ /// EFI_ALREADY_STARTED is also an error
+ ///
+ return Status;
+ }
+ ///
+ /// Allocate SATA private data structure
+ ///
+ SataPrivateData = AllocatePool (sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
+ if (SataPrivateData == NULL) {
+ DEBUG ((EFI_D_ERROR, "SATA Controller START ERROR: Allocating pool for IdePrivateData failed!\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ ///
+ /// Initialize SATA private data
+ ///
+ ZeroMem (SataPrivateData, sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
+ SataPrivateData->Signature = SATA_CONTROLLER_SIGNATURE;
+ SataPrivateData->PciIo = PciIo;
+ SataPrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
+ SataPrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase;
+ SataPrivateData->IdeInit.SubmitData = IdeInitSubmitData;
+ SataPrivateData->IdeInit.DisqualifyMode = IdeInitDisqualifyMode;
+ SataPrivateData->IdeInit.CalculateMode = IdeInitCalculateMode;
+ SataPrivateData->IdeInit.SetTiming = IdeInitSetTiming;
+ SataPrivateData->IdeInit.EnumAll = PCH_SATA_ENUMER_ALL;
+
+ Status = PciIo->GetLocation (
+ PciIo,
+ &SegNum,
+ &BusNum,
+ &DevNum,
+ &FuncNum
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciData),
+ &PciData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Get device capabilities
+ ///
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &CommandVal
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Enable Command Register
+ ///
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ CommandVal & EFI_PCI_DEVICE_ENABLE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_IDE) {
+ SataPrivateData->IdeInit.ChannelCount = PCH_IDE_1_MAX_CHANNELS;
+ } else if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_AHCI ||
+ PciData.Hdr.ClassCode[1] == V_PCH_SATA_SUB_CLASS_CODE_RAID) {
+ ///
+ /// Default MAX port number
+ ///
+ SataPrivateData->IdeInit.ChannelCount = GetPchMaxSataPortNum ();
+ }
+ ///
+ /// Install IDE_CONTROLLER_INIT protocol & private data to this instance
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gSataControllerDriverGuid,
+ SataPrivateData,
+ &gEfiIdeControllerInitProtocolGuid,
+ &(SataPrivateData->IdeInit),
+ NULL
+ );
+
+Done:
+
+ if (EFI_ERROR (Status)) {
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (SataPrivateData != NULL) {
+ FreePool (SataPrivateData);
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "SataControllerStart() End\n"));
+
+ return Status;
+}
+
+/**
+ Stop managing the target device
+
+ @param[in] This A pointer pointing to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be stopped
+ @param[in] NumberOfChildren Number of child devices
+ @param[in] ChildHandleBuffer Buffer holding child device handles
+
+ @retval EFI_SUCCESS The target device is stopped
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+
+ DEBUG ((EFI_D_INFO, "SataControllerStop() Start\n"));
+
+ ///
+ /// Get private data
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gSataControllerDriverGuid,
+ (VOID **) &SataPrivateData,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gSataControllerDriverGuid,
+ SataPrivateData,
+ &gEfiIdeControllerInitProtocolGuid,
+ &(SataPrivateData->IdeInit),
+ NULL
+ );
+ }
+ ///
+ /// Close protocols opened by SATA controller driver
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ if (SataPrivateData != NULL) {
+ FreePool (SataPrivateData);
+ }
+
+ DEBUG ((EFI_D_INFO, "SataControllerStop() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+//
+// Interface functions of IDE_CONTROLLER_INIT protocol
+//
+
+/**
+ This function can be used to obtain information about a specified channel.
+ It's usually used by IDE Bus driver during enumeration process.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+ @param[out] Enabled TRUE if the channel is enabled. If the channel is disabled,
+ then it will no be enumerated.
+ @param[out] MaxDevices The Max number of IDE devices that the bus driver can expect
+ on this channel. For ATA/ATAPI, this number is either 1 or 2.
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval Other Values Something error happened
+ @retval EFI_INVALID_PARAMETER The Channel parameter is invalid
+**/
+EFI_STATUS
+EFIAPI
+IdeInitGetChannelInfo (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ OUT BOOLEAN *Enabled,
+ OUT UINT8 *MaxDevices
+ )
+{
+ ///
+ /// Channel number (0 based, either 0 or 1)
+ ///
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if (Channel < This->ChannelCount) {
+ *Enabled = TRUE;
+ *MaxDevices = PCH_IDE_1_MAX_DEVICES;
+ return EFI_SUCCESS;
+ } else {
+ *Enabled = FALSE;
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ This function is called by IdeBus driver before executing certain actions.
+ This allows IDE Controller Init to prepare for each action.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Phase phase indicator defined by IDE_CONTROLLER_INIT protocol
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter is out of range
+ @exception EFI_UNSUPPORTED Phase is not supported
+**/
+EFI_STATUS
+EFIAPI
+IdeInitNotifyPhase (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
+ IN UINT8 Channel
+ )
+{
+ if (Channel >= This->ChannelCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Phase) {
+
+ case EfiIdeBeforeChannelEnumeration:
+ case EfiIdeAfterChannelEnumeration:
+ case EfiIdeBeforeChannelReset:
+ case EfiIdeAfterChannelReset:
+ case EfiIdeBusBeforeDevicePresenceDetection:
+ case EfiIdeBusAfterDevicePresenceDetection:
+ case EfiIdeResetMode:
+ ///
+ /// Do nothing at present
+ ///
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
+ obtained from IDE deivce. This structure is used to set IDE timing
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel or Device parameter is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSubmitData (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_IDENTIFY_DATA *IdentifyData
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (Device >= PCH_IDE_1_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Make a local copy of device's IdentifyData and mark the valid flag
+ ///
+ if (IdentifyData != NULL) {
+ CopyMem (
+ &(SataPrivateData->IdentifyData[Channel][Device]),
+ IdentifyData,
+ sizeof (EFI_IDENTIFY_DATA)
+ );
+
+ SataPrivateData->IdentifyValid[Channel][Device] = TRUE;
+ } else {
+ SataPrivateData->IdentifyValid[Channel][Device] = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to disqualify unsupported operation
+ mode on specfic IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] BadModes Operation mode indicator
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Devicde parameter is out of range,
+ or BadModes is NULL
+**/
+EFI_STATUS
+EFIAPI
+IdeInitDisqualifyMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *BadModes
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= PCH_IDE_1_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Record the disqualified modes per channel per device. From ATA/ATAPI spec,
+ /// if a mode is not supported, the modes higher than it is also not
+ /// supported
+ ///
+ CopyMem (
+ &(SataPrivateData->DisqulifiedModes[Channel][Device]),
+ BadModes,
+ sizeof (EFI_ATA_COLLECTIVE_MODE)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to calculate the best operation mode
+ supported by specific IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in, out] SupportedModes Modes collection supported by IDE device
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Device parameter is out of range;
+ Or SupportedModes is NULL
+ @retval EFI_NOT_READY Identify data is not valid
+ @retval EFI_OUT_OF_RESOURCES SupportedModes is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitCalculateMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ EFI_IDENTIFY_DATA *IdentifyData;
+ BOOLEAN IdentifyValid;
+ EFI_ATA_COLLECTIVE_MODE *DisqulifiedModes;
+ UINT16 SelectedMode;
+ EFI_STATUS Status;
+
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= PCH_IDE_1_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IdentifyData = &(SataPrivateData->IdentifyData[Channel][Device]);
+ DisqulifiedModes = &(SataPrivateData->DisqulifiedModes[Channel][Device]);
+ IdentifyValid = SataPrivateData->IdentifyValid[Channel][Device];
+
+ ///
+ /// Make sure we've got the valid identify data of the device from SubmitData()
+ ///
+ if (!IdentifyValid) {
+ return EFI_NOT_READY;
+ }
+
+ *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
+ if (*SupportedModes == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = CalculateBestPioMode (
+ IdentifyData,
+ (DisqulifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqulifiedModes->PioMode.Mode)) : NULL),
+ &SelectedMode
+ );
+ if (!EFI_ERROR (Status)) {
+ (*SupportedModes)->PioMode.Valid = TRUE;
+ (*SupportedModes)->PioMode.Mode = SelectedMode;
+
+ } else {
+ (*SupportedModes)->PioMode.Valid = FALSE;
+ }
+
+ Status = CalculateBestUdmaMode (
+ IdentifyData,
+ (DisqulifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqulifiedModes->UdmaMode.Mode)) : NULL),
+ &SelectedMode
+ );
+
+ if (!EFI_ERROR (Status)) {
+ (*SupportedModes)->UdmaMode.Valid = TRUE;
+ (*SupportedModes)->UdmaMode.Mode = SelectedMode;
+
+ } else {
+ (*SupportedModes)->UdmaMode.Valid = FALSE;
+ }
+ ///
+ /// The modes other than PIO and UDMA are not supported by SATA controller
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to set appropriate timing on IDE
+ controller according supported operation mode
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] Modes Operation modes
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSetTiming (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *Modes
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is used to calculate the best PIO mode supported by
+ specific IDE device
+
+ @param[in] IdentifyData The identify data of specific IDE device
+ @param[in] DisPioMode Disqualified PIO modes collection
+ @param[out] SelectedMode Available PIO modes collection
+
+ @retval EFI_SUCCESS Function completes successfully
+ @exception EFI_UNSUPPORTED Some invalid condition
+**/
+EFI_STATUS
+CalculateBestPioMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisPioMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ )
+{
+ UINT16 PioMode;
+ UINT16 AdvancedPioMode;
+ UINT16 Temp;
+ UINT16 Index;
+ UINT16 MinimumPioCycleTime;
+
+ Temp = 0xff;
+
+ PioMode = (UINT8) (IdentifyData->AtaData.pio_cycle_timing >> 8);
+
+ ///
+ /// see whether Identify Data word 64 - 70 are valid
+ ///
+ if ((IdentifyData->AtaData.field_validity & 0x02) == 0x02) {
+
+ AdvancedPioMode = IdentifyData->AtaData.advanced_pio_modes;
+
+ for (Index = 0; Index < 8; Index++) {
+ if ((AdvancedPioMode & 0x01) != 0) {
+ Temp = Index;
+ }
+
+ AdvancedPioMode >>= 1;
+ }
+ ///
+ /// if Temp is modified, meant the advanced_pio_modes is not zero;
+ /// if Temp is not modified, meant the no advanced PIO Mode is supported,
+ /// the best PIO Mode is the value in pio_cycle_timing.
+ ///
+ if (Temp != 0xff) {
+ AdvancedPioMode = (UINT16) (Temp + 3);
+ } else {
+ AdvancedPioMode = PioMode;
+ }
+ ///
+ /// Limit the PIO mode to at most PIO4.
+ ///
+ PioMode = (UINT16) (AdvancedPioMode < 4 ? AdvancedPioMode : 4);
+
+ MinimumPioCycleTime = IdentifyData->AtaData.min_pio_cycle_time_with_flow_control;
+
+ if (MinimumPioCycleTime <= 120) {
+ PioMode = (UINT16) (4 < PioMode ? 4 : PioMode);
+ } else if (MinimumPioCycleTime <= 180) {
+ PioMode = (UINT16) (3 < PioMode ? 3 : PioMode);
+ } else if (MinimumPioCycleTime <= 240) {
+ PioMode = (UINT16) (2 < PioMode ? 2 : PioMode);
+ } else {
+ PioMode = 0;
+ }
+ ///
+ /// Degrade the PIO mode if the mode has been disqualified
+ ///
+ if (DisPioMode != NULL) {
+
+ if (*DisPioMode < 2) {
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_PIO_MODE_BELOW_2
+ ///
+ }
+
+ if (PioMode >= *DisPioMode) {
+ PioMode = (UINT16) (*DisPioMode - 1);
+ }
+ }
+
+ if (PioMode < 2) {
+ *SelectedMode = 1;
+ ///
+ /// ATA_PIO_MODE_BELOW_2;
+ ///
+ } else {
+ *SelectedMode = PioMode;
+ ///
+ /// ATA_PIO_MODE_2 to ATA_PIO_MODE_4;
+ ///
+ }
+
+ } else {
+ ///
+ /// Identify Data word 64 - 70 are not valid
+ /// Degrade the PIO mode if the mode has been disqualified
+ ///
+ if (DisPioMode != NULL) {
+
+ if (*DisPioMode < 2) {
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_PIO_MODE_BELOW_2
+ ///
+ }
+
+ if (PioMode == *DisPioMode) {
+ PioMode--;
+ }
+ }
+
+ if (PioMode < 2) {
+ *SelectedMode = 1;
+ ///
+ /// ATA_PIO_MODE_BELOW_2;
+ ///
+ } else {
+ *SelectedMode = 2;
+ ///
+ /// ATA_PIO_MODE_2;
+ ///
+ }
+
+ }
+
+ DEBUG ((EFI_D_ERROR, "CalculateBestPioMode() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is used to calculate the best UDMA mode supported by
+ specific IDE device
+
+ @param[in] IdentifyData The identify data of specific IDE device
+ @param[in] DisUDmaMode Disqualified UDMA modes collection
+ @param[out] SelectedMode Available UMDA modes collection
+
+ @retval EFI_SUCCESS Function completes successfully
+ @exception EFI_UNSUPPORTED Some invalid condition
+**/
+EFI_STATUS
+CalculateBestUdmaMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisUDmaMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ )
+{
+ UINT16 TempMode;
+ UINT16 DeviceUDmaMode;
+
+ DeviceUDmaMode = 0;
+ ///
+ /// flag for 'Udma mode is not supported'
+ ///
+ /// Check whether the WORD 88 (supported UltraDMA by drive) is valid
+ ///
+ if ((IdentifyData->AtaData.field_validity & 0x04) == 0x00) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DeviceUDmaMode = IdentifyData->AtaData.ultra_dma_mode;
+ DeviceUDmaMode &= 0x3f;
+ TempMode = 0;
+ ///
+ /// initialize it to UDMA-0
+ ///
+ while ((DeviceUDmaMode >>= 1) != 0) {
+ TempMode++;
+ }
+ ///
+ /// Degrade the UDMA mode if the mode has been disqualified
+ ///
+ if (DisUDmaMode != NULL) {
+ if (*DisUDmaMode == 0) {
+ *SelectedMode = 0;
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_UDMA_MODE_0
+ ///
+ }
+
+ if (TempMode >= *DisUDmaMode) {
+ TempMode = (UINT16) (*DisUDmaMode - 1);
+ }
+ }
+ ///
+ /// Possible returned mode is between ATA_UDMA_MODE_0 and ATA_UDMA_MODE_5
+ ///
+ *SelectedMode = TempMode;
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.cif b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.cif
new file mode 100644
index 0000000..1ad423f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "SataController"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SataController\Dxe"
+ RefName = "SataController"
+[files]
+"SataController.sdl"
+"SataController.mak"
+"SataController.c"
+"SataController.h"
+"SataControllerName.c"
+"SataController.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.h b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.h
new file mode 100644
index 0000000..45b6f8a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.h
@@ -0,0 +1,323 @@
+/** @file
+ Header file for chipset Serial ATA controller 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 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 _SERIAL_ATA_CONTROLLER_H_
+#define _SERIAL_ATA_CONTROLLER_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 "pci22.h"
+#include "EFIScriptLib.h"
+
+#include EFI_PROTOCOL_PRODUCER (IdeControllerInit)
+#include EFI_PROTOCOL_CONSUMER (PciIo)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+//
+// Global Variables definitions
+//
+extern EFI_DRIVER_BINDING_PROTOCOL mSataControllerDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL mSataControllerName;
+extern UINTN mPchGpioBase;
+
+///
+/// {BB929DA9-68F7-4035-B22C-A3BB3F23DA55}
+///
+///
+/// Define the protocol GUID
+///
+/// Only EdkII defines EDK_RELEASE_VERSION as 0x00020000
+///
+#if (EDK_RELEASE_VERSION != 0x00020000)
+#define PCH_SATA_CONTROLLER_DRIVER_GUID \
+ { \
+ 0xbb929da9, 0x68f7, 0x4035, 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55 \
+ };
+#else
+#define PCH_SATA_CONTROLLER_DRIVER_GUID \
+ { \
+ 0xbb929da9, 0x68f7, 0x4035, \
+ { \
+ 0xb2, 0x2c, 0xa3, 0xbb, 0x3f, 0x23, 0xda, 0x55 \
+ } \
+ };
+#endif
+
+#define PCH_SATA_ENUMER_ALL FALSE
+
+#define PCH_SATA_MASTER_DRIVE 0x00
+#define PCH_SATA_SLAVE_DRIVE 0x01
+
+///
+/// SATA controller driver private data structure
+///
+#define SATA_CONTROLLER_SIGNATURE EFI_SIGNATURE_32 ('S', 'A', 'T', 'A')
+
+typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
+ ///
+ /// Standard signature used to identify SATA controller private data
+ ///
+ UINT32 Signature;
+
+ ///
+ /// Protocol instance of IDE_CONTROLLER_INIT produced by this driver
+ ///
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL IdeInit;
+
+ ///
+ /// copy of protocol pointers used by this driver
+ ///
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ ///
+ /// The highest disqulified mode for each attached SATA device.
+ /// Per ATA/ATAPI spec, if a mode is not supported, the modes higher than
+ /// it should not be supported
+ ///
+ EFI_ATA_COLLECTIVE_MODE DisqulifiedModes[LPTH_AHCI_MAX_PORTS][PCH_IDE_1_MAX_DEVICES];
+
+ ///
+ /// A copy of IDENTIFY data for each attached SATA device and its flag
+ ///
+ EFI_IDENTIFY_DATA IdentifyData[LPTH_AHCI_MAX_PORTS][PCH_IDE_1_MAX_DEVICES];
+ BOOLEAN IdentifyValid[LPTH_AHCI_MAX_PORTS][PCH_IDE_1_MAX_DEVICES];
+} EFI_SATA_CONTROLLER_PRIVATE_DATA;
+
+#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) \
+ CR ( \
+ a, \
+ EFI_SATA_CONTROLLER_PRIVATE_DATA, \
+ IdeInit, \
+ SATA_CONTROLLER_SIGNATURE \
+ )
+
+//
+// Driver binding functions declaration
+//
+
+/**
+ This function checks to see if the driver supports a device specified by
+ "Controller handle" parameter. It is called by DXE Core StartImage() or
+ ConnectController() routines. The driver uses 'device path' and/or
+ 'services' from the Bus I/O abstraction attached to the controller handle
+ to determine if the driver support this controller handle.
+ Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all
+ devices (or, controller) and assigns GUIDs to them.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested.
+ @param[in] RemainingDevicePath A pointer to the device path. Ignored by device
+ driver but used by bus driver
+
+ @retval EFI_SUCCESS The device is supported
+ @exception EFI_UNSUPPORTED The device is not supported
+**/
+EFI_STATUS
+EFIAPI
+SataControllerSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ This routine is called right after the .Supported() is called and returns
+ EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
+ are closed.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested. Parameter
+ passed by the caller
+ @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by
+ device driver
+
+ @retval EFI_SUCCESS The device is started
+ @retval Other values Something error happened
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop managing the target device
+
+ @param[in] This A pointer pointing to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be stopped
+ @param[in] NumberOfChildren Number of child devices
+ @param[in] ChildHandleBuffer Buffer holding child device handles
+
+ @retval EFI_SUCCESS The target device is stopped
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// IDE controller init functions declaration
+//
+
+/**
+ This function can be used to obtain information about a specified channel.
+ It's usually used by IDE Bus driver during enumeration process.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+ @param[out] Enabled TRUE if the channel is enabled. If the channel is disabled,
+ then it will no be enumerated.
+ @param[out] MaxDevices The Max number of IDE devices that the bus driver can expect
+ on this channel. For ATA/ATAPI, this number is either 1 or 2.
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval Other Values Something error happened
+ @retval EFI_INVALID_PARAMETER The Channel parameter is invalid
+**/
+EFI_STATUS
+EFIAPI
+IdeInitGetChannelInfo (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ OUT BOOLEAN *Enabled,
+ OUT UINT8 *MaxDevices
+ );
+
+/**
+ This function is called by IdeBus driver before executing certain actions.
+ This allows IDE Controller Init to prepare for each action.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Phase phase indicator defined by IDE_CONTROLLER_INIT protocol
+ @param[out] Channel Channel number (0 based, either 0 or 1)
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter is out of range
+ @exception EFI_UNSUPPORTED Phase is not supported
+**/
+EFI_STATUS
+EFIAPI
+IdeInitNotifyPhase (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
+ OUT UINT8 Channel
+ );
+
+/**
+ This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
+ obtained from IDE deivce. This structure is used to set IDE timing
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel or Device parameter is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSubmitData (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_IDENTIFY_DATA *IdentifyData
+ );
+
+/**
+ This function is called by IdeBus driver to disqualify unsupported operation
+ mode on specfic IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] BadModes Operation mode indicator
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Devicde parameter is out of range,
+ or BadModes is NULL
+**/
+EFI_STATUS
+EFIAPI
+IdeInitDisqualifyMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *BadModes
+ );
+
+/**
+ This function is called by IdeBus driver to calculate the best operation mode
+ supported by specific IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in, out] SupportedModes Modes collection supported by IDE device
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Device parameter is out of range;
+ Or SupportedModes is NULL
+ @retval EFI_NOT_READY Identify data is not valid
+ @retval EFI_OUT_OF_RESOURCES SupportedModes is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitCalculateMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
+ );
+
+/**
+ This function is called by IdeBus driver to set appropriate timing on IDE
+ controller according supported operation mode
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] Modes Operation modes
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSetTiming (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *Modes
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.inf b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.inf
new file mode 100644
index 0000000..b80a195
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.inf
@@ -0,0 +1,94 @@
+## @file
+# Component description file for PCH SATA controller Driver module.
+#
+#@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
+#
+
+[defines]
+BASE_NAME = SataController
+FILE_GUID = BB65942B-521F-4ec3-BAF9-A92540CF60D2
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ SataController.h
+ SataController.c
+ SataControllerName.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.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
+#
+# 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]
+ EfiScriptLib
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiLib
+ EdkIIGlueUefiDriverModelLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ PchPlatformLib
+ EdkIIGlueBasePciLibPciExpress
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeSataControllerDriver \
+ -D __EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mSataControllerDriverBinding \
+ -D __EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mSataControllerName
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_LIB__ \
+ -D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__
diff --git a/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.mak b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.mak
new file mode 100644
index 0000000..915e815
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.mak
@@ -0,0 +1,116 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/SataController/SataController.mak 3 10/16/12 3:33a Scottyang $
+#
+# $Revision: 3 $
+#
+# $Date: 10/16/12 3:33a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SataController/SataController.mak $
+#
+# 3 10/16/12 3:33a Scottyang
+# [TAG] EIP103924
+#
+# [Category] Improvement
+#
+# [Description] Update RC 0.7.1
+#
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 2 2/24/12 2:20a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create SataController Driver
+#---------------------------------------------------------------------------
+EDK : SataController
+SataController : $(BUILD_DIR)\SataController.mak SataControllerBin
+
+
+$(BUILD_DIR)\SataController.mak : $(SataController_DIR)\$(@B).cif $(SataController_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SataController_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SataController_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+SataController_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializeSataControllerDriver"\
+ /D"__EDKII_GLUE_DRIVER_BINDING_PROTOCOL_INSTANCE__=mSataControllerDriverBinding"\
+ /D"__EDKII_GLUE_COMPONENT_NAME_PROTOCOL_INSTANCE__=mSataControllerName"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_LIB__ \
+ /D __EDKII_GLUE_UEFI_DRIVER_MODEL_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_CF8__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__
+
+SataController_LIB_LINKS =\
+ $(EFISCRIPTLIB) $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiLib_LIB)\
+ $(EdkIIGlueUefiDriverModelLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueBasePciLibCf8_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)
+
+SataControllerBin: $(SataController_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\SataController.mak all \
+ "MY_INCLUDES=$(SataController_INCLUDES)" \
+ "MY_DEFINES=$(SataController_DEFINES)" \
+ GUID=BB65942B-521F-4ec3-BAF9-A92540CF60D2\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER \
+ EDKIIModule=DXEDRIVER\
+ 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/SataController/Dxe/SataController.sdl b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.sdl
new file mode 100644
index 0000000..cecd287
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataController.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/SataController/SataController.sdl 1 2/08/12 9:15a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:15a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SataController/SataController.sdl $
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "SataController_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable SataController support in Project"
+End
+
+PATH
+ Name = "SataController_DIR"
+ Help = "SataController file source directory"
+End
+
+MODULE
+ File = "SataController.mak"
+ Help = "Includes SataController.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SataController.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/SataController/Dxe/SataControllerName.c b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataControllerName.c
new file mode 100644
index 0000000..5de33b3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SataController/Dxe/SataControllerName.c
@@ -0,0 +1,173 @@
+/** @file
+ This portion is to register the Sata Controller Driver name:
+ "SATA Controller Init 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 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 "SataController.h"
+
+///
+/// Forward reference declaration
+///
+EFI_STATUS
+EFIAPI
+SataControllerGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+SataControllerGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+///
+/// EFI Component Name Protocol
+/// This portion declares a gloabl variable of EFI_COMPONENT_NAME_PROTOCOL type.
+///
+EFI_COMPONENT_NAME_PROTOCOL mSataControllerName = {
+ SataControllerGetDriverName,
+ SataControllerGetControllerName,
+ "eng"
+};
+
+///
+/// Define the Driver's unicode name string
+///
+static EFI_UNICODE_STRING_TABLE mSataControllerDriverNameTable[] = {
+ {
+ "eng",
+ L"PCH Serial ATA Controller Initialization Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static EFI_UNICODE_STRING_TABLE mSataControllerControllerNameTable[] = {
+ {
+ "eng",
+ L"PCH Serial ATA Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param[in] Language A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param[out] DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @exception EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+
+ return LookupUnicodeString (
+ Language,
+ mSataControllerName.SupportedLanguages,
+ mSataControllerDriverNameTable,
+ DriverName
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param[in] ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param[in] Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param[out] ControllerName A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language
+ specified by Language from the point of view of the
+ driver specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+ ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ ControllerName is NULL.
+ @exception EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ The driver specified by This does not support the
+ language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return LookupUnicodeString (
+ Language,
+ mSataControllerName.SupportedLanguages,
+ mSataControllerControllerNameTable,
+ ControllerName
+ );
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c
new file mode 100644
index 0000000..53fc550
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.c
@@ -0,0 +1,516 @@
+/** @file
+ PCH SERIAL GPIO Driver implements the SERIAL GPIO Interface.
+ Usage model for this protocol is:
+ 1. locate this protocol by guid variable gEfiSerialGpioProtocolGuid
+ 2. Use SerialGpioRegister to register for one serial GPIO pin.
+ 3. Send data using SerialGpioSendData.
+ 4. If another GPIO need to send serial data,
+ the former one need to be unregistered using SerialGpioUnRegister since PCH have only one set of registers for serial GPIO data sending.
+ And register the new GPIO pin for Serial Gpio data sending.
+
+@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
+
+**/
+#include "PchSerialGpio.h"
+
+///
+/// Global variables
+///
+UINT32 mPchGpioBase;
+
+/**
+ Register for one GPIO Pin that will be used as serial GPIO.
+ For PCH only GPIO0~31 will have the capability to be used as serail GPIO.
+ The caller of this procedure need to be very clear of whPch GPIO should be used as serail GPIO,
+ it should not be input, native, conflict with other GPIO, or Index > 31 on the caller's platform.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER SerialGpioPinIndex is out of range
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ )
+{
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ PCH_SERIES PchSeries;
+
+ if (SerialGpioPinIndex >= SERIAL_GPIO_MAX_PIN_NUMBER) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance->CurrentActiveSerialGpio != SERIAL_GPIO_PIN_CLEARED) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "You have to unregister the former serial GPIO %d registered, then try to register this GPIO pin %d\n",
+ SerialGpioInstance->CurrentActiveSerialGpio,
+ SerialGpioPinIndex)
+ );
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// Read out values original in serial GPIO registers.
+ ///
+ if (PchSeries == PchH) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL));
+ GpioIoSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL));
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))));
+ }
+
+ GpioBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK));
+ GpioSerBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK));
+
+ SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue = GpioUseSelValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue = GpioBlinkValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue = GpioSerBlinkValue;
+ if (PchSeries == PchH) {
+ SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue = GpioIoSelValue;
+ }
+
+ ///
+ /// Modify settings in serial GPIO registers.
+ ///
+ ///
+ /// Serial GPIO will have to be selected as GPIO, not native
+ ///
+ if (PchSeries == PchH) {
+ GpioUseSelValue |= (1 << SerialGpioPinIndex);
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue |= B_PCH_GPIO_OWN0_GPIO_USE_SEL;
+ }
+
+ ///
+ /// Serial GPIO will have no Blink setting
+ ///
+ GpioBlinkValue &= (~(1 << SerialGpioPinIndex));
+
+ ///
+ /// Serial GPIO will have to enable serial Binlk setting
+ ///
+ GpioSerBlinkValue |= (1 << SerialGpioPinIndex);
+
+ ///
+ /// Serial GPIO will have to be output
+ ///
+ if (PchSeries == PchH) {
+ GpioIoSelValue &= (~(1 << SerialGpioPinIndex));
+ }
+
+ if (PchSeries == PchLp) {
+ GpioUseSelValue &= (~B_PCH_GPIO_OWN0_GPIO_IO_SEL);
+ }
+
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (PchSeries == PchH) {
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL), GpioUseSelValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL), GpioIoSelValue);
+ }
+
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))), GpioUseSelValue);
+ }
+
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK), GpioBlinkValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK), GpioSerBlinkValue);
+
+ ///
+ /// Record this GPIO index to private data structure
+ ///
+ SerialGpioInstance->CurrentActiveSerialGpio = SerialGpioPinIndex;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Unregister for one GPIO Pin that has been used as serial GPIO, and recover the registers before
+ registering.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER Invalid function parameters
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioUnRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ )
+{
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ PCH_SERIES PchSeries;
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((SerialGpioPinIndex != SerialGpioInstance->CurrentActiveSerialGpio) ||
+ (SerialGpioPinIndex >= SERIAL_GPIO_MAX_PIN_NUMBER)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ GpioUseSelValue = SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue;
+ GpioBlinkValue = SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue;
+ GpioSerBlinkValue = SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue;
+
+ if (PchSeries == PchH) {
+ GpioIoSelValue = SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue;
+ }
+
+ ///
+ /// At least to clear the serial Blink property
+ ///
+ GpioSerBlinkValue &= (~(1 << SerialGpioInstance->CurrentActiveSerialGpio));
+
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Write values with original values in serial GPIO registers.
+ ///
+
+ if (PchSeries == PchH) {
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL), GpioUseSelValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL), GpioIoSelValue);
+ }
+
+ if (PchSeries == PchLp) {
+ IoWrite32 ((UINTN) (mPchGpioBase + (R_PCH_GP_N_CONFIG0 + (SerialGpioPinIndex * 0x08))), GpioUseSelValue);
+ }
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK), GpioBlinkValue);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK), GpioSerBlinkValue);
+
+ ///
+ /// Clear the GPIO index in private data structure
+ ///
+ SerialGpioInstance->CurrentActiveSerialGpio = SERIAL_GPIO_PIN_CLEARED;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Execute SERIAL_GPIO commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] GpioPinIndex Index of the GPIO pin.
+ @param[in] DataRate The data rate for serail data transfering. 1 ~ SERIAL_GPIO_MAX_DATA_RATE; 1: 128ns intervals; ...; 8: 8*128 = 1024ns intervals, default value;...
+ @param[in] DataCountInByte Number of bytes of the data will be transmitted through the GPIO pin.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada sent through the GPIO pin.
+
+ @retval EFI_SUCCESS Execute succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, GPIO serial data sent failed.
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioSendData (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 GpioPinIndex,
+ IN UINT8 DataRate,
+ IN UINTN DataCountInByte,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataCountInDword;
+ UINTN DataCountLeftInByte;
+ UINTN Index;
+ UINT32 GpioSbCmdStsValue;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+
+ SerialGpioInstance = SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL (This);
+ if (SerialGpioInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Check if the parameters are valid.
+ ///
+ if ((Buffer == NULL) ||
+ (DataRate > SERIAL_GPIO_MAX_DATA_RATE) ||
+ (GpioPinIndex != SerialGpioInstance->CurrentActiveSerialGpio)
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Make sure it's safe to program the serial GPIO.
+ ///
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// set data rate
+ ///
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ GpioSbCmdStsValue &= (~B_PCH_GPIO_SB_CMDSTS_DRS_MASK);
+ GpioSbCmdStsValue |= (DataRate << 16);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ DataCountInDword = DataCountInByte / 4;
+ DataCountLeftInByte = DataCountInByte % 4;
+ for (Index = 0; Index < DataCountInDword; Index++) {
+ Status = SendSerialGpioSend (
+ This,
+ EnumSerialGpioDataDword,
+ (Buffer + Index * 4)
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ for (Index = 0; Index < DataCountLeftInByte; Index++) {
+ Status = SendSerialGpioSend (
+ This,
+ EnumSerialGpioDataByte,
+ (Buffer + DataCountInDword * 4 + Index)
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function sends the dword/word/byte through the serial GPIO pin.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] DataWidth The data width. 0: byte; 1: word; 2: reserved; 3: dword.
+ @param[in] Data Data buffer that contains the data (<= UINT32)
+
+ @retval EFI_SUCCESS SERIAL_GPIO command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+**/
+EFI_STATUS
+SendSerialGpioSend (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN SERIAL_GPIO_DATA_WIDTH DataWidth,
+ IN UINT8 *Data
+ )
+{
+ UINT32 DataInDword;
+ UINT32 GpioSbCmdStsValue;
+
+ ///
+ /// Wait the SERIAL GPIO BUSY to be cleared.
+ ///
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// set data length
+ ///
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ GpioSbCmdStsValue &= (~B_PCH_GPIO_SB_CMDSTS_DLS_MASK);
+ GpioSbCmdStsValue |= (DataWidth << 22);
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ ///
+ /// Set Data
+ ///
+ DataInDword = *(UINT32 *) Data;
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_DATA), DataInDword);
+ ///
+ /// Set GO to start transmit
+ ///
+ GpioSbCmdStsValue |= B_PCH_GPIO_SB_CMDSTS_GO;
+ IoWrite32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS), GpioSbCmdStsValue);
+ if (WaitForSerialGpioNotBusy () != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Wait PCH serial GPIO Busy bit being cleared by PCH chipset.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS SERIAL GPIO BUSY bit is cleared.
+ @retval EFI_DEVICE_ERROR Time out while waiting the SERIAL GPIO BUSY bit to be cleared.
+ It's not safe to send next data block on the SERIAL GPIO interface.
+**/
+EFI_STATUS
+WaitForSerialGpioNotBusy (
+ VOID
+ )
+{
+ UINTN WaitTicks;
+ UINTN WaitCount;
+ UINT32 GpioSbCmdStsValue;
+
+ ///
+ /// Convert the wait period allowed into to tick count
+ ///
+ WaitCount = WAIT_TIME / WAIT_PERIOD;
+ ///
+ /// Wait for the SERIAL_GPIO cycle to complete.
+ ///
+ for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+ GpioSbCmdStsValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SB_CMDSTS));
+ if ((GpioSbCmdStsValue & B_PCH_GPIO_SB_CMDSTS_BUSY) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ PchPmTimerStall (WAIT_PERIOD);
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+/**
+ Entry point for the SERIAL_GPIO host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_SUCCESS Initialization complete.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSerialGpio (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ SERIAL_GPIO_INSTANCE *SerialGpioInstance;
+ UINT32 GpioSerBlinkValue;
+ UINT32 GpioUseSelValue;
+ UINT32 GpioIoSelValue;
+ UINT32 GpioBlinkValue;
+ PCH_SERIES PchSeries;
+
+ DEBUG ((EFI_D_INFO, "InstallPchSerialGpio() Start\n"));
+
+ ///
+ /// Locate CPU IO protocol
+ ///
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "SERIAL GPIO Protocol not supported due to no proper PCH LPC found!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ GpioUseSelValue = 0;
+ GpioIoSelValue = 0;
+ PchSeries = GetPchSeries();
+
+ ///
+ /// PCH RCBA must be initialized prior to run this driver.
+ ///
+ mPchGpioBase = 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;
+ ASSERT (mPchGpioBase != 0);
+
+ ///
+ /// Allocate Runtime memory for the SERIAL_GPIO protocol instance.
+ ///
+ SerialGpioInstance = AllocateRuntimePool (sizeof (SERIAL_GPIO_INSTANCE));
+ if (SerialGpioInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (PchSeries == PchH) {
+ GpioUseSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_USE_SEL));
+ GpioIoSelValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_IO_SEL));
+ }
+ GpioBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_BLINK));
+ GpioSerBlinkValue = IoRead32 ((UINTN) (mPchGpioBase + R_PCH_GPIO_SER_BLINK));
+ SerialGpioInstance->Signature = PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE;
+ SerialGpioInstance->Handle = NULL;
+ SerialGpioInstance->CurrentActiveSerialGpio = SERIAL_GPIO_PIN_CLEARED;
+
+ if (PchSeries == PchH) {
+ SerialGpioInstance->RegistersToRecover.SavedGpioUseSelValue = GpioUseSelValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioIoSelValue = GpioIoSelValue;
+ }
+ SerialGpioInstance->RegistersToRecover.SavedGpioBlinkValue = GpioBlinkValue;
+ SerialGpioInstance->RegistersToRecover.SavedGpioSerBlinkValue = GpioSerBlinkValue;
+
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioRegister = PchSerialGpioRegister;
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioSendData = PchSerialGpioSendData;
+ SerialGpioInstance->SerialGpioProtocol.SerialGpioUnRegister = PchSerialGpioUnRegister;
+ ///
+ /// Install the EFI_SERIAL_GPIO_PROTOCOL interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(SerialGpioInstance->Handle),
+ &gEfiSerialGpioProtocolGuid,
+ &(SerialGpioInstance->SerialGpioProtocol),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (SerialGpioInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ DEBUG ((EFI_D_INFO, "InstallPchSerialGpio() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif
new file mode 100644
index 0000000..9df0226
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchSerialGpio"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SerialGpio\Dxe"
+ RefName = "PchSerialGpio"
+[files]
+"PchSerialGpio.sdl"
+"PchSerialGpio.mak"
+"PchSerialGpio.c"
+"PchSerialGpio.h"
+"PchSerialGpio.dxs"
+"PchSerialGpio.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.dxs
new file mode 100644
index 0000000..7a9a510
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.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 "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"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h
new file mode 100644
index 0000000..d882ada
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.h
@@ -0,0 +1,193 @@
+/** @file
+ Header file for the PCH SERIAL GPIO Driver.
+
+@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_SERIAL_GPIO_H_
+#define _PCH_SERIAL_GPIO_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"
+
+//
+// Driver Produced Protocols
+//
+#include EFI_PROTOCOL_PRODUCER (SerialGpio)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('S', 'G', 'P', 'O')
+
+#define SERIAL_GPIO_INSTANCE_FROM_SERIAL_GPIO_PROTOCOL(a) \
+ CR ( \
+ a, \
+ SERIAL_GPIO_INSTANCE, \
+ SerialGpioProtocol, \
+ PCH_SERIAL_GPIO_PRIVATE_DATA_SIGNATURE \
+ )
+
+///
+/// Only when CurrentActiveSerialGpio == SERIAL_GPIO_PIN_CLEARED,
+/// can the next GPIO be register as serail GPIO using SerialGpioProtocol
+///
+#define SERIAL_GPIO_PIN_CLEARED 0xFF
+///
+/// This is the old values in GPIO related registers for recovery when unregister this serial GPIO pin.
+///
+typedef struct {
+ UINT32 SavedGpioUseSelValue;
+ UINT32 SavedGpioBlinkValue;
+ UINT32 SavedGpioSerBlinkValue;
+ UINT32 SavedGpioIoSelValue;
+} SERIAL_GPIO_REGISTERS_TO_RECOVER;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ UINT8 CurrentActiveSerialGpio; ///< can only have one pin at one time
+ SERIAL_GPIO_REGISTERS_TO_RECOVER RegistersToRecover;
+ EFI_SERIAL_GPIO_PROTOCOL SerialGpioProtocol;
+} SERIAL_GPIO_INSTANCE;
+
+//
+// Function prototypes used by the SERIAL_GPIO protocol.
+//
+
+/**
+ Register for one GPIO Pin that will be used as serial GPIO.
+ For PCH only GPIO0~31 will have the capability to be used as serail GPIO.
+ The caller of this procedure need to be very clear of whPch GPIO should be used as serail GPIO,
+ it should not be input, native, conflict with other GPIO, or Index > 31 on the caller's platform.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER SerialGpioPinIndex is out of range
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Unregister for one GPIO Pin that has been used as serial GPIO, and recover the registers before
+ registering.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] SerialGpioPinIndex The GPIO pin Index that will be used as serial GPIO for data sending.
+
+ @retval EFI_SUCCESS Opcode initialization on the SERIAL_GPIO host controller completed.
+ @retval EFI_ACCESS_DENIED The SERIAL_GPIO configuration interface is locked.
+ @retval EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @retval EFI_INVALID_PARAMETER Invalid function parameters
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioUnRegister (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 SerialGpioPinIndex
+ );
+
+/**
+ Execute SERIAL_GPIO commands from the host controller.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] GpioPinIndex Index of the GPIO pin.
+ @param[in] DataRate The data rate for serail data transfering. 1 ~ SERIAL_GPIO_MAX_DATA_RATE; 1: 128ns intervals; ...; 8: 8*128 = 1024ns intervals, default value;...
+ @param[in] DataCountInByte Number of bytes of the data will be transmitted through the GPIO pin.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada sent through the GPIO pin.
+
+ @retval EFI_SUCCESS Execute succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @retval EFI_DEVICE_ERROR Device error, GPIO serial data sent failed.
+**/
+EFI_STATUS
+EFIAPI
+PchSerialGpioSendData (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN UINT8 GpioPinIndex,
+ IN UINT8 DataRate,
+ IN UINTN DataCountInByte,
+ IN OUT UINT8 *Buffer
+ );
+
+/**
+ This function sends the dword/word/byte through the serial GPIO pin.
+
+ @param[in] This Pointer to the EFI_SERIAL_GPIO_PROTOCOL instance.
+ @param[in] DataWidth The data width. 0: byte; 1: word; 2: reserved; 3: dword.
+ @param[in] Data Data buffer that contains the data (<= UINT32)
+
+ @retval EFI_SUCCESS SERIAL_GPIO command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+**/
+EFI_STATUS
+SendSerialGpioSend (
+ IN EFI_SERIAL_GPIO_PROTOCOL *This,
+ IN SERIAL_GPIO_DATA_WIDTH DataWidth,
+ IN UINT8 *Data
+ );
+
+/**
+ Wait PCH serial GPIO Busy bit being cleared by PCH chipset.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS SERIAL GPIO BUSY bit is cleared.
+ @retval EFI_DEVICE_ERROR Time out while waiting the SERIAL GPIO BUSY bit to be cleared.
+ It's not safe to send next data block on the SERIAL GPIO interface.
+**/
+EFI_STATUS
+WaitForSerialGpioNotBusy (
+ VOID
+ );
+
+/**
+ Entry point for the SERIAL_GPIO host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_SUCCESS Initialization complete.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSerialGpio (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf
new file mode 100644
index 0000000..508c09d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.inf
@@ -0,0 +1,79 @@
+## @file
+# Component description file for the PCH serial GPIO driver.
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchSerialGpio
+FILE_GUID = FC1B7640-3466-4c06-B1CC-1C935394B5C2
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSerialGpio.h
+ PchSerialGpio.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.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
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSerialGpio.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSerialGpio
+ 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_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak
new file mode 100644
index 0000000..21383c0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.mak
@@ -0,0 +1,96 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSerialGpio/PchSerialGpio.mak 2 2/24/12 2:20a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:20a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.mak $
+#
+# 2 2/24/12 2:20a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSerialGpio Driver
+#---------------------------------------------------------------------------
+EDK : PchSerialGpio
+PchSerialGpio : $(BUILD_DIR)\PchSerialGpio.mak PchSerialGpioBin
+
+$(BUILD_DIR)\PchSerialGpio.mak : $(PchSerialGpio_DIR)\$(@B).cif $(PchSerialGpio_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSerialGpio_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSerialGpio_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSerialGpio_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSerialGpio"\
+ /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_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSerialGpio_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)
+
+PchSerialGpioBin: $(PchSerialGpio_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSerialGpio.mak all \
+ "MY_INCLUDES=$(PchSerialGpio_INCLUDES)"\
+ "MY_DEFINES=$(PchSerialGpio_DEFINES)"\
+ GUID=FC1B7640-3466-4c06-B1CC-1C935394B5C2\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchSerialGpio_DIR)\PchSerialGpio.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/SerialGpio/Dxe/PchSerialGpio.sdl b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.sdl
new file mode 100644
index 0000000..d7095d3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SerialGpio/Dxe/PchSerialGpio.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/PchSerialGpio/PchSerialGpio.sdl 1 2/08/12 9:15a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:15a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSerialGpio/PchSerialGpio.sdl $
+#
+# 1 2/08/12 9:15a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSerialGpio_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSerialGpio support in Project"
+End
+
+PATH
+ Name = "PchSerialGpio_DIR"
+ Help = "PchSerialGpio file source directory"
+End
+
+MODULE
+ File = "PchSerialGpio.mak"
+ Help = "Includes PchSerialGpio.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSerialGpio.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/SmartTimer/Dxe/SmartTimer.c b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.c
new file mode 100644
index 0000000..2d97c7a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.c
@@ -0,0 +1,523 @@
+/** @file
+ Timer Architectural Protocol as defined in the DXE CIS
+
+@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 "SmartTimer.h"
+
+///
+/// The handle onto which the Timer Architectural Protocol will be installed
+///
+EFI_HANDLE mTimerHandle = NULL;
+
+///
+/// The Timer Architectural Protocol that this driver produces
+///
+EFI_TIMER_ARCH_PROTOCOL mTimer = {
+ TimerDriverRegisterHandler,
+ TimerDriverSetTimerPeriod,
+ TimerDriverGetTimerPeriod,
+ TimerDriverGenerateSoftInterrupt
+};
+
+///
+/// Pointer to the CPU Architectural Protocol instance
+///
+EFI_CPU_ARCH_PROTOCOL *mCpu;
+
+///
+/// Pointer to the Legacy 8259 Protocol instance
+///
+EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+
+///
+/// The notification function to call on every timer interrupt.
+/// A bug in the compiler prevents us from initializing this here.
+///
+volatile EFI_TIMER_NOTIFY mTimerNotifyFunction;
+
+///
+/// The current period of the timer interrupt
+///
+volatile UINT64 mTimerPeriod = 0;
+
+///
+/// The time of twice timer interrupt duration
+///
+volatile UINTN mPreAcpiTick = 0;
+
+///
+/// PMIO BAR Registers
+///
+UINT16 mPchPmioBase;
+
+//
+// Worker Functions
+//
+
+/**
+ Sets the counter value for Timer #0 in a legacy 8254 timer.
+
+ @param[in] Count The 16-bit counter value to program into Timer #0 of the legacy 8254 timer.
+
+ @retval None
+**/
+VOID
+SetPitCount (
+ IN UINT16 Count
+ )
+{
+ UINT8 Data;
+ ///
+ /// 0x36 = Read/Write counter LSB then MSB, Mode3 square wave output from this timer.
+ /// Check register Counter Access Ports Register(0x40/41/42 for counter0/1/2) in PCH B0D31F0
+ /// check Counter Operating Mode 0~5 at 8254 Timer function description in LPC in EDS.
+ ///
+ Data = 0x36;
+ IoWrite8 (TIMER_CONTROL_PORT, Data);
+ IoWrite8 (TIMER0_COUNT_PORT, (UINT8) Count);
+ IoWrite8 (TIMER0_COUNT_PORT, (UINT8) (Count >> 8));
+}
+
+/**
+ Get the current ACPI counter's value
+
+ @param[in] None
+
+ @retval UINT32 The value of the counter
+**/
+UINT32
+GetAcpiTick (
+ VOID
+ )
+{
+ UINT32 Tick;
+
+ Tick = IoRead32 ((UINTN) (mPchPmioBase + R_PCH_ACPI_PM1_TMR));
+ return Tick;
+
+}
+
+/**
+ Measure the 8254 timer interrupt use the ACPI time counter
+
+ @param[in] TimePeriod The current period of the timer interrupt
+
+ @retval UINT64 The real system time pass between the sequence 8254 timer
+ interrupt
+**/
+UINT64
+MeasureTimeLost (
+ IN UINT64 TimePeriod
+ )
+{
+ UINT32 CurrentTick;
+ UINT32 EndTick;
+ UINT64 LostTime;
+
+ CurrentTick = GetAcpiTick ();
+ EndTick = CurrentTick;
+
+ if (CurrentTick < mPreAcpiTick) {
+ EndTick = CurrentTick + 0x1000000;
+ }
+ ///
+ /// The calculation of the lost system time should be very accurate, we use
+ /// the shift calcu to make sure the value's accurate:
+ /// the origenal formula is:
+ /// (EndTick - mPreAcpiTick) * 10,000,000
+ /// LostTime = -----------------------------------------------
+ /// (3,579,545 Hz / 1,193,182 Hz) * 1,193,182 Hz
+ ///
+ /// Note: the 3,579,545 Hz is the ACPI timer's clock;
+ /// the 1,193,182 Hz is the 8254 timer's clock;
+ ///
+ LostTime = RShiftU64 (
+ MultU64x32 ((UINT64) (EndTick - mPreAcpiTick),
+ 46869689) + 0x00FFFFFF,
+ 24
+ );
+
+ if (LostTime != 0) {
+ mPreAcpiTick = CurrentTick;
+ }
+
+ return LostTime;
+}
+
+/**
+ 8254 Timer #0 Interrupt Handler
+
+ @param[in] InterruptType The type of interrupt that occured
+ @param[in] SystemContext A pointer to the system context when the interrupt occured
+
+ @retval None
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+ )
+{
+ EFI_TPL OriginalTPL;
+
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ mLegacy8259->EndOfInterrupt (mLegacy8259, Efi8259Irq0);
+
+ if (mTimerNotifyFunction) {
+ ///
+ /// If we have the timer interrupt miss, then we use
+ /// the platform ACPI time counter to retrieve the time lost
+ ///
+ mTimerNotifyFunction (MeasureTimeLost (mTimerPeriod));
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+ This function registers the handler NotifyFunction so it is called every time
+ the timer interrupt fires. It also passes the amount of time since the last
+ handler call to the NotifyFunction. If NotifyFunction is NULL, then the
+ handler is unregistered. If the handler is registered, then EFI_SUCCESS is
+ returned. If the CPU does not support registering a timer interrupt handler,
+ then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
+ when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+ If an attempt is made to unregister a handler when a handler is not registered,
+ then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
+ register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+ is returned.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[in] NotifyFunction The function to call when a timer interrupt fires. This
+ function executes at TPL_HIGH_LEVEL. The DXE Core will
+ register a handler for the timer interrupt, so it can know
+ how much time has passed. This information is used to
+ signal timer based events. NULL will unregister the handler.
+
+ @retval EFI_SUCCESS The timer handler was registered.
+ @exception EFI_UNSUPPORTED The CPU does not support registering a timer interrupt handler
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered.
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_TIMER_NOTIFY NotifyFunction
+ )
+{
+ ///
+ /// If an attempt is made to unregister a handler when a handler is not registered,
+ /// then EFI_INVALID_PARAMETER is returned.
+ ///
+ if (mTimerNotifyFunction == NULL && NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// If an attempt is made to register a handler
+ /// when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+ ///
+ if (mTimerNotifyFunction != NULL && NotifyFunction != NULL) {
+ return EFI_ALREADY_STARTED;
+ }
+ ///
+ /// If the CPU does not support registering a timer interrupt handler, then EFI_UNSUPPORTED is returned.
+ ///
+ if (mCpu == NULL || mLegacy8259 == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (NotifyFunction == NULL) {
+ ///
+ /// If NotifyFunction is NULL, then the handler is unregistered.
+ ///
+ mTimerNotifyFunction = NULL;
+ } else {
+ mTimerNotifyFunction = NotifyFunction;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[in] TimerPeriod The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+ @retval EFI_SUCCESS The timer period was changed.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod
+ )
+{
+ UINT64 TimerCount;
+
+ ///
+ /// The basic clock is 1.19318 MHz or 0.119318 ticks per 100 ns.
+ /// TimerPeriod * 0.119318 = 8254 timer divisor. Using integer arithmetic
+ /// TimerCount = (TimerPeriod * 119318)/1000000.
+ ///
+ /// Round up to next highest integer. This guarantees that the timer is
+ /// equal to or slightly longer than the requested time.
+ /// TimerCount = ((TimerPeriod * 119318) + 500000)/1000000
+ ///
+ /// Note that a TimerCount of 0 is equivalent to a count of 65,536
+ ///
+ /// Since TimerCount is limited to 16 bits for IA32, TimerPeriod is limited
+ /// to 20 bits.
+ ///
+ if (TimerPeriod == 0) {
+ ///
+ /// Disable timer interrupt for a TimerPeriod of 0
+ ///
+ mLegacy8259->DisableIrq (mLegacy8259, Efi8259Irq0);
+ } else {
+ ///
+ /// Convert TimerPeriod into 8254 counts
+ ///
+ TimerCount = DivU64x32Remainder (MultU64x32 (119318, (UINT32) TimerPeriod) + 500000, 1000000, 0);
+
+ ///
+ /// Check for overflow
+ ///
+ if (TimerCount >= 65536) {
+ TimerCount = 0;
+ if (TimerPeriod >= DEFAULT_TIMER_TICK_DURATION) {
+ TimerPeriod = DEFAULT_TIMER_TICK_DURATION;
+ }
+ }
+ ///
+ /// Program the 8254 timer with the new count value
+ ///
+ SetPitCount ((UINT16) TimerCount);
+
+ ///
+ /// Enable timer interrupt
+ ///
+ mLegacy8259->EnableIrq (mLegacy8259, Efi8259Irq0, FALSE);
+ }
+ ///
+ /// Save the new timer period
+ ///
+ mTimerPeriod = TimerPeriod;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[out] TimerPeriod A pointer to the timer period to retrieve in 100 ns units.
+ If 0 is returned, then the timer is currently disabled.
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ )
+{
+ if (TimerPeriod == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *TimerPeriod = mTimerPeriod;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function generates a soft timer interrupt. If the platform does not support soft
+ timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+ If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+ service, then a soft timer interrupt will be generated. If the timer interrupt is
+ enabled when this service is called, then the registered handler will be invoked. The
+ registered handler should not be able to distinguish a hardware-generated timer
+ interrupt from a software-generated timer interrupt.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The soft timer interrupt was generated.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+ IN EFI_TIMER_ARCH_PROTOCOL *This
+ )
+{
+ EFI_STATUS Status;
+ UINT16 IRQMask;
+ EFI_TPL OriginalTPL;
+
+ DEBUG ((EFI_D_INFO, "TimerDriverGenerateSoftInterrupt() Start\n"));
+
+ ///
+ /// If the timer interrupt is enabled, then the registered handler will be invoked.
+ ///
+ Status = mLegacy8259->GetMask (mLegacy8259, NULL, NULL, &IRQMask, NULL);
+ ASSERT_EFI_ERROR (Status);
+ if ((IRQMask & 0x1) == 0) {
+ ///
+ /// Invoke the registered handler
+ ///
+ OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+ if (mTimerNotifyFunction) {
+ ///
+ /// We use the platform ACPI time counter to determine
+ /// the amount of time that has passed
+ ///
+ mTimerNotifyFunction (MeasureTimeLost (mTimerPeriod));
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+ }
+
+ DEBUG ((EFI_D_INFO, "TimerDriverGenerateSoftInterrupt() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the Timer Architectural Protocol driver
+
+ @param[in] ImageHandle ImageHandle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Timer Architectural Protocol created
+ @retval Other Failed
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT32 TimerVector;
+
+ DEBUG ((EFI_D_INFO, "TimerDriverInitialize() Start\n"));
+
+ ///
+ /// Initialize the pointer to our notify function.
+ ///
+ mTimerNotifyFunction = NULL;
+ mCpu = NULL;
+ mLegacy8259 = NULL;
+
+ ///
+ /// Make sure the Timer Architectural Protocol is not already installed in the system
+ ///
+ ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid);
+
+ ///
+ /// Find the CPU architectural protocol. ASSERT if not found.
+ ///
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **) &mCpu);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Find the Legacy8259 protocol. ASSERT if not found.
+ ///
+ Status = gBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, (VOID **) &mLegacy8259);
+ ASSERT_EFI_ERROR (Status);
+
+ mPchPmioBase = MmioRead16 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+ ASSERT (mPchPmioBase != 0);
+ ///
+ /// Force the timer to be disabled
+ ///
+ Status = TimerDriverSetTimerPeriod (&mTimer, 0);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Get the interrupt vector number corresponding to IRQ0 from the 8259 driver
+ ///
+ TimerVector = 0;
+ Status = mLegacy8259->GetVector (mLegacy8259, Efi8259Irq0, (UINT8 *) &TimerVector);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install interrupt handler for 8254 Timer #0 (ISA IRQ0)
+ ///
+ Status = mCpu->RegisterInterruptHandler (mCpu, TimerVector, TimerInterruptHandler);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Force the timer to be enabled at its default period
+ ///
+ Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Begin the ACPI timer counter
+ ///
+ mPreAcpiTick = GetAcpiTick ();
+
+ ///
+ /// Install the Timer Architectural Protocol onto a new handle
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mTimerHandle,
+ &gEfiTimerArchProtocolGuid,
+ &mTimer,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "TimerDriverInitialize() End\n"));
+
+ return Status;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.cif b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.cif
new file mode 100644
index 0000000..dc6239c
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "SmartTimer"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SmartTimer\Dxe"
+ RefName = "SmartTimer"
+[files]
+"SmartTimer.sdl"
+"SmartTimer.mak"
+"SmartTimer.h"
+"SmartTimer.c"
+"SmartTimer.dxs"
+"SmartTimer.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.dxs b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.dxs
new file mode 100644
index 0000000..bca8dd7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.dxs
@@ -0,0 +1,42 @@
+/** @file
+ Dependency expression source file.
+
+@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_ARCH_PROTOCOL_DEFINITION (Cpu)
+#include EFI_PROTOCOL_DEFINITION (Legacy8259)
+#endif
+
+DEPENDENCY_START
+ EFI_CPU_ARCH_PROTOCOL_GUID AND EFI_LEGACY_8259_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h
new file mode 100644
index 0000000..d691a29
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.h
@@ -0,0 +1,178 @@
+/** @file
+ Private data structures
+
+@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
+**/
+#ifndef _SMARTTIMER_H_
+#define _SMARTTIMER_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"
+
+//
+// Consumed Protocols
+//
+#include EFI_ARCH_PROTOCOL_CONSUMER (Cpu)
+#include EFI_PROTOCOL_CONSUMER (Legacy8259)
+//
+// Produced Protocols
+//
+#include EFI_ARCH_PROTOCOL_PRODUCER (Timer)
+#endif
+///
+/// The PCAT 8253/8254 has an input clock at 1.193182 MHz and Timer 0 is
+/// initialized as a 16 bit free running counter that generates an interrupt(IRQ0)
+/// each time the counter rolls over.
+///
+/// 65536 counts
+/// ---------------- * 1,000,000 uS/S = 54925.4 uS = 549254 * 100 ns
+/// 1,193,182 Hz
+///
+#define DEFAULT_TIMER_TICK_DURATION 549254
+#define TIMER_CONTROL_PORT 0x43
+#define TIMER0_COUNT_PORT 0x40
+
+//
+// Function Prototypes
+//
+
+/**
+ Initialize the Timer Architectural Protocol driver
+
+ @param[in] ImageHandle ImageHandle of the loaded driver
+ @param[in] SystemTable Pointer to the System Table
+
+ @retval EFI_SUCCESS Timer Architectural Protocol created
+ @retval Other Failed
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+;
+
+/**
+ This function registers the handler NotifyFunction so it is called every time
+ the timer interrupt fires. It also passes the amount of time since the last
+ handler call to the NotifyFunction. If NotifyFunction is NULL, then the
+ handler is unregistered. If the handler is registered, then EFI_SUCCESS is
+ returned. If the CPU does not support registering a timer interrupt handler,
+ then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler
+ when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+ If an attempt is made to unregister a handler when a handler is not registered,
+ then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to
+ register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+ is returned.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[in] NotifyFunction The function to call when a timer interrupt fires. This
+ function executes at TPL_HIGH_LEVEL. The DXE Core will
+ register a handler for the timer interrupt, so it can know
+ how much time has passed. This information is used to
+ signal timer based events. NULL will unregister the handler.
+
+ @retval EFI_SUCCESS The timer handler was registered.
+ @exception EFI_UNSUPPORTED The CPU does not support registering a timer interrupt handler
+ @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already registered.
+ @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not previously registered.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN EFI_TIMER_NOTIFY NotifyFunction
+ );
+
+/**
+ This function adjusts the period of timer interrupts to the value specified
+ by TimerPeriod. If the timer period is updated, then the selected timer
+ period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+ If an error occurs while attempting to update the timer period, then the
+ timer hardware will be put back in its state prior to this call, and
+ EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt
+ is disabled. This is not the same as disabling the CPU's interrupts.
+ Instead, it must either turn off the timer hardware, or it must adjust the
+ interrupt controller so that a CPU interrupt is not generated when the timer
+ interrupt fires.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[in] TimerPeriod The rate to program the timer interrupt in 100 nS units. If
+ the timer hardware is not programmable, then EFI_UNSUPPORTED is
+ returned. If the timer is programmable, then the timer period
+ will be rounded up to the nearest timer period that is supported
+ by the timer hardware. If TimerPeriod is set to 0, then the
+ timer interrupts will be disabled.
+
+ @retval EFI_SUCCESS The timer period was changed.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ IN UINT64 TimerPeriod
+ );
+
+/**
+ This function retrieves the period of timer interrupts in 100 ns units,
+ returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod
+ is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is
+ returned, then the timer is currently disabled.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+ @param[out] TimerPeriod A pointer to the timer period to retrieve in 100 ns units.
+ If 0 is returned, then the timer is currently disabled.
+
+ @retval EFI_SUCCESS The timer period was returned in TimerPeriod.
+ @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+ IN EFI_TIMER_ARCH_PROTOCOL *This,
+ OUT UINT64 *TimerPeriod
+ );
+
+/**
+ This function generates a soft timer interrupt. If the platform does not support soft
+ timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+ If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+ service, then a soft timer interrupt will be generated. If the timer interrupt is
+ enabled when this service is called, then the registered handler will be invoked. The
+ registered handler should not be able to distinguish a hardware-generated timer
+ interrupt from a software-generated timer interrupt.
+
+ @param[in] This The EFI_TIMER_ARCH_PROTOCOL instance.
+
+ @retval EFI_SUCCESS The soft timer interrupt was generated.
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+ IN EFI_TIMER_ARCH_PROTOCOL *This
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.inf b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.inf
new file mode 100644
index 0000000..cd6c46b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.inf
@@ -0,0 +1,77 @@
+## @file
+# Component description file for 8254 Timer module cooperate
+# with ACPI time counter
+#
+#@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
+#
+
+[defines]
+BASE_NAME = SmartTimer
+FILE_GUID = 90CB75DB-71FC-489d-AACF-943477EC7212
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ SmartTimer.c
+ SmartTimer.h
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/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
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkFrameworkProtocolLib
+ ArchProtocolLib
+ EdkProtocolLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=SmartTimer.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=TimerDriverInitialize
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -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__
diff --git a/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.mak b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.mak
new file mode 100644
index 0000000..53ffa0d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.mak
@@ -0,0 +1,100 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/SmartTimer/SmartTimer.mak 3 9/26/12 3:17a Victortu $
+#
+# $Revision: 3 $
+#
+# $Date: 9/26/12 3:17a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SmartTimer/SmartTimer.mak $
+#
+# 3 9/26/12 3:17a Victortu
+# Lynx Point PCH Chipset Framework Reference Code Beta 0.7.0
+#
+# 2 2/24/12 2:21a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:17a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create SmartTimer Driver
+#---------------------------------------------------------------------------
+EDK : SmartTimer
+SmartTimer : $(BUILD_DIR)\SmartTimer.mak SmartTimerBin
+
+
+$(BUILD_DIR)\SmartTimer.mak : $(SmartTimer_DIR)\$(@B).cif $(SmartTimer_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SmartTimer_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SmartTimer_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+SmartTimer_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=TimerDriverInitialize"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /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__
+
+SmartTimer_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(ArchProtocolLib)\
+ $(EDKPROTOCOLLIB)
+
+
+SmartTimerBin: $(SmartTimer_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\SmartTimer.mak all \
+ "MY_INCLUDES=$(SmartTimer_INCLUDES)"\
+ "MY_DEFINES=$(SmartTimer_DEFINES)"\
+ GUID=90CB75DB-71FC-489d-AACF-943477EC7212\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(SmartTimer_DIR)\SmartTimer.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/SmartTimer/Dxe/SmartTimer.sdl b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.sdl
new file mode 100644
index 0000000..33c25e3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmartTimer/Dxe/SmartTimer.sdl
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/SmartTimer/SmartTimer.sdl 2 11/19/13 7:36a Barretlin $
+#
+# $Revision: 2 $
+#
+# $Date: 11/19/13 7:36a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SmartTimer/SmartTimer.sdl $
+#
+# 2 11/19/13 7:36a Barretlin
+# [TAG] EIP141917
+# [Category] New Feature
+# [Description] Support SetTimer() with HPET Timer on Lynx Point
+# [Files] SB.sdl SBGeneric.c SBDxe.c SbHpet.h sbProtocal.cif
+# SamrtTimer.sdl
+#
+# 1 2/08/12 9:17a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "SmartTimer_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmartTimer support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "HPET_PROTOCOL_SUPPORT" "=" "0"
+End
+
+PATH
+ Name = "SmartTimer_DIR"
+End
+
+MODULE
+ Help = "Includes SmartTimer to Project"
+ File = "SmartTimer.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmartTimer.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/Smbus/Common/PchSmbusCommon.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h
new file mode 100644
index 0000000..35cf2e5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommon.h
@@ -0,0 +1,190 @@
+/** @file
+ PCH Smbus Protocol
+
+@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_SMBUS_COMMON_H
+#define _PCH_SMBUS_COMMON_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 "EdkIIGlueBase.h"
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#include "EfiSmbus.h"
+
+#endif
+//
+// Definitions
+//
+#define STALL_PERIOD 10 * STALL_ONE_MICRO_SECOND ///< 10 microseconds
+#define STALL_TIME STALL_ONE_SECOND ///< 1 second
+#define BUS_TRIES 3 ///< How many times to retry on Bus Errors
+#define SMBUS_NUM_RESERVED 38 ///< Number of device addresses that are reserved by the SMBus spec.
+#define SMBUS_ADDRESS_ARP 0xC2 >> 1
+#define SMBUS_DATA_PREPARE_TO_ARP 0x01
+#define SMBUS_DATA_RESET_DEVICE 0x02
+#define SMBUS_DATA_GET_UDID_GENERAL 0x03
+#define SMBUS_DATA_ASSIGN_ADDRESS 0x04
+#define SMBUS_GET_UDID_LENGTH 17 ///< 16 byte UDID + 1 byte address
+//
+// Private data and functions
+//
+
+typedef
+UINT8
+(EFIAPI *SMBUS_IO_READ) (
+ IN UINT8 Offset
+ );
+
+typedef
+VOID
+(EFIAPI *SMBUS_IO_WRITE) (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ );
+
+typedef
+BOOLEAN
+(EFIAPI *SMBUS_IO_DONE) (
+ IN UINT8 *StsReg
+ );
+
+#define PCH_SMBUS_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('p', 's', 'm', 'b')
+
+/**
+ Get SMBUS IO Base address
+
+ @param[in] None
+
+ @retval UINT32 The SMBUS IO Base Address
+**/
+UINT32
+SmbusGetIoBase (
+ VOID
+ );
+
+/**
+ This function provides a standard way to read PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+
+ @retval UINT8 Returns data read from IO.
+**/
+UINT8
+EFIAPI
+SmbusIoRead (
+ IN UINT8 Offset
+ );
+
+/**
+ This function provides a standard way to write PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+ @param[in] Data Data to write to register.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+SmbusIoWrite (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ );
+
+/**
+ This function provides a standard way to check if an SMBus transaction has
+ completed.
+
+ @param[in] StsReg Not used for input. On return, contains the
+ value of the SMBus status register.
+
+ @retval TRUE Transaction is complete
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+IoDone (
+ IN UINT8 *StsReg
+ );
+
+/**
+ Check if it's ok to use the bus.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SmBus is acquired and it's safe to send commands.
+ @retval EFI_TIMEOUT SmBus is busy, it's not safe to send commands.
+**/
+EFI_STATUS
+AcquireBus (
+ VOID
+ );
+
+/**
+ This function provides a standard way to execute Smbus protocols
+ as defined in the SMBus Specification. The data can either be of
+ the Length byte, word, or a block of data. The resulting transaction will be
+ either the SMBus Slave Device accepts this transaction or this function
+ returns with an error
+
+ @param[in] SlaveAddress Smbus Slave device the command is directed at
+ @param[in] Command Slave Device dependent
+ @param[in] Operation Which SMBus protocol will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+ It will contain the actual number of bytes read/written.
+ @param[in, out] Buffer Contain the data read/written.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @exception EFI_UNSUPPORTED The operation is unsupported.
+
+ @retval EFI_INVALID_PARAMETER Length or Buffer is NULL for any operation besides
+ quick read or quick write.
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period, or the controller is not
+ available for use.
+ @retval EFI_DEVICE_ERROR There was an Smbus error (NACK) during the operation.
+ This could indicate the slave device is not present
+ or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ This function initializes the Smbus Registers.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+InitializeSmbusRegisters (
+ VOID
+ );
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif
new file mode 100644
index 0000000..e62b886
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PchSmbusCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Common"
+ RefName = "PchSmbusCommonLib"
+[files]
+"PchSmbusCommonLib.sdl"
+"PchSmbusCommonLib.mak"
+"PchSmbusExec.c"
+"PchSmbusCommon.h"
+<endComponent> \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak
new file mode 100644
index 0000000..2eb1277
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.mak
@@ -0,0 +1,124 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusCommonLib/PchSmbusCommonLib.mak 1 2/08/12 9:18a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:18a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusCommonLib/PchSmbusCommonLib.mak $
+#
+# 1 2/08/12 9:18a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchSmbusCommonLib
+
+PchSmbusCommonLib : PchSmbusCommonDxeLib PchSmbusCommonSmmLib PchSmbusCommonPeiLib
+
+$(PchSmbusCommonSmmLib_LIB) : PchSmbusCommonSmmLib
+$(PchSmbusCommonDxeLib_LIB) : PchSmbusCommonDxeLib
+$(PchSmbusCommonPeiLib_LIB) : PchSmbusCommonPeiLib
+
+PchSmbusCommonSmmLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibSmmBin
+
+PchSmbusCommonDxeLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibDxeBin
+
+PchSmbusCommonPeiLib : $(BUILD_DIR)\PchSmbusCommonLib.mak PchSmbusCommonLibPeiBin
+
+$(BUILD_DIR)\PchSmbusCommonLib.mak : $(PchSmbusCommonLib_DIR)\$(@B).cif $(PchSmbusCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusCommonLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchSmbusCommonLibSmm_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLibDxe_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLibPeim_INCLUDES=\
+ $(PchSmbusCommonLib_INCLUDES)
+
+PchSmbusCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+PchSmbusCommonLibPeim_DEFINES = \
+ $(PchSmbusCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+PchSmbusCommonLibDxe_DEFINES = \
+ $(PchSmbusCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+PchSmbusCommonLibSmm_DEFINES = \
+ $(PchSmbusCommonLibDxe_DEFINES)\
+
+PchSmbusCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibDxe_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(PchSmbusCommonDxeLib_LIB)
+
+PchSmbusCommonLibSmmBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibSmm_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibSmm_DEFINES)"\
+ TYPE=LIBRARY \
+ BUILD_DIR=$(BUILD_DIR)\Smm\
+ LIBRARY_NAME=$(PchSmbusCommonSmmLib_LIB)
+
+PchSmbusCommonLibPeiBin :
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\PchSmbusCommonLib.mak all\
+ "MY_INCLUDES=$(PchSmbusCommonLibPeim_INCLUDES)" \
+ "CFLAGS=$(PchSmbusCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(PchSmbusCommonPeiLib_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/Smbus/Common/PchSmbusCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl
new file mode 100644
index 0000000..7785408
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusCommonLib.sdl
@@ -0,0 +1,92 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusCommonLib/PchSmbusCommonLib.sdl 1 2/08/12 9:18a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:18a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusCommonLib/PchSmbusCommonLib.sdl $
+#
+# 1 2/08/12 9:18a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchSmbusCommonLib.mak to Project"
+ File = "PchSmbusCommonLib.mak"
+End
+
+ELINK
+ Name = "PchSmbusCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonDxeLib.lib"
+ Parent = "PchSmbusCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSmbusCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonPeiLib.lib"
+ Parent = "PchSmbusCommonPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSmbusCommonSmmLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusCommonSmmLib.lib"
+ Parent = "PchSmbusCommonSmmLib_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/Smbus/Common/PchSmbusExec.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c
new file mode 100644
index 0000000..4015dda
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Common/PchSmbusExec.c
@@ -0,0 +1,661 @@
+/** @file
+ PCH Smbus Executive Code (common PEI/DXE/SMM code)
+
+@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 "PchSmbusCommon.h"
+
+/**
+ Get SMBUS IO Base address
+
+ @param[in] None
+
+ @retval UINT32 The SMBUS IO Base Address
+**/
+UINT32
+SmbusGetIoBase (
+ VOID
+ )
+{
+ UINT32 SmbusIoBase;
+
+ SmbusIoBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ R_PCH_SMBUS_BASE)
+ ) & B_PCH_SMBUS_BASE_BAR;
+
+ ASSERT (SmbusIoBase != B_PCH_SMBUS_BASE_BAR && SmbusIoBase != 0);
+
+ return SmbusIoBase;
+}
+
+/**
+ This function provides a standard way to read PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+
+ @retval UINT8 Returns data read from IO.
+**/
+UINT8
+EFIAPI
+SmbusIoRead (
+ IN UINT8 Offset
+ )
+{
+ return IoRead8 (SmbusGetIoBase () + Offset);
+}
+
+/**
+ This function provides a standard way to write PCH Smbus IO registers.
+
+ @param[in] Offset Register offset from Smbus base IO address.
+ @param[in] Data Data to write to register.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+SmbusIoWrite (
+ IN UINT8 Offset,
+ IN UINT8 Data
+ )
+{
+ ///
+ /// Write New Value
+ ///
+ IoWrite8 (SmbusGetIoBase () + Offset, Data);
+ return;
+}
+
+/**
+ This function provides a standard way to check if an SMBus transaction has
+ completed.
+
+ @param[in] StsReg Not used for input. On return, contains the
+ value of the SMBus status register.
+
+ @retval TRUE Transaction is complete
+ @retval FALSE Otherwise.
+**/
+BOOLEAN
+EFIAPI
+IoDone (
+ IN UINT8 *StsReg
+ )
+{
+ ///
+ /// Wait for IO to complete
+ ///
+ UINTN StallIndex;
+ UINTN StallTries;
+
+ StallTries = STALL_TIME / STALL_PERIOD;
+
+ for (StallIndex = 0; StallIndex < StallTries; StallIndex++) {
+ *StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS);
+ if (*StsReg & (B_PCH_SMBUS_INTR | B_PCH_SMBUS_BYTE_DONE_STS | B_PCH_SMBUS_DERR | B_PCH_SMBUS_BERR)) {
+ return TRUE;
+ } else {
+ PchPmTimerStall (STALL_PERIOD);
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Check if it's ok to use the bus.
+
+ @param[in] None
+
+ @retval EFI_SUCCESS SmBus is acquired and it's safe to send commands.
+ @retval EFI_TIMEOUT SmBus is busy, it's not safe to send commands.
+**/
+EFI_STATUS
+AcquireBus (
+ VOID
+ )
+{
+ UINT8 StsReg;
+
+ StsReg = 0;
+ StsReg = SmbusIoRead (R_PCH_SMBUS_HSTS);
+ if (StsReg & B_PCH_SMBUS_IUS) {
+ return EFI_TIMEOUT;
+ } else if (StsReg & B_PCH_SMBUS_HBSY) {
+ ///
+ /// Clear Status Register and exit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ return EFI_TIMEOUT;
+ } else {
+ ///
+ /// Clear out any odd status information (Will Not Clear In Use)
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, StsReg);
+ return EFI_SUCCESS;
+ }
+}
+
+/**
+ This function provides a standard way to execute Smbus protocols
+ as defined in the SMBus Specification. The data can either be of
+ the Length byte, word, or a block of data. The resulting transaction will be
+ either the SMBus Slave Device accepts this transaction or this function
+ returns with an error
+
+ @param[in] SlaveAddress Smbus Slave device the command is directed at
+ @param[in] Command Slave Device dependent
+ @param[in] Operation Which SMBus protocol will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read. Must be 0 <= Length <= 32 depending on Operation
+ It will contain the actual number of bytes read/written.
+ @param[in, out] Buffer Contain the data read/written.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @exception EFI_UNSUPPORTED The operation is unsupported.
+
+ @retval EFI_INVALID_PARAMETER Length or Buffer is NULL for any operation besides
+ quick read or quick write.
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period, or the controller is not
+ available for use.
+ @retval EFI_DEVICE_ERROR There was an Smbus error (NACK) during the operation.
+ This could indicate the slave device is not present
+ or is in a hung condition.
+**/
+EFI_STATUS
+SmbusExec (
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 AuxcReg;
+ UINT8 AuxStsReg;
+ UINT8 SmbusOperation;
+ UINT8 StsReg;
+ UINT8 SlvAddrReg;
+ UINT8 HostCmdReg;
+ UINT8 BlockCount;
+ BOOLEAN BufferTooSmall;
+ UINTN Index;
+ UINTN BusIndex;
+ UINT8 *CallBuffer;
+ UINT8 SmbusHctl;
+ UINT32 Timeout;
+
+ CallBuffer = Buffer;
+ BlockCount = 0;
+
+ ///
+ /// For any operations besides quick read & write, the pointers to
+ /// Length and Buffer must not be NULL.
+ ///
+ if ((Operation != EfiSmbusQuickRead) && (Operation != EfiSmbusQuickWrite)) {
+ if ((Length == NULL) || (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ ///
+ /// See if its ok to use the bus based upon INUSE_STS bit.
+ ///
+ Status = AcquireBus ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// This is the main operation loop. If the operation results in a Smbus
+ /// collision with another master on the bus, it attempts the requested
+ /// transaction again at least BUS_TRIES attempts.
+ ///
+ for (BusIndex = 0; BusIndex < BUS_TRIES; BusIndex++) {
+ ///
+ /// Operation Specifics (pre-execution)
+ ///
+ Status = EFI_SUCCESS;
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_QUICK;
+ SlvAddrReg = (UINT8) ((SlaveAddress.SmbusDeviceAddress << 1) | 1);
+ HostCmdReg = (UINT8) Command;
+ AuxcReg = 0;
+
+ switch (Operation) {
+
+ case EfiSmbusQuickWrite:
+ SlvAddrReg--;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusQuickRead:
+ if (PecCheck == TRUE) {
+ Status = EFI_UNSUPPORTED;
+ }
+ break;
+
+ case EfiSmbusSendByte:
+ HostCmdReg = CallBuffer[0];
+ SlvAddrReg--;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReceiveByte:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE;
+ if (*Length < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 1;
+ break;
+
+ case EfiSmbusWriteByte:
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ SlvAddrReg--;
+ *Length = 1;
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReadByte:
+ if (*Length < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else if (*Length == 1) {
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BYTE_DATA;
+ } else if (*Length <= 256) {
+ if (PecCheck == TRUE) {
+ ///
+ /// The I2C Read command with either PEC_EN or AAC bit set
+ /// produces undefined results.
+ ///
+ Status = EFI_UNSUPPORTED;
+ }
+
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_IIC_READ;
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ break;
+
+ case EfiSmbusReadWord:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA;
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusWriteWord:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_WORD_DATA;
+ SlvAddrReg--;
+ SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]);
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusWriteBlock:
+ SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+ SlvAddrReg--;
+ BlockCount = (UINT8) (*Length);
+
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusReadBlock:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK;
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ case EfiSmbusProcessCall:
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_PROCESS_CALL;
+ SmbusIoWrite (R_PCH_SMBUS_HD1, CallBuffer[1]);
+ SmbusIoWrite (R_PCH_SMBUS_HD0, CallBuffer[0]);
+ if (*Length < 2) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Length = 2;
+ break;
+
+ case EfiSmbusBWBRProcessCall:
+ ///
+ /// The write byte count cannot be zero or more than
+ /// 32 bytes.
+ ///
+ if ((*Length < 1) || (*Length > 32)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ SmbusIoWrite (R_PCH_SMBUS_HD0, *(UINT8 *) Length);
+ BlockCount = (UINT8) (*Length);
+ SmbusOperation = V_PCH_SMBUS_SMB_CMD_BLOCK_PROCESS;
+
+ AuxcReg |= B_PCH_SMBUS_E32B;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (PecCheck == TRUE) {
+ AuxcReg |= B_PCH_SMBUS_AAC;
+ }
+ ///
+ /// Set Auxiliary Control register
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_AUXC, AuxcReg);
+
+ ///
+ /// Reset the pointer of the internal buffer
+ ///
+ SmbusIoRead (R_PCH_SMBUS_HCTL);
+
+ ///
+ /// Now that the 32 byte buffer is turned on, we can write th block data
+ /// into it
+ ///
+ if ((Operation == EfiSmbusWriteBlock) || (Operation == EfiSmbusBWBRProcessCall)) {
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Write next byte
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HBD, CallBuffer[Index]);
+ }
+ }
+ ///
+ /// Set SMBus slave address for the device to send/receive from
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_TSA, SlvAddrReg);
+
+ ///
+ /// For I2C read, send DATA1 register for the offset (address)
+ /// within the serial memory chips
+ ///
+ if ((Operation == EfiSmbusReadByte) && (*Length > 1)) {
+ SmbusIoWrite (R_PCH_SMBUS_HD1, HostCmdReg);
+ } else {
+ ///
+ /// Set Command register
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HCMD, HostCmdReg);
+ }
+ ///
+ /// Set Control Register (Initiate Operation, Interrupt disabled)
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, (UINT8) (SmbusOperation + B_PCH_SMBUS_START));
+
+ ///
+ /// Wait for IO to complete
+ ///
+ if (!IoDone (&StsReg)) {
+ Status = EFI_TIMEOUT;
+ break;
+ } else if (StsReg & B_PCH_SMBUS_DERR) {
+ AuxStsReg = SmbusIoRead (R_PCH_SMBUS_AUXS);
+ if (AuxStsReg & B_PCH_SMBUS_CRCE) {
+ Status = EFI_CRC_ERROR;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ break;
+ } else if (StsReg & B_PCH_SMBUS_BERR) {
+ ///
+ /// Clear the Bus Error for another try
+ ///
+ Status = EFI_DEVICE_ERROR;
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+ ///
+ /// Clear Status Registers
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+ ///
+ /// If bus collision happens, stall some time, then try again
+ /// Here we choose 10 milliseconds to avoid MTCP transfer.
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ continue;
+ }
+ ///
+ /// successfull completion
+ /// Operation Specifics (post-execution)
+ ///
+ switch (Operation) {
+
+ case EfiSmbusReadWord:
+ ///
+ /// The "break;" command is not present here to allow code execution
+ /// do drop into the next case, which contains common code to this case.
+ ///
+ case EfiSmbusProcessCall:
+ CallBuffer[1] = SmbusIoRead (R_PCH_SMBUS_HD1);
+ CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0);
+ break;
+
+ case EfiSmbusReadByte:
+ if (*Length > 1) {
+ for (Index = 0; Index < *Length; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ ///
+ /// After receiving byte n-1 (1-base) of the message, the
+ /// software will then set the LAST BYTE bit. The software
+ /// will then clear the BYTE_DONE_STS bit.
+ ///
+ if (Index == ((*Length - 1) - 1)) {
+ SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) | (UINT8) B_PCH_SMBUS_LAST_BYTE;
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl);
+ } else if (Index == (*Length - 1)) {
+ ///
+ /// Clear the LAST BYTE bit after receiving byte n (1-base) of the message
+ ///
+ SmbusHctl = SmbusIoRead (R_PCH_SMBUS_HCTL) & (UINT8) ~B_PCH_SMBUS_LAST_BYTE;
+ SmbusIoWrite (R_PCH_SMBUS_HCTL, SmbusHctl);
+ }
+ ///
+ /// Clear the BYTE_DONE_STS bit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+ ///
+ /// Check BYTE_DONE_STS bit to know if it has completed transmission
+ /// of a byte. No need to check it for the last byte.
+ ///
+ if (Index < (*Length - 1)) {
+ ///
+ /// If somehow board operates at 10Khz, it will take 0.9 ms (9/10Khz) for another byte.
+ /// Add 10 us delay for a loop of 100 that the total timeout is 1 ms to take care of
+ /// the slowest case.
+ ///
+ for (Timeout = 0; Timeout < 100; Timeout++) {
+ if ((SmbusIoRead (R_PCH_SMBUS_HSTS) & (UINT8) B_PCH_SMBUS_BYTE_DONE_STS) != 0) {
+ break;
+ }
+ ///
+ /// Delay 10 us
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ }
+
+ if (Timeout >= 100) {
+ Status = EFI_TIMEOUT;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case EfiSmbusReceiveByte:
+ CallBuffer[0] = SmbusIoRead (R_PCH_SMBUS_HD0);
+ break;
+
+ case EfiSmbusWriteBlock:
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BYTE_DONE_STS);
+ break;
+
+ case EfiSmbusReadBlock:
+ BufferTooSmall = FALSE;
+ ///
+ /// Find out how many bytes will be in the block
+ ///
+ BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0);
+ if (*Length < BlockCount) {
+ BufferTooSmall = TRUE;
+ } else {
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ }
+ }
+
+ *Length = BlockCount;
+ if (BufferTooSmall) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ break;
+
+ case EfiSmbusBWBRProcessCall:
+ ///
+ /// Find out how many bytes will be in the block
+ ///
+ BlockCount = SmbusIoRead (R_PCH_SMBUS_HD0);
+ ///
+ /// The read byte count cannot be zero.
+ ///
+ if (BlockCount < 1) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ break;
+ }
+ ///
+ /// The combined data payload (the write byte count + the read byte count)
+ /// must not exceed 32 bytes
+ ///
+ if (((UINT8) (*Length) + BlockCount) > 32) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+
+ for (Index = 0; Index < BlockCount; Index++) {
+ ///
+ /// Read the byte
+ ///
+ CallBuffer[Index] = SmbusIoRead (R_PCH_SMBUS_HBD);
+ }
+
+ *Length = BlockCount;
+ break;
+
+ default:
+ break;
+ };
+
+ if ((StsReg & B_PCH_SMBUS_BERR) && (Status != EFI_BUFFER_TOO_SMALL)) {
+ ///
+ /// Clear the Bus Error for another try
+ ///
+ Status = EFI_DEVICE_ERROR;
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_BERR);
+ ///
+ /// If bus collision happens, stall some time, then try again
+ /// Here we choose 10 milliseconds to avoid MTCP transfer.
+ ///
+ PchPmTimerStall (STALL_PERIOD);
+ continue;
+ } else {
+ break;
+ }
+ }
+ ///
+ /// Clear Status Registers and exit
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+ SmbusIoWrite (R_PCH_SMBUS_AUXS, B_PCH_SMBUS_CRCE);
+ SmbusIoWrite (R_PCH_SMBUS_AUXC, 0);
+ return Status;
+}
+
+/**
+ This function initializes the Smbus Registers.
+
+ @param[in] None.
+
+ @retval None.
+**/
+VOID
+InitializeSmbusRegisters (
+ VOID
+ )
+{
+ UINTN SmbusRegBase;
+
+ SmbusRegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ 0
+ );
+ ///
+ /// Enable the Smbus I/O Enable
+ ///
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+ ///
+ /// Enable the Smbus host controller
+ ///
+ MmioAndThenOr8 (
+ SmbusRegBase + R_PCH_SMBUS_HOSTC,
+ (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)),
+ B_PCH_SMBUS_HOSTC_HST_EN
+ );
+
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs
new file mode 100644
index 0000000..a64aee1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.dxs
@@ -0,0 +1,40 @@
+/** @file
+ Dispatch dependency expression file for the DXE PchSmbus driver.
+
+@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 "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 (PchPlatformPolicy)
+#endif
+
+DEPENDENCY_START
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h
new file mode 100644
index 0000000..6c6b93b
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbus.h
@@ -0,0 +1,360 @@
+/** @file
+ PCH Smbus Protocol
+
+@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 _DXE_PCH_SMBUS_H
+#define _DXE_PCH_SMBUS_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"
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_PRODUCER (Smbus)
+#include EFI_GUID_DEFINITION (SmbusArpMap)
+//
+// Driver Consumed Protcol Prototypes
+//
+#include EFI_PROTOCOL_CONSUMER (PchPlatformPolicy)
+#include "PchSmbusCommon.h"
+#endif
+//
+// Definitions
+//
+///
+/// Max number of SMBus devices (7 bit address yields 128 combinations but 21 of those are reserved)
+///
+#define MAX_SMBUS_DEVICES 107
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+///
+/// Private Data Structures
+///
+typedef struct _SMBUS_NOTIFY_FUNCTION_LIST_NODE {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINTN Data;
+ EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction;
+} SMBUS_NOTIFY_FUNCTION_LIST_NODE;
+
+#define SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK(_node) \
+ CR ( \
+ _node, \
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE, \
+ Link, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+///
+/// Declare a local instance structure for this driver
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ UINT32 SmbusIoBase;
+ SMBUS_IO_READ SmbusIoRead;
+ SMBUS_IO_WRITE SmbusIoWrite;
+ SMBUS_IO_DONE IoDone;
+
+ ///
+ /// Published interface
+ ///
+ EFI_SMBUS_HC_PROTOCOL SmbusController;
+
+ UINT8 DeviceMapEntries;
+ EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES];
+
+ UINT8 PlatformNumRsvd;
+ UINT8 *PlatformRsvdAddr;
+
+ LIST_ENTRY NotifyFunctionList;
+ EFI_EVENT NotificationEvent;
+
+} SMBUS_INSTANCE;
+
+//
+// Driver global data
+//
+SMBUS_INSTANCE *mSmbusContext;
+
+//
+// Prototypes
+//
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[out] Length Length of data
+ @param[out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @@param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @retval EFI_INVALID_PARAMETER ArpAll == FALSE but SmbusUdid or SlaveAddress are NULL.
+ Return value from SmbusFullArp() or SmbusDirectedArp().
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @retval EFI_SUCCESS Function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED Unable to create the event needed for notifications.
+ @retval EFI_INVALID_PARAMETER NotifyFunction was NULL.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the notification.
+ @retval EFI_SUCCESS Function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+/**
+ Set up a periodic event so that we can check if any Slave Device has sent a
+ Notify ARP Master command.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS Periodic event successfully set up.
+ @retval Other Errors Failed to set up Periodic event.
+ Error value from CreateEvent().
+ Error value from SetTimer().
+**/
+EFI_STATUS
+InitializePeriodicEvent (
+ VOID
+ );
+
+/**
+ Function to be called every time periodic event happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Event The periodic event that occured and got us into this callback.
+ @param[in] Context Event context. Will be NULL in this case, since we already have our
+ private data in a module global variable.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PollSmbusNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices
+ Or there is no available address to assign
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c
new file mode 100644
index 0000000..88124d4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusArp.c
@@ -0,0 +1,681 @@
+/** @file
+ PCH Smbus Driver, ARP functions common to PEI and DXE
+
+@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
+
+**/
+#include "PchSmbus.h"
+
+///
+/// These addresses are reserved by the SMBus 2.0 specification
+///
+static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = {
+ 0x00,
+ 0x02,
+ 0x04,
+ 0x06,
+ 0x08,
+ 0x0A,
+ 0x0C,
+ 0x0E,
+ 0x10,
+ 0x18,
+ 0x50,
+ 0x6E,
+ 0xC2,
+ 0xF0,
+ 0xF2,
+ 0xF4,
+ 0xF6,
+ 0xF8,
+ 0xFA,
+ 0xFC,
+ 0xFE,
+ 0x12,
+ 0x14,
+ 0x16,
+ 0x58,
+ 0x5A,
+ 0x80,
+ 0x82,
+ 0x84,
+ 0x86,
+ 0x88,
+ 0x90,
+ 0x92,
+ 0x94,
+ 0x96,
+ 0x1A,
+ 0x1C,
+ 0x1E
+};
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @@param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @retval EFI_INVALID_PARAMETER ArpAll == FALSE but SmbusUdid or SlaveAddress are NULL.
+ Return value from SmbusFullArp() or SmbusDirectedArp().
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ DEBUG ((EFI_D_INFO, "SmbusArpDevice() Start\n"));
+
+ InitializeSmbusRegisters ();
+
+ DEBUG ((EFI_D_INFO, "SmbusArpDevice() End\n"));
+
+ if (ArpAll) {
+ return SmbusFullArp (mSmbusContext);
+ } else {
+ if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmbusDirectedArp (mSmbusContext, SmbusUdid, SlaveAddress);
+ }
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @retval EFI_SUCCESS Function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ *Length = mSmbusContext->DeviceMapEntries * sizeof (EFI_SMBUS_DEVICE_MAP);
+ *SmbusDeviceMap = mSmbusContext->DeviceMap;
+ return EFI_SUCCESS;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED Unable to create the event needed for notifications.
+ @retval EFI_INVALID_PARAMETER NotifyFunction was NULL.
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate space to register the notification.
+ @retval EFI_SUCCESS Function completed successfully
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE *NewNode;
+
+ DEBUG ((EFI_D_INFO, "SmbusNotify() Start\n"));
+
+ if (NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NewNode = (SMBUS_NOTIFY_FUNCTION_LIST_NODE *) AllocatePool (sizeof (SMBUS_NOTIFY_FUNCTION_LIST_NODE));
+ if (NewNode == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for NewNode! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ///
+ /// If this is the first notification request, start an event to periodically
+ /// check for a Notify master command.
+ ///
+ if (!mSmbusContext->NotificationEvent) {
+ Status = InitializePeriodicEvent ();
+ if (EFI_ERROR (Status)) {
+ FreePool (NewNode);
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ NewNode->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ NewNode->SlaveAddress.SmbusDeviceAddress = SlaveAddress.SmbusDeviceAddress;
+ NewNode->Data = Data;
+ NewNode->NotifyFunction = NotifyFunction;
+
+ InsertTailList (&mSmbusContext->NotifyFunctionList, &NewNode->Link);
+
+ DEBUG ((EFI_D_INFO, "SmbusNotify() End\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Set up a periodic event so that we can check if any Slave Device has sent a
+ Notify ARP Master command.
+
+ @param[in] None.
+
+ @retval EFI_SUCCESS Periodic event successfully set up.
+ @retval Other Errors Failed to set up Periodic event.
+ Error value from CreateEvent().
+**/
+EFI_STATUS
+InitializePeriodicEvent (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->CreateEvent (
+ (EVENT_TIMER | EVENT_NOTIFY_SIGNAL),
+ TPL_CALLBACK,
+ PollSmbusNotify,
+ NULL,
+ &mSmbusContext->NotificationEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->SetTimer (
+ mSmbusContext->NotificationEvent,
+ TimerPeriodic,
+ 1000 * MILLISECOND
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to be called every time periodic event happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Event The periodic event that occured and got us into this callback.
+ @param[in] Context Event context. Will be NULL in this case, since we already have our
+ private data in a module global variable.
+
+ @retval None
+**/
+VOID
+EFIAPI
+PollSmbusNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ LIST_ENTRY *Link;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ SMBUS_NOTIFY_FUNCTION_LIST_NODE *Node;
+ UINT8 SstsReg;
+ UINTN Data;
+
+ DEBUG ((EFI_D_INFO, "PollSmbusNotify() Start\n"));
+
+ InitializeSmbusRegisters ();
+
+ SstsReg = SmbusIoRead (R_PCH_SMBUS_SSTS);
+ if (!(SstsReg & B_PCH_SMBUS_HOST_NOTIFY_STS)) {
+ ///
+ /// Host Notify has not been received
+ ///
+ return;
+ }
+ ///
+ /// There was a Host Notify, see if any one wants to know about it
+ ///
+ SlaveAddress.SmbusDeviceAddress = (SmbusIoRead (R_PCH_SMBUS_NDA)) >> 1;
+
+ Link = GetFirstNode (&mSmbusContext->NotifyFunctionList);
+
+ while (!IsNull (&mSmbusContext->NotifyFunctionList, Link)) {
+ Node = SMBUS_NOTIFY_FUNCTION_LIST_NODE_FROM_LINK (Link);
+
+ if (Node->SlaveAddress.SmbusDeviceAddress == SlaveAddress.SmbusDeviceAddress) {
+ Data = (SmbusIoRead (R_PCH_SMBUS_NDHB) << 8) + (SmbusIoRead (R_PCH_SMBUS_NDLB));
+ if ((UINT16) Node->Data == (UINT16) Data) {
+ ///
+ /// We have a match, notify the requested function
+ ///
+ Node->NotifyFunction (SlaveAddress, Data);
+ }
+ }
+
+ Link = GetNextNode (&mSmbusContext->NotifyFunctionList, &Node->Link);
+ }
+ ///
+ /// Clear the Notify Status bit and exit.
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_SSTS, B_PCH_SMBUS_HOST_NOTIFY_STS);
+
+ DEBUG ((EFI_D_INFO, "PollSmbusNotify() End\n"));
+
+ return;
+}
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer;
+
+ DEBUG ((EFI_D_INFO, "SmbusPrepareToArp() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = 1;
+ Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ 0,
+ EfiSmbusSendByte,
+ TRUE,
+ &Length,
+ &Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "SmbusPrepareToArp() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "SmbusGetUdidGeneral() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_GET_UDID_GENERAL,
+ EfiSmbusReadBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if (Length == SMBUS_GET_UDID_LENGTH) {
+ DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+ DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+ DeviceMap->SmbusDeviceUdid.VendorId = (UINT16) ((Buffer[2] << 8) + Buffer[3]);
+ DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16) ((Buffer[4] << 8) + Buffer[5]);
+ DeviceMap->SmbusDeviceUdid.Interface = (UINT16) ((Buffer[6] << 8) + Buffer[7]);
+ DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16) ((Buffer[8] << 8) + Buffer[9]);
+ DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16) ((Buffer[10] << 8) + Buffer[11]);
+ DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32) ((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+ DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8) (Buffer[16] >> 1);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "SmbusGetUdidGeneral() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "SmbusAssignAddress() Start\n"));
+
+ Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+ Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+ Buffer[2] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+ Buffer[3] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId);
+ Buffer[4] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+ Buffer[5] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId);
+ Buffer[6] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8);
+ Buffer[7] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface);
+ Buffer[8] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+ Buffer[9] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+ Buffer[10] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+ Buffer[11] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+ Buffer[12] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+ Buffer[13] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+ Buffer[14] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+ Buffer[15] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+ Buffer[16] = (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_ASSIGN_ADDRESS,
+ EfiSmbusWriteBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "SmbusAssignAddress() End\n"));
+
+ return Status;
+}
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "SmbusFullArp() Start\n"));
+
+ Status = SmbusPrepareToArp (Private);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ ///
+ /// ARP is complete
+ ///
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+ }
+ ///
+ /// Main loop to ARP all ARP-capable devices
+ ///
+ do {
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+ Status = SmbusGetUdidGeneral (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+ ///
+ /// If address is unassigned, assign it
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+ ///
+ /// if address is not fixed, check if the current address is available
+ ///
+ if (!IsAddressAvailable (
+ Private,
+ CurrentDeviceMap->SmbusDeviceAddress
+ )) {
+ ///
+ /// if currently assigned address is already used, get a new one
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// If there was a device error, just continue on and try again.
+ /// Other errors should be reported.
+ ///
+ if (Status != EFI_DEVICE_ERROR) {
+ return Status;
+ }
+ } else {
+ ///
+ /// If there was no error, the address was assigned and we must update our
+ /// records.
+ ///
+ Private->DeviceMapEntries++;
+ }
+
+ } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES);
+
+ DEBUG ((EFI_D_INFO, "SmbusFullArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices
+ Or there is no available address to assign
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "SmbusDirectedArp() Start\n"));
+
+ if (Private->DeviceMapEntries >= MAX_SMBUS_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+
+ ///
+ /// Find an available address to assign
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities;
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId;
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->DeviceMapEntries++;
+ SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+ DEBUG ((EFI_D_INFO, "SmbusDirectedArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ for (SlaveAddress->SmbusDeviceAddress = 0x03;
+ SlaveAddress->SmbusDeviceAddress < 0x7F;
+ SlaveAddress->SmbusDeviceAddress++
+ ) {
+ if (IsAddressAvailable (Private, *SlaveAddress)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ )
+{
+ UINT8 Index;
+
+ ///
+ /// See if we have already assigned this address to a device
+ ///
+ for (Index = 0; Index < Private->DeviceMapEntries; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress == Private->DeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this address is claimed by a platform non-ARP-capable device
+ ///
+ for (Index = 0; Index < Private->PlatformNumRsvd; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == Private->PlatformRsvdAddr[Index]) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this is a reserved address
+ ///
+ for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == (UINTN) mReservedAddress[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif
new file mode 100644
index 0000000..5a97eaa
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Dxe"
+ RefName = "PchSmbusDxe"
+[files]
+"PchSmbusDxe.sdl"
+"PchSmbusDxe.mak"
+"PchSmbus.h"
+"PchSmbusArp.c"
+"PchSmbusEntry.c"
+"PchSmbus.dxs"
+"PchSmbusDxe.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf
new file mode 100644
index 0000000..ae41336
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.inf
@@ -0,0 +1,93 @@
+## @file
+# Component description file for PchSmbus driver
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchSmbusDxe
+FILE_GUID = E052D8A6-224A-4c32-8D37-2E0AE162364D
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSmbusEntry.c
+ PchSmbus.h
+ PchSmbusArp.c
+ ../Common/PchSmbusExec.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.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
+#
+# 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]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseLib
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeHobLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbus
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_LIB__ \
+ -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_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_HOB_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak
new file mode 100644
index 0000000..3e74002
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.mak
@@ -0,0 +1,103 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusDxe/PchSmbusDxe.mak 2 2/24/12 2:22a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:22a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusDxe/PchSmbusDxe.mak $
+#
+# 2 2/24/12 2:22a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:19a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusDxe Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusDxe
+PchSmbusDxe : $(BUILD_DIR)\PchSmbusDxe.mak PchSmbusDxeBin
+
+
+$(BUILD_DIR)\PchSmbusDxe.mak : $(PchSmbusDxe_DIR)\$(@B).cif $(PchSmbusDxe_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusDxe_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusDxe_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbus"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /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_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusDxe_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(PchSmbusCommonDxeLib_LIB)
+
+PchSmbusDxeBin: $(PchSmbusDxe_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusDxe.mak all \
+ "MY_INCLUDES=$(PchSmbusDxe_INCLUDES)"\
+ "MY_DEFINES=$(PchSmbusDxe_DEFINES)"\
+ GUID=E052D8A6-224A-4c32-8D37-2E0AE162364D\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(PchSmbusDxe_DIR)\PchSmbus.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/Smbus/Dxe/PchSmbusDxe.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.sdl
new file mode 100644
index 0000000..8d5afd7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusDxe.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/PchSmbusDxe/PchSmbusDxe.sdl 1 2/08/12 9:19a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:19a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusDxe/PchSmbusDxe.sdl $
+#
+# 1 2/08/12 9:19a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusDxe_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSmbusDxe support in Project"
+End
+
+PATH
+ Name = "PchSmbusDxe_DIR"
+ Help = "PchSmbusDxe file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusDxe.mak to Project"
+ File = "PchSmbusDxe.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusDxe.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/Smbus/Dxe/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c
new file mode 100644
index 0000000..35cab3f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Dxe/PchSmbusEntry.c
@@ -0,0 +1,149 @@
+/** @file
+ PCH Smbus Driver
+
+@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
+**/
+#include "PchSmbus.h"
+
+EFI_GUID mEfiSmbusArpMapGuid = EFI_SMBUS_ARP_MAP_GUID;
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ DEBUG ((EFI_D_INFO, "SmbusExecute() Start, SmbusDeviceAddress=%x, Command=%x, Operation=%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Command, Operation));
+ InitializeSmbusRegisters ();
+
+ return SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+}
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbus (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ DXE_PCH_PLATFORM_POLICY_PROTOCOL *PchPlatformPolicy;
+ EFI_STATUS Status;
+ UINTN DataSize;
+ VOID *Data;
+ EFI_PEI_HOB_POINTERS HobList;
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbus() Start\n"));
+
+ Status = gBS->LocateProtocol (
+ &gDxePchPlatformPolicyProtocolGuid,
+ NULL,
+ (VOID **) &PchPlatformPolicy
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ mSmbusContext = AllocateZeroPool (sizeof (SMBUS_INSTANCE));
+ if (mSmbusContext == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ mSmbusContext->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ mSmbusContext->IoDone = IoDone;
+ mSmbusContext->SmbusIoRead = SmbusIoRead;
+ mSmbusContext->SmbusIoWrite = SmbusIoWrite;
+ mSmbusContext->SmbusController.Execute = SmbusExecute;
+ mSmbusContext->SmbusController.ArpDevice = SmbusArpDevice;
+ mSmbusContext->SmbusController.GetArpMap = SmbusGetArpMap;
+ mSmbusContext->SmbusController.Notify = SmbusNotify;
+ mSmbusContext->PlatformNumRsvd = PchPlatformPolicy->SmbusConfig->NumRsvdSmbusAddresses;
+ mSmbusContext->PlatformRsvdAddr = PchPlatformPolicy->SmbusConfig->RsvdSmbusAddressTable;
+
+ ///
+ /// See if PEI already ARPed any devices, and if so, update our device map.
+ ///
+ /// Get Hob list
+ ///
+ Status = EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &HobList.Raw);
+ ASSERT_EFI_ERROR (Status);
+
+ HobList.Raw = GetNextGuidHob (&mEfiSmbusArpMapGuid, HobList.Raw);
+ ///
+ /// If we found the right hob, store the information. Otherwise, continue.
+ ///
+ if (HobList.Raw != NULL) {
+ Data = (VOID *) ((UINT8 *) (&HobList.Guid->Name) + sizeof (EFI_GUID));
+ DataSize = HobList.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE);
+ CopyMem (mSmbusContext->DeviceMap, Data, DataSize);
+ mSmbusContext->DeviceMapEntries = (UINT8) (DataSize / sizeof (EFI_SMBUS_DEVICE_MAP));
+ }
+ ///
+ /// Initialize the NotifyFunctionList
+ ///
+ InitializeListHead (&mSmbusContext->NotifyFunctionList);
+
+ ///
+ /// Install the SMBUS interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusContext->Handle,
+ &gEfiSmbusProtocolGuid,
+ &mSmbusContext->SmbusController,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbus() End\n"));
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs
new file mode 100644
index 0000000..30bfdc5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.dxs
@@ -0,0 +1,44 @@
+/** @file
+ Dependency expression file for PCH SMBUS PEIM.
+
+@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 "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"
+#include "Common/EdkIIGlueDefinitionChangesPeim.h"
+
+#include EFI_PPI_DEFINITION (SmbusPolicy)
+#endif
+
+DEPENDENCY_START
+ PEI_SMBUS_POLICY_PPI_GUID
+DEPENDENCY_END
+
+
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h
new file mode 100644
index 0000000..fe64e8a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbus.h
@@ -0,0 +1,409 @@
+/** @file
+ PCH Smbus PPI
+
+@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
+
+**/
+#ifndef _PEI_PCH_SMBUS_H_
+#define _PEI_PCH_SMBUS_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 "EdkIIGluePeim.h"
+
+//
+// Driver Produced PPI Prototypes
+//
+#include EFI_PPI_PRODUCER (Smbus)
+//
+// Driver Consumed PPI Prototypes
+//
+#include EFI_PPI_CONSUMER (EndOfPeiSignal)
+#include EFI_PPI_CONSUMER (SmbusPolicy)
+#include EFI_PPI_CONSUMER (MemoryDiscovered)
+#include EFI_GUID_DEFINITION (SmbusArpMap)
+#include "PchSmbusCommon.h"
+#endif
+///
+/// Max number of SMBus devices
+/// (7 bit address yields 128 combinations but 21 of those are reserved)
+/// Due to limited resources, we only allow 8 in PEI.
+///
+#define MAX_SMBUS_DEVICES 8
+
+#define MAX_SMBUS_NOTIFICATION 8
+
+///
+/// Private Data Structures
+///
+typedef struct _PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE {
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINTN Data;
+ EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction;
+} PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE;
+
+///
+/// Declare a local instance structure for this PEIM
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_SMBUS_POLICY_PPI *SmbusPolicy;
+ UINTN SmbusIoBase;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ EFI_PEI_SMBUS_PPI SmbusPpi;
+ EFI_PEI_NOTIFY_DESCRIPTOR NotifyDescriptor;
+ UINT8 DeviceMapEntries;
+ EFI_SMBUS_DEVICE_MAP DeviceMap[MAX_SMBUS_DEVICES];
+ UINT8 PlatformNumRsvd;
+ UINT8 *PlatformRsvdAddr;
+
+ UINT8 NotifyFunctionNum;
+ PEI_SMBUS_NOTIFY_FUNCTION_LIST_NODE NotifyFunctionList[MAX_SMBUS_NOTIFICATION];
+} SMBUS_INSTANCE;
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) PEI_CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE)
+
+#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \
+ PEI_CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ PpiDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \
+ PEI_CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ NotifyDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#else
+
+#define SMBUS_PRIVATE_DATA_FROM_PPI_THIS(a) CR (a, SMBUS_INSTANCE, SmbusPpi, PCH_SMBUS_PRIVATE_DATA_SIGNATURE)
+
+#define SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS(a) \
+ CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ PpiDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#define SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS(a) \
+ CR ( \
+ a, \
+ SMBUS_INSTANCE, \
+ NotifyDescriptor, \
+ PCH_SMBUS_PRIVATE_DATA_SIGNATURE \
+ )
+
+#endif
+//
+// Prototypes
+//
+
+/**
+ This function provides a standard way to execute an SMBUS command
+ PPI as defined in the SMBus Specification. The data can either be of
+ the length byte, word, or a block of data (1 to 32 bytes long).
+ The resulting transaction will be either the SMBus Slave Device accepts
+ this transaction or this function returns with an error
+
+ @param[in] PeiServices PEI services table pointer
+ @param[in] This PEI_SMBUS_PPI instance
+ @param[in] SlaveAddress Smbus Slave device address
+ @param[in] Command Command to be sent
+ @param[in] Operation Which SMBus PPI will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS Operation success.
+ Length will contain the actual number of bytes read.
+ Buffer will contain the data read.
+ @retval Otherwise Operation failed.
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Initialize the Smbus PPI and program the Smbus BAR
+
+ @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
+InitializePchSmbusPeim (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @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 The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+/**
+ This function initializes the SmBus driver in PEI.
+
+ @param[in] PeiServices Standard PEI services
+ @param[in] Private SMBUS private data structure
+
+ @retval None.
+**/
+VOID
+InitializePeiPrivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ );
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ );
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices.
+ Or there is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ );
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ );
+
+/**
+ This function gets called back at the end of PEI if any devices were ARPed
+ during PEI. It will build a HOB to describe to DXE what devices were ARPed.
+
+ @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 EndOfPeiSignal PPI.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c
new file mode 100644
index 0000000..9ba5647
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArp.c
@@ -0,0 +1,444 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we want ARP support.
+
+@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
+
+**/
+#include "PchSmbus.h"
+
+///
+/// These addresses are reserved by the SMBus 2.0 specification
+///
+static UINT8 mReservedAddress[SMBUS_NUM_RESERVED] = {
+ 0x00,
+ 0x02,
+ 0x04,
+ 0x06,
+ 0x08,
+ 0x0A,
+ 0x0C,
+ 0x0E,
+ 0x10,
+ 0x18,
+ 0x50,
+ 0x6E,
+ 0xC2,
+ 0xF0,
+ 0xF2,
+ 0xF4,
+ 0xF6,
+ 0xF8,
+ 0xFA,
+ 0xFC,
+ 0xFE,
+ 0x12,
+ 0x14,
+ 0x16,
+ 0x58,
+ 0x5A,
+ 0x80,
+ 0x82,
+ 0x84,
+ 0x86,
+ 0x88,
+ 0x90,
+ 0x92,
+ 0x94,
+ 0x96,
+ 0x1A,
+ 0x1C,
+ 0x1E
+};
+
+/**
+ Issue a prepare ARP command to informs all devices that the ARP Master is starting the ARP process
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusPrepareToArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() Start\n"));
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = 1;
+ Buffer = SMBUS_DATA_PREPARE_TO_ARP;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ 0,
+ EfiSmbusSendByte,
+ TRUE,
+ &Length,
+ &Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusPrepareToArp() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Get UDID (general) command to requests ARP-capable and/or Discoverable devices to
+ return their slave address along with their UDID.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that slave device return
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusGetUdidGeneral (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() Start\n"));
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_GET_UDID_GENERAL,
+ EfiSmbusReadBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if (Length == SMBUS_GET_UDID_LENGTH) {
+ DeviceMap->SmbusDeviceUdid.DeviceCapabilities = Buffer[0];
+ DeviceMap->SmbusDeviceUdid.VendorRevision = Buffer[1];
+ DeviceMap->SmbusDeviceUdid.VendorId = (UINT16) ((Buffer[2] << 8) + Buffer[3]);
+ DeviceMap->SmbusDeviceUdid.DeviceId = (UINT16) ((Buffer[4] << 8) + Buffer[5]);
+ DeviceMap->SmbusDeviceUdid.Interface = (UINT16) ((Buffer[6] << 8) + Buffer[7]);
+ DeviceMap->SmbusDeviceUdid.SubsystemVendorId = (UINT16) ((Buffer[8] << 8) + Buffer[9]);
+ DeviceMap->SmbusDeviceUdid.SubsystemDeviceId = (UINT16) ((Buffer[10] << 8) + Buffer[11]);
+ DeviceMap->SmbusDeviceUdid.VendorSpecificId = (UINT32) ((Buffer[12] << 24) + (Buffer[13] << 16) + (Buffer[14] << 8) + Buffer[15]);
+ DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress = (UINT8) (Buffer[16] >> 1);
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusGetUdidGeneral() End\n"));
+
+ return Status;
+}
+
+/**
+ Issue a Assign address command to assigns an address to a specific slave device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in, out] DeviceMap Pointer to SMBUS device map table that send to slave device
+
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusAssignAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN OUT EFI_SMBUS_DEVICE_MAP *DeviceMap
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_STATUS Status;
+ UINTN Length;
+ UINT8 Buffer[SMBUS_GET_UDID_LENGTH];
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() Start\n"));
+
+ Buffer[0] = DeviceMap->SmbusDeviceUdid.DeviceCapabilities;
+ Buffer[1] = DeviceMap->SmbusDeviceUdid.VendorRevision;
+ Buffer[2] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId >> 8);
+ Buffer[3] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorId);
+ Buffer[4] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId >> 8);
+ Buffer[5] = (UINT8) (DeviceMap->SmbusDeviceUdid.DeviceId);
+ Buffer[6] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface >> 8);
+ Buffer[7] = (UINT8) (DeviceMap->SmbusDeviceUdid.Interface);
+ Buffer[8] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId >> 8);
+ Buffer[9] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemVendorId);
+ Buffer[10] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId >> 8);
+ Buffer[11] = (UINT8) (DeviceMap->SmbusDeviceUdid.SubsystemDeviceId);
+ Buffer[12] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 24);
+ Buffer[13] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 16);
+ Buffer[14] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId >> 8);
+ Buffer[15] = (UINT8) (DeviceMap->SmbusDeviceUdid.VendorSpecificId);
+ Buffer[16] = (UINT8) (DeviceMap->SmbusDeviceAddress.SmbusDeviceAddress << 1);
+
+ SlaveAddress.SmbusDeviceAddress = SMBUS_ADDRESS_ARP;
+ Length = SMBUS_GET_UDID_LENGTH;
+
+ Status = SmbusExec (
+ SlaveAddress,
+ SMBUS_DATA_ASSIGN_ADDRESS,
+ EfiSmbusWriteBlock,
+ TRUE,
+ &Length,
+ Buffer
+ );
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusAssignAddress() End\n"));
+
+ return Status;
+}
+
+/**
+ Do a fully (general) Arp procress to assign the slave address of all ARP-capable device.
+ This function will issue issue the "Prepare to ARP", "Get UDID" and "Assign Address" commands.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval EFI_OUT_OF_RESOURCES No available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusFullArp (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() Start\n"));
+
+ Status = SmbusPrepareToArp (Private);
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_DEVICE_ERROR) {
+ ///
+ /// ARP is complete
+ ///
+ return EFI_SUCCESS;
+ } else {
+ return Status;
+ }
+ }
+ ///
+ /// Main loop to ARP all ARP-capable devices
+ ///
+ do {
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+ Status = SmbusGetUdidGeneral (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ if (CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress == (0xFF >> 1)) {
+ ///
+ /// If address is unassigned, assign it
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (((CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities) & 0xC0) != 0) {
+ ///
+ /// if address is not fixed, check if the current address is available
+ ///
+ if (!IsAddressAvailable (
+ Private,
+ CurrentDeviceMap->SmbusDeviceAddress
+ )) {
+ ///
+ /// if currently assigned address is already used, get a new one
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ ///
+ /// If there was a device error, just continue on and try again.
+ /// Other errors should be reported.
+ ///
+ if (Status != EFI_DEVICE_ERROR) {
+ return Status;
+ }
+ } else {
+ ///
+ /// If there was no error, the address was assigned and we must update our
+ /// records.
+ ///
+ Private->DeviceMapEntries++;
+ }
+
+ } while (Private->DeviceMapEntries < MAX_SMBUS_DEVICES);
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusFullArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Do a directed Arp procress to assign the slave address of a single ARP-capable device.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES DeviceMapEntries is more than Max number of SMBus devices.
+ Or there is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+SmbusDirectedArp (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_UDID *SmbusUdid,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ EFI_STATUS Status;
+ EFI_SMBUS_DEVICE_MAP *CurrentDeviceMap;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() Start\n"));
+
+ if (Private->DeviceMapEntries >= MAX_SMBUS_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap = &Private->DeviceMap[Private->DeviceMapEntries];
+
+ ///
+ /// Find an available address to assign
+ ///
+ Status = GetNextAvailableAddress (
+ Private,
+ &CurrentDeviceMap->SmbusDeviceAddress
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceCapabilities = SmbusUdid->DeviceCapabilities;
+ CurrentDeviceMap->SmbusDeviceUdid.DeviceId = SmbusUdid->DeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.Interface = SmbusUdid->Interface;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemDeviceId = SmbusUdid->SubsystemDeviceId;
+ CurrentDeviceMap->SmbusDeviceUdid.SubsystemVendorId = SmbusUdid->SubsystemVendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorId = SmbusUdid->VendorId;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorRevision = SmbusUdid->VendorRevision;
+ CurrentDeviceMap->SmbusDeviceUdid.VendorSpecificId = SmbusUdid->VendorSpecificId;
+
+ Status = SmbusAssignAddress (Private, CurrentDeviceMap);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Private->DeviceMapEntries++;
+ SlaveAddress->SmbusDeviceAddress = CurrentDeviceMap->SmbusDeviceAddress.SmbusDeviceAddress;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusDirectedArp() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Find an available address to assign
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @retval EFI_OUT_OF_RESOURCES There is no available address to assign
+ @retval EFI_SUCCESS The function completed successfully
+**/
+EFI_STATUS
+GetNextAvailableAddress (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress
+ )
+{
+ for (SlaveAddress->SmbusDeviceAddress = 0x03;
+ SlaveAddress->SmbusDeviceAddress < 0x7F;
+ SlaveAddress->SmbusDeviceAddress++
+ ) {
+ if (IsAddressAvailable (Private, *SlaveAddress)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_OUT_OF_RESOURCES;
+}
+
+/**
+ Check whether the address is assignable.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+ @param[in] SlaveAddress The Slave Address for checking
+
+ @retval TRUE The address is assignable
+ @retval FALSE The address is not assignable
+**/
+BOOLEAN
+IsAddressAvailable (
+ IN SMBUS_INSTANCE *Private,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress
+ )
+{
+ UINT8 Index;
+
+ ///
+ /// See if we have already assigned this address to a device
+ ///
+ for (Index = 0; Index < Private->DeviceMapEntries; Index++) {
+ if (SlaveAddress.SmbusDeviceAddress == Private->DeviceMap[Index].SmbusDeviceAddress.SmbusDeviceAddress) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this address is claimed by a platform non-ARP-capable device
+ ///
+ for (Index = 0; Index < Private->PlatformNumRsvd; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == Private->PlatformRsvdAddr[Index]) {
+ return FALSE;
+ }
+ }
+ ///
+ /// See if this is a reserved address
+ ///
+ for (Index = 0; Index < SMBUS_NUM_RESERVED; Index++) {
+ if ((SlaveAddress.SmbusDeviceAddress << 1) == (UINTN) mReservedAddress[Index]) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif
new file mode 100644
index 0000000..6682817
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusArpDisabled"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei"
+ RefName = "PchSmbusArpDisabled"
+[files]
+"PchSmbusArpDisabled.sdl"
+"PchSmbusArpDisabled.mak"
+"PchSmbusEntry.c"
+"PchSmbus.h"
+"PchSmbusArpdisabled.c"
+"PchSmbus.dxs"
+"PchSmbusArpDisabled.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf
new file mode 100644
index 0000000..a66047e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.inf
@@ -0,0 +1,88 @@
+## @file
+# Component description file for PchSmbus module
+# This version will NOT include ARP support.
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchSmbusArpDisabled
+FILE_GUID = 643DF777-F312-42ed-81CC-1B1F57E18AD6
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchSmbus.h
+ PchSmbusEntry.c
+ PchSmbusArpDisabled.c
+ ../Common/PchSmbusExec.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
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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]
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim
+ C_FLAGS = $(C_FLAGS) -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__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.mak
new file mode 100644
index 0000000..531b08e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.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/PchSmbusArpDisabled/PchSmbusArpDisabled.mak 2 2/24/12 2:23a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:23a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.mak $
+#
+# 2 2/24/12 2:23a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:20a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusArpDisabled Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusArpDisabled
+PchSmbusArpDisabled : $(BUILD_DIR)\PchSmbusArpDisabled.mak PchSmbusArpDisabledBin
+
+
+$(BUILD_DIR)\PchSmbusArpDisabled.mak : $(PchSmbusArpDisabled_DIR)\$(@B).cif $(PchSmbusArpDisabled_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusArpDisabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusArpDisabled_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusArpDisabled_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\
+ /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_CF8_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusArpDisabled_LIB_LINKS =\
+ $(EDKFRAMEWORKPPILIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchSmbusCommonPeiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibCf8_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchSmbusArpDisabledBin: $(PchSmbusArpDisabled_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusArpDisabled.mak all\
+ NAME=PchSmbusArpDisabled\
+ MAKEFILE=$(BUILD_DIR)\PchSmbusArpDisabled.mak \
+ GUID=643DF777-F312-42ed-81CC-1B1F57E18AD6\
+ "MY_INCLUDES=$(PchSmbusArpDisabled_INCLUDES)"\
+ "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpDisabled_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchSmbusArpDisabled_DIR)\PchSmbus.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/Smbus/Pei/PchSmbusArpDisabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.sdl
new file mode 100644
index 0000000..23e79a5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpDisabled.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/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl 1 2/08/12 9:20a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:20a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpDisabled/PchSmbusArpDisabled.sdl $
+#
+# 1 2/08/12 9:20a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusArpDisabled_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSmbusArpDisabled support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusArpDisabled_DIR"
+ Help = "PchSmbusArpDisabled file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusArpDisabled.mak to Project"
+ File = "PchSmbusArpDisabled.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusArpDisabled.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/Smbus/Pei/PchSmbusArpEnabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c
new file mode 100644
index 0000000..91a8614
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.c
@@ -0,0 +1,291 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we want ARP support.
+
+@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
+
+**/
+#include "PchSmbus.h"
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEndOfPeiSignalPpiGuid,
+ EndOfPeiCallback
+};
+
+EFI_GUID mEfiSmbusArpMapGuid = EFI_SMBUS_ARP_MAP_GUID;
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ SMBUS_INSTANCE *Private;
+ EFI_STATUS Status;
+ UINT8 OldMapEntries;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() Start\n"));
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ OldMapEntries = Private->DeviceMapEntries;
+
+ if (ArpAll) {
+ Status = SmbusFullArp (Private);
+ } else {
+ if ((SmbusUdid == NULL) || (SlaveAddress == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SmbusDirectedArp (Private, SmbusUdid, SlaveAddress);
+ }
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// If we just added the first entry in the device map, set up a callback so
+ /// we can pass the map to DXE via a HOB at the end of PEI.
+ ///
+ if ((OldMapEntries == 0) && (Private->DeviceMapEntries > 0)) {
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mNotifyList);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusArpDevice() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ *Length = Private->DeviceMapEntries * sizeof (EFI_SMBUS_DEVICE_MAP);
+ *SmbusDeviceMap = Private->DeviceMap;
+ return EFI_SUCCESS;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusNotify() Start\n"));
+
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ if (NotifyFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// NOTE: Currently there is no periodic event in PEI.
+ /// So we just check the Notification at the end of in each
+ /// Smbus.Execute function.
+ ///
+ if (Private->NotifyFunctionNum >= MAX_SMBUS_NOTIFICATION) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].SlaveAddress.SmbusDeviceAddress = SlaveAddress.SmbusDeviceAddress;
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].Data = Data;
+ Private->NotifyFunctionList[Private->NotifyFunctionNum].NotifyFunction = NotifyFunction;
+ Private->NotifyFunctionNum++;
+
+ ///
+ /// Last step, check notification
+ ///
+ CheckNotification (Private);
+
+ DEBUG ((EFI_D_INFO, "PEI SmbusNotify() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function gets called back at the end of PEI if any devices were ARPed
+ during PEI. It will build a HOB to describe to DXE what devices were ARPed.
+
+ @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 EndOfPeiSignal PPI.
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *SmbusDescriptor;
+ PEI_SMBUS_PPI *SmbusPpi;
+ SMBUS_INSTANCE *Private;
+ UINTN BufferSize;
+ VOID *Hob;
+
+ DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() Start\n"));
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPeiSmbusPpiGuid, /// GUID
+ 0, /// INSTANCE
+ &SmbusDescriptor, /// PEI_PPI_DESCRIPTOR
+ &SmbusPpi /// PPI
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Private = SMBUS_PRIVATE_DATA_FROM_DESCRIPTOR_THIS (SmbusDescriptor);
+ BufferSize = sizeof (EFI_SMBUS_DEVICE_MAP) * Private->DeviceMapEntries;
+
+ Hob = BuildGuidDataHob (
+ &mEfiSmbusArpMapGuid,
+ Private->DeviceMap,
+ BufferSize
+ );
+ ASSERT (Hob != NULL);
+
+ DEBUG ((EFI_D_INFO, "PEI EndOfPeiCallback() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ UINT8 SstsReg;
+ UINTN Data;
+ UINTN Index;
+
+ DEBUG ((EFI_D_INFO, "PEI CheckNotification() Start\n"));
+
+ if (Private->NotifyFunctionNum == 0) {
+ ///
+ /// Since no one register it, not need to check.
+ ///
+ return;
+ }
+
+ SstsReg = SmbusIoRead (R_PCH_SMBUS_SSTS);
+ if (!(SstsReg & B_PCH_SMBUS_HOST_NOTIFY_STS)) {
+ ///
+ /// Host Notify has not been received
+ ///
+ return;
+ }
+ ///
+ /// There was a Host Notify, see if any one wants to know about it
+ ///
+ SlaveAddress.SmbusDeviceAddress = (SmbusIoRead (R_PCH_SMBUS_NDA)) >> 1;
+
+ for (Index = 0; Index < Private->NotifyFunctionNum; Index++) {
+
+ if (Private->NotifyFunctionList[Index].SlaveAddress.SmbusDeviceAddress == SlaveAddress.SmbusDeviceAddress) {
+ Data = (SmbusIoRead (R_PCH_SMBUS_NDHB) << 8) + (SmbusIoRead (R_PCH_SMBUS_NDLB));
+ if ((UINT16) Private->NotifyFunctionList[Index].Data == (UINT16) Data) {
+ ///
+ /// We have a match, notify the requested function
+ ///
+ Private->NotifyFunctionList[Index].NotifyFunction (
+ Private->PeiServices,
+ &Private->SmbusPpi,
+ SlaveAddress,
+ Data
+ );
+ }
+ }
+ }
+ ///
+ /// Clear the Notify Status bit and exit.
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_SSTS, B_PCH_SMBUS_HOST_NOTIFY_STS);
+
+ DEBUG ((EFI_D_INFO, "PEI CheckNotification() End\n"));
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif
new file mode 100644
index 0000000..5674891
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "PchSmbusArpEnabled"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Pei"
+ RefName = "PchSmbusArpEnabled"
+[files]
+"PchSmbusArpEnabled.sdl"
+"PchSmbusArpEnabled.mak"
+"PchSmbusEntry.c"
+"PchSmbus.h"
+"PchSmbusArpEnabled.c"
+"PchSmbusArp.c"
+"PchSmbus.dxs"
+"PchSmbusArpEnabled.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf
new file mode 100644
index 0000000..c4a23f1
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.inf
@@ -0,0 +1,91 @@
+## @file
+# Component description file for PchSmbus module
+# This version will include ARP support.
+#
+#@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 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 = PchSmbusArpEnabled
+FILE_GUID = 22B194B4-CC0E-46c7-9FCE-DA10D6ED1731
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchSmbus.h
+ PchSmbusEntry.c
+ PchSmbusArpEnabled.c
+ PchSmbusArp.c
+ ../Common/PchSmbusExec.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
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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]
+ EdkFrameworkPpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGluePeiHobLib
+ EdkIIGlueBasePciLibPciExpress
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=PeimInitializePchSmbus
+ C_FLAGS = $(C_FLAGS) -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_PEI_HOB_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.mak
new file mode 100644
index 0000000..b1b2ce9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.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/PchSmbusArpEnabled/PchSmbusArpEnabled.mak 2 2/24/12 2:29a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:29a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.mak $
+#
+# 2 2/24/12 2:29a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:28a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbusArpEnabled Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusArpEnabled
+PchSmbusArpEnabled : $(BUILD_DIR)\PchSmbusArpEnabled.mak PchSmbusArpEnabledBin
+
+
+$(BUILD_DIR)\PchSmbusArpEnabled.mak : $(PchSmbusArpEnabled_DIR)\$(@B).cif $(PchSmbusArpEnabled_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusArpEnabled_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusArpEnabled_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusArpEnabled_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusPeim"\
+ /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_PEI_HOB_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusArpEnabled_LIB_LINKS =\
+ $(EDKFRAMEWORKPPILIB)\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchSmbusCommonPeiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(EdkIIGluePeiHobLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchSmbusArpEnabledBin: $(PchSmbusArpEnabled_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusArpEnabled.mak all\
+ NAME=PchSmbusArpEnabled\
+ MAKEFILE=$(BUILD_DIR)\PchSmbusArpEnabled.mak \
+ GUID=22B194B4-CC0E-46c7-9FCE-DA10D6ED1731\
+ "MY_INCLUDES=$(PchSmbusArpEnabled_INCLUDES)"\
+ "MY_DEFINES=$(MY_DEFINES) $(PchSmbusArpEnabled_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchSmbusArpEnabled_DIR)\PchSmbus.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/Smbus/Pei/PchSmbusArpEnabled.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.sdl
new file mode 100644
index 0000000..dcb1377
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpEnabled.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/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl 1 2/08/12 9:28a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:28a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusArpEnabled/PchSmbusArpEnabled.sdl $
+#
+# 1 2/08/12 9:28a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusArpEnabled_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable PchSmbusArpEnabled support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSmbusArpEnabled_DIR"
+ Help = "PchSmbusArpEnabled file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusArpEnabled.mak to Project"
+ File = "PchSmbusArpEnabled.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusArpEnabled.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/Smbus/Pei/PchSmbusArpdisabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c
new file mode 100644
index 0000000..b249317
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusArpdisabled.c
@@ -0,0 +1,117 @@
+/** @file
+ PCH Smbus PEIM. This file is used when we do not want ARP support.
+
+@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 "PchSmbus.h"
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid OPTIONAL,
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] PeiServices Pointer to the PEI Services table.
+ @param[in] This Pointer to the instance of the PEI_SMBUS_PPI.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] PeiServices The general PEI Services
+ @param[in] This The PPI instance
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_PEI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ ///
+ /// Requires a periodic event, not supported in PEI
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Function to be called when SMBus.Execute happens. This will check if
+ the SMBus Host Controller has received a Host Notify command. If so, it will
+ see if a notification has been reqested on that event and make any callbacks
+ that may be necessary.
+
+ @param[in] Private Pointer to the SMBUS_INSTANCE
+
+ @retval None
+**/
+VOID
+CheckNotification (
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ return;
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c
new file mode 100644
index 0000000..3e4a6a0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Pei/PchSmbusEntry.c
@@ -0,0 +1,241 @@
+/** @file
+ PCH Smbus PEIM.
+
+@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 "PchSmbus.h"
+
+///
+/// Global variables
+///
+EFI_GUID mPeiSmbusPolicyPpiGuid = PEI_SMBUS_POLICY_PPI_GUID;
+
+//
+// Functions
+//
+
+/**
+ This function provides a standard way to execute an SMBUS command
+ PPI as defined in the SMBus Specification. The data can either be of
+ the length byte, word, or a block of data (1 to 32 bytes long).
+ The resulting transaction will be either the SMBus Slave Device accepts
+ this transaction or this function returns with an error
+
+ @param[in] PeiServices PEI services table pointer
+ @param[in] This PEI_SMBUS_PPI instance
+ @param[in] SlaveAddress Smbus Slave device address
+ @param[in] Command Command to be sent
+ @param[in] Operation Which SMBus PPI will be used
+ @param[in] PecCheck Defines if Packet Error Code Checking is to be used
+ @param[in, out] Length How many bytes to read/write. Must be 1 <= Length <= 32 depending on the Operation
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS Operation success.
+ Length will contain the actual number of bytes read.
+ Buffer will contain the data read.
+ @retval Otherwise Operation failed.
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SMBUS_PPI *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_INSTANCE *Private;
+ DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() Start, SmbusDeviceAddress=%x, Command=%x, Operation=%x\n", (SlaveAddress.SmbusDeviceAddress << 1), Command, Operation));
+ Private = SMBUS_PRIVATE_DATA_FROM_PPI_THIS (This);
+
+ Status = SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+ ///
+ /// Last step, check notification
+ ///
+ CheckNotification (Private);
+ DEBUG ((EFI_D_EVENT, "PEI SmbusExecute() End\n"));
+ return Status;
+}
+
+/**
+ Initialize the Smbus PPI and program the Smbus BAR
+
+ @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
+InitializePchSmbusPeim (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ SMBUS_INSTANCE *Private;
+ UINTN SmbusRegBase;
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() Start\n"));
+
+ Private = (SMBUS_INSTANCE *) AllocatePool (sizeof (SMBUS_INSTANCE));
+ if (Private == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for Private! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializePeiPrivate (PeiServices, Private);
+
+ SmbusRegBase = MmPciAddress (
+ 0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_SMBUS,
+ PCI_FUNCTION_NUMBER_PCH_SMBUS,
+ 0
+ );
+ ///
+ /// Since PEI has no PCI enumerator, set the BAR & I/O space enable ourselves
+ ///
+ MmioAndThenOr32 (SmbusRegBase + R_PCH_SMBUS_BASE, B_PCH_SMBUS_BASE_BAR, Private->SmbusIoBase);
+
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_PCICMD, B_PCH_SMBUS_PCICMD_IOSE);
+
+ ///
+ /// Reset the SMBus host controller
+ ///
+ MmioOr8 (SmbusRegBase + R_PCH_SMBUS_HOSTC, B_PCH_SMBUS_HOSTC_SSRESET);
+
+ ///
+ /// Enable the SMBus host controller
+ ///
+ MmioAndThenOr8 (
+ SmbusRegBase + R_PCH_SMBUS_HOSTC,
+ (UINT8) (~(B_PCH_SMBUS_HOSTC_SMI_EN | B_PCH_SMBUS_HOSTC_I2C_EN)),
+ B_PCH_SMBUS_HOSTC_HST_EN
+ );
+
+ ///
+ /// Clear Status Register before anyone uses the interfaces
+ ///
+ SmbusIoWrite (R_PCH_SMBUS_HSTS, B_PCH_SMBUS_HSTS_ALL);
+
+ Status = PeiServicesInstallPpi (&Private->PpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Install a call-back for the permanent-memory so that we can fix up internal pointers
+ ///
+ Status = (**PeiServices).NotifyPpi (PeiServices, &Private->NotifyDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitializePchSmbusPeim() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function initializes the SmBus driver in PEI.
+
+ @param[in] PeiServices Standard PEI services
+ @param[in] Private SMBUS private data structure
+
+ @retval None.
+**/
+VOID
+InitializePeiPrivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN SMBUS_INSTANCE *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ Private->PeiServices = PeiServices;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &mPeiSmbusPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &(Private->SmbusPolicy)
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Private->SmbusIoBase = Private->SmbusPolicy->BaseAddress;
+
+ Private->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ Private->PpiDescriptor.Guid = &gEfiPeiSmbusPpiGuid;
+
+ Private->PpiDescriptor.Ppi = &Private->SmbusPpi;
+
+ Private->SmbusPpi.Execute = SmbusExecute;
+ Private->SmbusPpi.ArpDevice = SmbusArpDevice;
+ Private->SmbusPpi.GetArpMap = SmbusGetArpMap;
+ Private->SmbusPpi.Notify = SmbusNotify;
+
+ Private->NotifyDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ Private->NotifyDescriptor.Guid = &gEfiPeiMemoryDiscoveredPpiGuid;
+ Private->NotifyDescriptor.Notify = MemoryDiscoveredPpiNotifyCallback;
+
+ Private->DeviceMapEntries = 0;
+ Private->PlatformNumRsvd = Private->SmbusPolicy->NumRsvdAddress;
+ Private->PlatformRsvdAddr = Private->SmbusPolicy->RsvdAddress;
+
+ Private->NotifyFunctionNum = 0;
+
+ return;
+}
+
+/**
+ Fix up pointers since they are located in real memory now.
+
+ @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 The function completed successfully.
+**/
+EFI_STATUS
+EFIAPI
+MemoryDiscoveredPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ SMBUS_INSTANCE *Private;
+
+ Private = SMBUS_PRIVATE_DATA_FROM_NOTIFY_THIS (NotifyDescriptor);
+
+ InitializePeiPrivate (PeiServices, Private);
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs
new file mode 100644
index 0000000..287dd96
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.dxs
@@ -0,0 +1,41 @@
+/** @file
+ Dependency expression source file.
+
+@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 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 (SmmBase)
+#include EFI_PROTOCOL_DEFINITION (Smbus)
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h
new file mode 100644
index 0000000..8b99bcd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbus.h
@@ -0,0 +1,183 @@
+/** @file
+ PCH Smbus Protocol
+
+@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 _SMM_PCH_SMBUS_H
+#define _SMM_PCH_SMBUS_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"
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (Smbus)
+#include EFI_PROTOCOL_PRODUCER (SmmSmbus)
+
+//
+// Driver Consumed Protcol Prototypes
+//
+#include "PchSmbusCommon.h"
+#endif
+//
+// Definitions
+//
+///
+/// Max number of SMBus devices (7 bit address yields 128 combinations but 21 of those are reserved)
+///
+#define MAX_SMBUS_DEVICES 107
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+///
+/// Declare a local instance structure for this driver
+///
+typedef struct _SMBUS_INSTANCE {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ UINT32 SmbusIoBase;
+ SMBUS_IO_READ SmbusIoRead;
+ SMBUS_IO_WRITE SmbusIoWrite;
+ SMBUS_IO_DONE IoDone;
+
+ ///
+ /// Published interface
+ ///
+ EFI_SMBUS_HC_PROTOCOL SmbusController;
+
+} SMBUS_INSTANCE;
+
+SMBUS_INSTANCE *mSmbusContext;
+
+//
+// Prototypes
+//
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ );
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbusSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ );
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ );
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c
new file mode 100644
index 0000000..89b9fbc
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusArpDisabled.c
@@ -0,0 +1,103 @@
+/** @file
+ PCH Smbus Driver, ARP functions not supported
+
+@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
+**/
+#include "PchSmbus.h"
+
+/**
+ Set Slave address for an Smbus device with a known UDID or perform a general
+ ARP of all devices.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] ArpAll If TRUE, do a full ARP. Otherwise, just ARP the specified UDID.
+ @param[in] SmbusUdid When doing a directed ARP, ARP the device with this UDID.
+ @param[in, out] SlaveAddress Buffer to store new Slave Address during directed ARP. On output,If
+ ArpAlll == TRUE, this will contain the newly assigned Slave address.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+ IN EFI_SMBUS_HC_PROTOCOL * This,
+ IN BOOLEAN ArpAll,
+ IN EFI_SMBUS_UDID * SmbusUdid, OPTIONAL
+ IN OUT EFI_SMBUS_DEVICE_ADDRESS * SlaveAddress OPTIONAL
+ )
+{
+ ///
+ /// ARP should be done in DXE SMBUS driver.
+ /// Not needed here.
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Get a pointer to the assigned mappings of UDID's to Slave Addresses.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in, out] Length Buffer to contain the lenght of the Device Map, it will be updated to
+ contain the number of pairs of UDID's mapped to Slave Addresses.
+ @param[in, out] SmbusDeviceMap Buffer to contian a pointer to the Device Map, it will be updated to
+ point to the first pair in the Device Map
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN OUT UINTN *Length,
+ IN OUT EFI_SMBUS_DEVICE_MAP **SmbusDeviceMap
+ )
+{
+ ///
+ /// ARP should be done in DXE SMBUS driver.
+ /// Not needed here.
+ ///
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Register a callback in the event of a Host Notify command being sent by a
+ specified Slave Device.
+
+ @param[in] This Pointer to the instance of the EFI_SMBUS_HC_PROTOCOL.
+ @param[in] SlaveAddress Address of the device whose Host Notify command we want to
+ trap.
+ @param[in] Data Data of the Host Notify command we want to trap.
+ @param[in] NotifyFunction Function to be called in the event the desired Host Notify
+ command occurs.
+
+ @exception EFI_UNSUPPORTED This functionality is not supported
+**/
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN UINTN Data,
+ IN EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+ )
+{
+ ///
+ /// Not needed for SMM.
+ ///
+ return EFI_UNSUPPORTED;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c
new file mode 100644
index 0000000..37cb621
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusEntry.c
@@ -0,0 +1,128 @@
+/** @file
+ PCH Smbus Driver Entry
+
+@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
+**/
+#include "PchSmbus.h"
+
+//
+// Global variables
+//
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+
+EFI_GUID mEfiSmmSmbusProtocolGuid = EFI_SMM_SMBUS_PROTOCOL_GUID;
+
+/**
+ Execute an SMBUS operation
+
+ @param[in] This The protocol instance
+ @param[in] SlaveAddress The address of the SMBUS slave device
+ @param[in] Command The SMBUS command
+ @param[in] Operation Which SMBus protocol will be issued
+ @param[in] PecCheck If Packet Error Code Checking is to be used
+ @param[in, out] Length Length of data
+ @param[in, out] Buffer Data buffer
+
+ @retval EFI_SUCCESS The SMBUS operation is successful
+ @retval Other Values Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+ IN EFI_SMBUS_HC_PROTOCOL *This,
+ IN EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+ IN EFI_SMBUS_DEVICE_COMMAND Command,
+ IN EFI_SMBUS_OPERATION Operation,
+ IN BOOLEAN PecCheck,
+ IN OUT UINTN *Length,
+ IN OUT VOID *Buffer
+ )
+{
+ InitializeSmbusRegisters ();
+
+ return SmbusExec (
+ SlaveAddress,
+ Command,
+ Operation,
+ PecCheck,
+ Length,
+ Buffer
+ );
+}
+
+/**
+ Smbus driver entry point
+
+ @param[in] ImageHandle ImageHandle of this module
+ @param[in] SystemTable EFI System Table
+
+ @retval EFI_SUCCESS Driver initializes successfully
+ @retval Other values Some error occurred
+**/
+EFI_STATUS
+EFIAPI
+InitializePchSmbusSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate SMM Base Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = mSmst->SmmAllocatePool (EfiRuntimeServicesData, sizeof (SMBUS_INSTANCE), (VOID **) &mSmbusContext);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ } else {
+ ZeroMem (mSmbusContext, sizeof (SMBUS_INSTANCE));
+
+ mSmbusContext->Signature = PCH_SMBUS_PRIVATE_DATA_SIGNATURE;
+ mSmbusContext->IoDone = IoDone;
+ mSmbusContext->SmbusIoRead = SmbusIoRead;
+ mSmbusContext->SmbusIoWrite = SmbusIoWrite;
+ mSmbusContext->SmbusController.Execute = SmbusExecute;
+ mSmbusContext->SmbusController.ArpDevice = SmbusArpDevice;
+ mSmbusContext->SmbusController.GetArpMap = SmbusGetArpMap;
+ mSmbusContext->SmbusController.Notify = SmbusNotify;
+
+ ///
+ /// Install the SMBUS interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmbusContext->Handle,
+ &mEfiSmmSmbusProtocolGuid,
+ &mSmbusContext->SmbusController,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif
new file mode 100644
index 0000000..884f322
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PchSmbusSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Smbus\Smm"
+ RefName = "PchSmbusSmm"
+[files]
+"PchSmbusSmm.sdl"
+"PchSmbusSmm.mak"
+"PchSmbus.h"
+"PchSmbusArpDisabled.c"
+"PchSmbusEntry.c"
+"PchSmbus.dxs"
+"PchSmbusSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf
new file mode 100644
index 0000000..bd5a8f8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.inf
@@ -0,0 +1,95 @@
+## @file
+# Component description file for PchSmbus 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 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 = PchSmbusSmm
+FILE_GUID = 59287178-59B2-49ca-BC63-532B12EA2C53
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSmbusEntry.c
+ PchSmbus.h
+ PchSmbusArpDisabled.c
+ ../Common/PchSmbusExec.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
+#
+# 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]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkProtocolLib
+ EdkFrameworkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchSmbus.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusSmm
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_LIB__ \
+ -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak
new file mode 100644
index 0000000..32274ff
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.mak
@@ -0,0 +1,105 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSmbusSmm/PchSmbusSmm.mak 2 2/24/12 2:28a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:28a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusSmm/PchSmbusSmm.mak $
+#
+# 2 2/24/12 2:28a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:27a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSmbus SMM Driver
+#---------------------------------------------------------------------------
+EDK : PchSmbusSmm
+PchSmbusSmm : $(BUILD_DIR)\PchSmbusSmm.mak PchSmbusSmmBin
+
+
+$(BUILD_DIR)\PchSmbusSmm.mak : $(PchSmbusSmm_DIR)\$(@B).cif $(PchSmbusSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSmbusSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSmbusSmm_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSmbusSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchSmbusSmm"\
+ /D __EDKII_GLUE_BASE_LIB__ \
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PchSmbusSmm_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformSmmLib_LIB) \
+ $(PchSmbusCommonSmmLib_LIB)
+
+PchSmbusSmmBin: $(PchSmbusSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSmbusSmm.mak all \
+ "MY_INCLUDES=$(PchSmbusSmm_INCLUDES)"\
+ "MY_DEFINES=$(PchSmbusSmm_DEFINES)"\
+ GUID=59287178-59B2-49ca-BC63-532B12EA2C53\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchSmbusSmm_DIR)\PchSmbus.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/Smbus/Smm/PchSmbusSmm.sdl b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.sdl
new file mode 100644
index 0000000..b2db358
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Smbus/Smm/PchSmbusSmm.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/PchSmbusSmm/PchSmbusSmm.sdl 1 2/08/12 9:27a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:27a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSmbusSmm/PchSmbusSmm.sdl $
+#
+# 1 2/08/12 9:27a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSmbusSmm_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSmbusSmm support in Project"
+End
+
+PATH
+ Name = "PchSmbusSmm_DIR"
+ Help = "PchSmbusSmm file source directory"
+End
+
+MODULE
+ Help = "Includes PchSmbusSmm.mak to Project"
+ File = "PchSmbusSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSmbusSmm.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/SmmControl/Pei/PeiSmmControl.cif b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.cif
new file mode 100644
index 0000000..4d83025
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PeiSmmControl"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SmmControl\Pei\"
+ RefName = "PeiSmmControl"
+[files]
+"PeiSmmControl.sdl"
+"PeiSmmControl.mak"
+"SmmControl.dxs"
+"SmmControl.inf"
+"SmmControlDriver.c"
+"SmmControlDriver.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.mak b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.mak
new file mode 100644
index 0000000..5199538
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.mak
@@ -0,0 +1,93 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, 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/PeiSmmControl/PeiSmmControl.mak 1 9/26/12 3:34a Victortu $
+#
+# $Revision: 1 $
+#
+# $Date: 9/26/12 3:34a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PeiSmmControl/PeiSmmControl.mak $
+#
+# 1 9/26/12 3:34a Victortu
+# Lynx Point PCH Chipset Framework Reference Code Beta 0.7.0
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiSmmControl.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+EDK : PeiSmmControl
+
+PeiSmmControl : $(BUILD_DIR)\PeiSmmControl.mak PeiSmmControlBin
+
+$(BUILD_DIR)\PeiSmmControl.mak : $(PeiSmmControl_DIR)\$(@B).cif $(PeiSmmControl_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiSmmControl_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiSmmControl_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PeiSmmControl_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=SmmControlPeiDriverEntryInit"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
+
+PeiSmmControl_LIB_LINKS =\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PeiSmmControlBin : $(PeiSmmControl_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiSmmControl.mak all\
+ "MY_INCLUDES=$(PeiSmmControl_INCLUDES)" \
+ "MY_DEFINES=$(PeiSmmControl_DEFINES)" \
+ GUID=FF456B9C-0DC7-4682-9E92-0DE84B6E4067\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PeiSmmControl_DIR)\SmmControl.dxs\
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX\
+ COMPRESS=0
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.sdl b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.sdl
new file mode 100644
index 0000000..8470880
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/PeiSmmControl.sdl
@@ -0,0 +1,24 @@
+TOKEN
+ Name = PeiSmmControl_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PeiSmmControl support in Project"
+End
+
+MODULE
+ Help = "Includes PeiSmmControl.mak to Project"
+ File = "PeiSmmControl.mak"
+End
+
+PATH
+ Name = "PeiSmmControl_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiSmmControl.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.dxs b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.dxs
new file mode 100644
index 0000000..2ff2cf2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.dxs
@@ -0,0 +1,35 @@
+/** @file
+ @todo ADD DESCRIPTION
+
+@copyright
+ Copyright (c) 2005 - 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
+
+**/
+
+//
+// Same for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "PeimDepex.h"
+//
+// For R8 only
+//
+#ifdef BUILD_WITH_EDKII_GLUE_LIB
+#include "EfiDepex.h"
+
+#endif
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.inf b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.inf
new file mode 100644
index 0000000..f65db70
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControl.inf
@@ -0,0 +1,76 @@
+## @file
+# Component description file for SmmControl module
+#
+#@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 = SmmControl
+FILE_GUID = FF456B9C-0DC7-4682-9E92-0DE84B6E4067
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ SmmControlDriver.h
+ SmmControlDriver.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ .
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Include/Pei
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/Library/Include
+ $(EFI_SOURCE)/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/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGlueBasePciLibPciExpress
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=SmmControl.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=SmmControlPeiDriverEntryInit
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_PEI_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_PEI_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_PEI_SERVICES_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.c b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.c
new file mode 100644
index 0000000..a4638e8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.c
@@ -0,0 +1,282 @@
+/** @file
+ This is the driver that publishes the SMM Control Ppi.
+
+@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 "SmmControlDriver.h"
+
+EFI_GUID mPeiSmmControlPpiGuid = PEI_SMM_CONTROL_PPI_GUID;
+
+STATIC PEI_SMM_CONTROL_PPI mSmmControlPpi = {
+ PeiActivate,
+ PeiDeactivate
+};
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &mPeiSmmControlPpiGuid,
+ &mSmmControlPpi
+};
+
+EFI_PEIM_ENTRY_POINT (SmmControlPeiDriverEntryInit)
+
+/**
+ This is the constructor for the SMM Control ppi
+
+ @param[in] FfsHeader FfsHeader.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Ppi
+**/
+EFI_STATUS
+EFIAPI
+SmmControlPeiDriverEntryInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mPpiList);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT32 PmBase;
+
+ PmBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ ///
+ /// Enable the APMC SMI
+ ///
+ OutputPort = PmBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_PCH_SMI_EN_APMC | B_PCH_SMI_EN_GBL_SMI);
+ DEBUG (
+ (EFI_D_INFO,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_PCH_APM_CNT;
+ OutputData = Data;
+
+ ///
+ /// Generate the APMC SMI
+ ///
+ IoWrite8 (
+ (UINTN) OutputPort,
+ (UINT8) (OutputData)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Clear the SMI status
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+ UINT32 PmBase;
+
+ PmBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ ///
+ /// Clear the Power Button Override Status Bit, it gates EOS from being set.
+ ///
+ OutputPort = PmBase + R_PCH_ACPI_PM1_STS;
+ OutputData = B_PCH_ACPI_PM1_STS_PRBTNOR;
+ DEBUG (
+ (EFI_D_INFO,
+ "The PM1 Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ ///
+ /// Clear the APM SMI Status Bit
+ ///
+ OutputPort = PmBase + R_PCH_SMI_STS;
+ OutputData = B_PCH_SMI_STS_APM;
+ DEBUG (
+ (EFI_D_INFO,
+ "The SMI Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = PmBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_PCH_SMI_EN_EOS;
+ DEBUG (
+ (EFI_D_INFO,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// If the EOS bit did not get set, then we've got a problem.
+ ///
+ DEBUG_CODE (
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ if ((OutputData & B_PCH_SMI_EN_EOS) != B_PCH_SMI_EN_EOS) {
+ DEBUG ((EFI_D_ERROR, "Bugger, EOS did not get set!\n"));
+ return EFI_DEVICE_ERROR;
+ }
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This routine generates an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ if (Periodic) {
+ DEBUG ((EFI_D_WARN, "Invalid parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ArgumentBuffer == NULL) {
+ Data = 0xFF;
+ } else {
+ if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Data = *ArgumentBuffer;
+ }
+ ///
+ /// Clear any pending the APM SMI
+ ///
+ Status = SmmClear ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return SmmTrigger (Data);
+}
+
+/**
+ This routine clears an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmmClear ();
+}
+
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.h b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.h
new file mode 100644
index 0000000..1cc28b3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/Pei/SmmControlDriver.h
@@ -0,0 +1,95 @@
+/** @file
+ Header file for SMM Control 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 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 _EFI_PEI_SMM_CONTROL_DRIVER_H_
+#define _EFI_PEI_SMM_CONTROL_DRIVER_H_
+
+#include "EdkIIGluePeim.h"
+#include "Pci22.h"
+
+//
+// Driver private data
+//
+#include EFI_PPI_DEFINITION (SmmControl)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+
+//
+// Prototypes
+//
+
+/**
+ This is the constructor for the SMM Control ppi
+
+ @param[in] FfsHeader FfsHeader.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Ppi
+**/
+EFI_STATUS
+EFIAPI
+SmmControlPeiDriverEntryInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+/**
+ This routine generates an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+PeiActivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ This routine clears an SMI
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] This The EFI SMM Control ppi instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+PeiDeactivate (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SMM_CONTROL_PPI *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif
new file mode 100644
index 0000000..f683a24
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "SmmControl"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\SmmControl\RuntimeDxe"
+ RefName = "SmmControl"
+[files]
+"SmmControl.sdl"
+"SmmControl.mak"
+"SmmControlDriver.h"
+"SmmControlDriver.c"
+"SmmControl.dxs"
+"SmmControl.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs
new file mode 100644
index 0000000..994ee96
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.dxs
@@ -0,0 +1,36 @@
+/** @file
+ Dispatch dependency expression file for the SmmControl driver.
+
+@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
+
+**/
+
+//
+// Same for R8 and R9 codebase
+//
+#include "AutoGen.h"
+#include "DxeDepex.h"
+
+//
+// For R8 only
+//
+#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/SmmControl/RuntimeDxe/SmmControl.inf b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.inf
new file mode 100644
index 0000000..5d9d647
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.inf
@@ -0,0 +1,85 @@
+## @file
+# Component description file for SmmControl module
+#
+#@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
+#
+
+[defines]
+BASE_NAME = SmmControl
+FILE_GUID = A0BAD9F7-AB78-491b-B583-C52B7F84B9E0
+COMPONENT_TYPE = RT_DRIVER
+
+[sources.common]
+ SmmControlDriver.h
+ SmmControlDriver.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.c
+
+[includes.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
+#
+# 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/Library/Dxe/Include
+ $(EDK_SOURCE)/Foundation/Library/EdkIIGlueLib/Include
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueEdkDxeRuntimeDriverLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = SmmControl.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=SmmControlDriverEntryInit
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=SmmControlVirtualAddressChangeEvent
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ -D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+ -D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak
new file mode 100644
index 0000000..802fa7f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.mak
@@ -0,0 +1,105 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/SmmControl/SmmControl.mak 2 2/24/12 2:24a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:24a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SmmControl/SmmControl.mak $
+#
+# 2 2/24/12 2:24a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:21a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+#---------------------------------------------------------------------------
+# Create SmmControl Driver
+#---------------------------------------------------------------------------
+EDK : SmmControl
+SmmControl : $(BUILD_DIR)\SmmControl.mak SmmControlBin
+
+
+$(BUILD_DIR)\SmmControl.mak : $(SmmControl_DIR)\$(@B).cif $(SmmControl_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SmmControl_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SmmControl_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+SmmControl_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=SmmControlDriverEntryInit"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+SmmControl_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(SmmControlLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+SmmControlBin: $(SmmControl_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmControl.mak all \
+ "MY_INCLUDES=$(SmmControl_INCLUDES)" \
+ "MY_DEFINES=$(SmmControl_DEFINES)" \
+ GUID=A0BAD9F7-AB78-491b-B583-C52B7F84B9E0\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(SmmControl_DIR)\SmmControl.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/SmmControl/RuntimeDxe/SmmControl.sdl b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.sdl
new file mode 100644
index 0000000..9809183
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControl.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/SmmControl/SmmControl.sdl 1 2/08/12 9:21a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:21a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/SmmControl/SmmControl.sdl $
+#
+# 1 2/08/12 9:21a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "SmmControl_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmmControl support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SMM_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "SmmControl_DIR"
+End
+
+MODULE
+ File = "SmmControl.mak"
+ Help = "Includes SmmControl to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmControl.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/SmmControl/RuntimeDxe/SmmControlDriver.c b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.c
new file mode 100644
index 0000000..1220cf2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.c
@@ -0,0 +1,478 @@
+/** @file
+ This is the driver that publishes the SMM Control Protocol.
+
+@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 "SmmControlDriver.h"
+
+STATIC SMM_CONTROL_PRIVATE_DATA mSmmControl;
+UINT32 mPmBase;
+UINT32 mGpioBase;
+
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context.
+
+ @retval None.
+**/
+VOID
+EFIAPI
+SmmControlVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Trigger));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.Clear));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSmmControl.SmmControl.GetRegisterInfo));
+}
+
+/**
+ This is the constructor for the SMM Control protocol
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "SMM Control Protocol not supported due to no proper PCH LPC found!\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+
+ DEBUG ((EFI_D_INFO, "SmmControlDriverEntryInit() Start\n"));
+
+ ///
+ /// Get the Power Management I/O space base address. We assume that
+ /// this base address has already been programmed if this driver is
+ /// being run.
+ ///
+ mGpioBase = MmioRead32 (
+ 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 ;
+ ASSERT (mGpioBase != 0);
+
+ mPmBase = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ Status = EFI_SUCCESS;
+ if (mPmBase != 0) {
+ ///
+ /// Install the instance of the protocol
+ ///
+ mSmmControl.Signature = SMM_CONTROL_PRIVATE_DATA_SIGNATURE;
+ mSmmControl.Handle = ImageHandle;
+
+ mSmmControl.SmmControl.Trigger = Activate;
+ mSmmControl.SmmControl.Clear = Deactivate;
+ mSmmControl.SmmControl.GetRegisterInfo = GetRegisterInfo;
+ mSmmControl.SmmControl.MinimumTriggerPeriod = 0;
+
+ ///
+ /// Install our protocol interfaces on the device's handle
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmmControl.Handle,
+ &gEfiSmmControlProtocolGuid,
+ &mSmmControl.SmmControl,
+ NULL
+ );
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Disable any PCH SMIs that, for whatever reason, are asserted after the boot.
+ ///
+ DisablePendingSmis ();
+
+ DEBUG ((EFI_D_INFO, "SmmControlDriverEntryInit() End\n"));
+
+ return Status;
+}
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ IN UINT8 Data
+ )
+{
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ ///
+ /// Enable the APMC SMI
+ ///
+ OutputPort = mPmBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= (B_PCH_SMI_EN_APMC | B_PCH_SMI_EN_GBL_SMI);
+ DEBUG (
+ (EFI_D_VERBOSE,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ OutputPort = R_PCH_APM_CNT;
+ OutputData = Data;
+
+ ///
+ /// Generate the APMC SMI
+ ///
+ IoWrite8 (
+ (UINTN) OutputPort,
+ (UINT8) (OutputData)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Clear the SMI status
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINT32 OutputData;
+ UINT32 OutputPort;
+
+ Status = EFI_SUCCESS;
+
+ ///
+ /// Clear the Power Button Override Status Bit, it gates EOS from being set.
+ ///
+ OutputPort = mPmBase + R_PCH_ACPI_PM1_STS;
+ OutputData = B_PCH_ACPI_PM1_STS_PRBTNOR;
+ DEBUG (
+ (EFI_D_VERBOSE,
+ "The PM1 Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite16 (
+ (UINTN) OutputPort,
+ (UINT16) (OutputData)
+ );
+
+ ///
+ /// Clear the APM SMI Status Bit
+ ///
+ OutputPort = mPmBase + R_PCH_SMI_STS;
+ OutputData = B_PCH_SMI_STS_APM;
+ DEBUG (
+ (EFI_D_VERBOSE,
+ "The SMI Status Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// Set the EOS Bit
+ ///
+ OutputPort = mPmBase + R_PCH_SMI_EN;
+ OutputData = IoRead32 ((UINTN) OutputPort);
+ OutputData |= B_PCH_SMI_EN_EOS;
+ DEBUG (
+ (EFI_D_VERBOSE,
+ "The SMI Control Port at address %x will be written to %x.\n",
+ OutputPort,
+ OutputData)
+ );
+ IoWrite32 (
+ (UINTN) OutputPort,
+ (UINT32) (OutputData)
+ );
+
+ ///
+ /// There is no need to read EOS back and check if it is set.
+ /// This can lead to a reading of zero if an SMI occurs right after the SMI_EN port read
+ /// but before the data is returned to the CPU.
+ /// SMM Dispatcher should make sure that EOS is set after all SMI sources are processed.
+ ///
+ return Status;
+}
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN EFI_SMM_CONTROL_PROTOCOL * This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data;
+
+ if (Periodic) {
+ DEBUG ((EFI_D_WARN, "Invalid parameter\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ArgumentBuffer == NULL) {
+ Data = 0xFF;
+ } else {
+ if (ArgumentBufferSize == NULL || *ArgumentBufferSize != 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Data = *ArgumentBuffer;
+ }
+ ///
+ /// Clear any pending the APM SMI
+ ///
+ Status = SmmClear ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return SmmTrigger (Data);
+}
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN EFI_SMM_CONTROL_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ )
+{
+ if (Periodic) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SmmClear ();
+}
+
+/**
+ This routine gets SMM control register information
+
+ @param[in] This The SMM Control protocol instance
+ @param[in, out] SmiRegister Output parameter: the SMI control register information is returned
+
+ @retval EFI_INVALID_PARAMETER Parameter SmiRegister is NULL
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+GetRegisterInfo (
+ IN EFI_SMM_CONTROL_PROTOCOL *This,
+ IN OUT EFI_SMM_CONTROL_REGISTER *SmiRegister
+ )
+{
+ if (SmiRegister == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SmiRegister->SmiTriggerRegister = R_PCH_APM_CNT;
+ SmiRegister->SmiDataRegister = R_PCH_APM_STS;
+ return EFI_SUCCESS;
+}
+
+/**
+ Disable all pending SMIs
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ )
+{
+ UINT32 Data;
+ UINT32 Port;
+ BOOLEAN SciEn;
+ PCH_SERIES PchSeries;
+
+ ///
+ /// Determine whether an ACPI OS is present (via the SCI_EN bit)
+ ///
+ Port = mPmBase + R_PCH_ACPI_PM1_CNT;
+ Data = IoRead16 ((UINTN) Port);
+ SciEn = (BOOLEAN) ((Data & B_PCH_ACPI_PM1_CNT_SCI_EN) == B_PCH_ACPI_PM1_CNT_SCI_EN);
+ PchSeries = GetPchSeries();
+
+ if (!SciEn) {
+ ///
+ /// Clear any SMIs that double as SCIs (when SCI_EN==0)
+ ///
+ Port = mPmBase + R_PCH_ACPI_PM1_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mPmBase + R_PCH_ACPI_PM1_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mPmBase + R_PCH_ACPI_PM1_CNT;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ if (PchSeries == PchLp) {
+ Port = mPmBase + R_PCH_ACPI_GPE0_STS_127_96;
+ Data = 0xFFFBFFFF;
+ } else if (PchSeries == PchH) {
+ Port = mPmBase + R_PCH_ACPI_GPE0a_STS;
+ Data = 0xFFFFFFFF;
+ }
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ if (PchSeries == PchLp) {
+ Port = mPmBase + R_PCH_ACPI_GPE0_EN_127_96;
+ Data = 0x00040000;
+ } else if (PchSeries == PchH) {
+ Port = mPmBase + R_PCH_ACPI_GPE0a_EN;
+ Data = 0x00000000;
+ }
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ if (PchSeries == PchH) {
+ Port = mPmBase + R_PCH_ACPI_GPE0b_STS;
+ Data = IoRead32 (Port);
+ Data |= 0x1F;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ Port = mPmBase + R_PCH_ACPI_GPE0b_EN;
+ Data = IoRead32 (Port);
+ Data &= 0xFFFFFFE0;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+ }
+ }
+ ///
+ /// Clear and disable all SMIs that are unaffected by SCI_EN
+ ///
+ if (PchSeries == PchH) {
+ Port = mPmBase + R_PCH_LPTH_ALT_GP_SMI_EN;
+ Data = 0x0000;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+
+ Port = mPmBase + R_PCH_LPTH_ALT_GP_SMI_STS;
+ Data = 0xFFFF;
+ IoWrite16 ((UINTN) Port, (UINT16) (Data));
+ } else if (PchSeries == PchLp) {
+ Port = mGpioBase + R_PCH_LPTLP_ALT_GP_SMI_EN;
+ Data = IoRead32 ((UINTN) Port) & 0x0000;
+ IoWrite32 ((UINTN) Port, Data);
+
+ Port = mGpioBase + R_PCH_LPTLP_ALT_GP_SMI_STS;
+ Data = IoRead32 ((UINTN) Port) | 0xFFFF;
+ IoWrite32 ((UINTN) Port, Data);
+ }
+
+ Port = mPmBase + R_PCH_DEVACT_STS;
+ Data = 0xFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ Port = mPmBase + R_PCH_SMI_STS;
+ Data = 0xFFFFFFFF;
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+ ///
+ /// (Make sure to write this register last -- EOS re-enables SMIs for the PCH)
+ ///
+ Port = mPmBase + R_PCH_SMI_EN;
+ Data = IoRead32 ((UINTN) Port);
+ ///
+ /// clear all bits except those tied to SCI_EN
+ ///
+ Data &= B_PCH_SMI_EN_BIOS_RLS;
+ ///
+ /// enable SMIs and specifically enable writes to APM_CNT.
+ ///
+ Data |= B_PCH_SMI_EN_GBL_SMI | B_PCH_SMI_EN_APMC;
+ ///
+ /// NOTE: Default value of EOS is set in PCH, it will be automatically cleared Once the PCH asserts SMI# low,
+ /// we don't need to do anything to clear it
+ ///
+ IoWrite32 ((UINTN) Port, (UINT32) (Data));
+
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.h b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.h
new file mode 100644
index 0000000..79effdb
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/SmmControl/RuntimeDxe/SmmControlDriver.h
@@ -0,0 +1,164 @@
+/** @file
+ Header file for SMM Control 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 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 _SMM_CONTROL_DRIVER_H_
+#define _SMM_CONTROL_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 "Pci22.h"
+
+//
+// Driver private data
+//
+#include EFI_PROTOCOL_DEFINITION (SmmControl)
+#include "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+
+#define SMM_CONTROL_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('i', '4', 's', 'c')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_CONTROL_PROTOCOL SmmControl;
+} SMM_CONTROL_PRIVATE_DATA;
+
+#define SMM_CONTROL_PRIVATE_DATA_FROM_THIS(a) CR (a, SMM_CONTROL_PRIVATE_DATA, SmmControl, SMM_CONTROL_DEV_SIGNATURE)
+
+//
+// Prototypes
+//
+
+/**
+ This is the constructor for the SMM Control protocol
+
+ @param[in] ImageHandle Handle for the image of this driver
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_STATUS Results of the installation of the SMM Control Protocol
+**/
+EFI_STATUS
+EFIAPI
+SmmControlDriverEntryInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Trigger the software SMI
+
+ @param[in] Data The value to be set on the software SMI data port
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+SmmTrigger (
+ UINT8 Data
+ );
+
+/**
+ Clear the SMI status
+
+ @param[in] None
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_DEVICE_ERROR Something error occurred
+**/
+EFI_STATUS
+EFIAPI
+SmmClear (
+ VOID
+ );
+
+/**
+ This routine generates an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in, out] ArgumentBuffer The buffer of argument
+ @param[in, out] ArgumentBufferSize The size of the argument buffer
+ @param[in] Periodic Periodic or not
+ @param[in] ActivationInterval Interval of periodic SMI
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Activate (
+ IN EFI_SMM_CONTROL_PROTOCOL * This,
+ IN OUT INT8 *ArgumentBuffer OPTIONAL,
+ IN OUT UINTN *ArgumentBufferSize OPTIONAL,
+ IN BOOLEAN Periodic OPTIONAL,
+ IN UINTN ActivationInterval OPTIONAL
+ );
+
+/**
+ This routine clears an SMI
+
+ @param[in] This The EFI SMM Control protocol instance
+ @param[in] Periodic Periodic or not
+
+ @retval EFI Status Describing the result of the operation
+ @retval EFI_INVALID_PARAMETER Some parameter value passed is not supported
+**/
+EFI_STATUS
+EFIAPI
+Deactivate (
+ IN EFI_SMM_CONTROL_PROTOCOL *This,
+ IN BOOLEAN Periodic OPTIONAL
+ );
+
+/**
+ This routine gets SMM control register information
+
+ @param[in] This The SMM Control protocol instance
+ @param[in, out] SmiRegister Output parameter: the SMI control register information is returned
+
+ @retval EFI_INVALID_PARAMETER Parameter SmiRegister is NULL
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+GetRegisterInfo (
+ IN EFI_SMM_CONTROL_PROTOCOL *This,
+ IN OUT EFI_SMM_CONTROL_REGISTER *SmiRegister
+ );
+
+/**
+ Disable all pending SMIs
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisablePendingSmis (
+ VOID
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.cif
new file mode 100644
index 0000000..5b922d8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PchSpiCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Spi\Common"
+ RefName = "PchSpiCommonLib"
+[files]
+"PchSpiCommonLib.sdl"
+"PchSpiCommonLib.mak"
+"SpiCommon.c"
+"SpiCommon.h"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.mak
new file mode 100644
index 0000000..b781d72
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.mak
@@ -0,0 +1,125 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSpiCommonLib/PchSpiCommonLib.mak 1 2/08/12 9:22a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:22a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiCommonLib/PchSpiCommonLib.mak $
+#
+# 1 2/08/12 9:22a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+all : PchSpiCommonLib
+
+PchSpiCommonLib : PchSpiCommonDxeLib PchSpiCommonSmmLib PchSpiCommonPeiLib
+
+$(PchSpiCommonSmmLib_LIB) : PchSpiCommonSmmLib
+$(PchSpiCommonDxeLib_LIB) : PchSpiCommonDxeLib
+$(PchSpiCommonPeiLib_LIB) : PchSpiCommonPeiLib
+
+PchSpiCommonSmmLib : $(BUILD_DIR)\PchSpiCommonLib.mak PchSpiCommonLibSmmBin
+
+PchSpiCommonDxeLib : $(BUILD_DIR)\PchSpiCommonLib.mak PchSpiCommonLibDxeBin
+
+PchSpiCommonPeiLib : $(BUILD_DIR)\PchSpiCommonLib.mak PchSpiCommonLibPeiBin
+
+$(BUILD_DIR)\PchSpiCommonLib.mak : $(PchSpiCommonLib_DIR)\$(@B).cif $(PchSpiCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSpiCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSpiCommonLib_INCLUDES=\
+ $(EDK_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+
+PchSpiCommonLibSmm_INCLUDES=\
+ $(PchSpiCommonLib_INCLUDES) $(PCH_SPI_INCLUDES)
+
+PchSpiCommonLibDxe_INCLUDES=\
+ $(PchSpiCommonLib_INCLUDES) $(PCH_SPI_INCLUDES)
+
+PchSpiCommonLibPeim_INCLUDES=\
+ $(PchSpiCommonLib_INCLUDES) $(PCH_SPI_INCLUDES)
+
+PchSpiCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+PchSpiCommonLibPeim_DEFINES = \
+ $(PchSpiCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+PchSpiCommonLibDxe_DEFINES = \
+ $(PchSpiCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+PchSpiCommonLibSmm_DEFINES = \
+ $(PchSpiCommonLibDxe_DEFINES)\
+
+PchSpiCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSpiCommonLib.mak all\
+ "MY_INCLUDES=$(PchSpiCommonLibDxe_INCLUDES)" \
+ "CFLAGS=$(PchSpiCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(PchSpiCommonDxeLib_LIB)
+
+PchSpiCommonLibSmmBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\PchSpiCommonLib.mak all\
+ "MY_INCLUDES=$(PchSpiCommonLibSmm_INCLUDES)" \
+ "CFLAGS=$(PchSpiCommonLibSmm_DEFINES)"\
+ TYPE=LIBRARY \
+ BUILD_DIR=$(BUILD_DIR)\Smm\
+ LIBRARY_NAME=$(PchSpiCommonSmmLib_LIB)
+
+PchSpiCommonLibPeiBin :
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\PchSpiCommonLib.mak all\
+ "MY_INCLUDES=$(PchSpiCommonLibPeim_INCLUDES)" \
+ "CFLAGS=$(PchSpiCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(PchSpiCommonPeiLib_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/Spi/Common/PchSpiCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.sdl
new file mode 100644
index 0000000..33582be
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Common/PchSpiCommonLib.sdl
@@ -0,0 +1,92 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSpiCommonLib/PchSpiCommonLib.sdl 1 2/08/12 9:22a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:22a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiCommonLib/PchSpiCommonLib.sdl $
+#
+# 1 2/08/12 9:22a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSpiCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSpiCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSpiCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes PchSpiCommonLib.mak to Project"
+ File = "PchSpiCommonLib.mak"
+End
+
+ELINK
+ Name = "PchSpiCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiCommonDxeLib.lib"
+ Parent = "PchSpiCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSpiCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiCommonPeiLib.lib"
+ Parent = "PchSpiCommonPeiLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PchSpiCommonSmmLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiCommonSmmLib.lib"
+ Parent = "PchSpiCommonSmmLib_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/Spi/Common/SpiCommon.c b/ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.c
new file mode 100644
index 0000000..2797bd9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.c
@@ -0,0 +1,1425 @@
+/** @file
+ PCH SPI Common Driver implements the SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2008 - 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 "PchSpi.h"
+
+/**
+ Initialize an SPI protocol instance.
+ The function will assert in debug if PCH RCBA has not been initialized
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ SPI_INSTANCE *SpiInstance
+ )
+{
+ ///
+ /// Check if the current PCH is known and supported by this code
+ ///
+ if (!IsPchSupported ()) {
+ DEBUG ((EFI_D_ERROR, "PCH SPI Protocol not supported due to no proper PCH LPC found!\n"));
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ SpiInstance->Signature = PCH_SPI_PRIVATE_DATA_SIGNATURE;
+ SpiInstance->Handle = NULL;
+ SpiInstance->SpiProtocol.ReadId = SpiProtocolReadId;
+ SpiInstance->SpiProtocol.Init = SpiProtocolInit;
+ SpiInstance->SpiProtocol.Execute = SpiProtocolExecute;
+
+ ///
+ /// Sanity check to ensure PCH RCBA initialization has occurred previously.
+ ///
+ SpiInstance->PchRootComplexBar = PCH_RCRB_BASE;
+ ASSERT (SpiInstance->PchRootComplexBar != 0);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ JEDEC Read IDs from SPI flash part, this function will return 1-byte Vendor ID and 2-byte Device ID
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] Address This value is for determines the command is sent to SPI Component 1 or 2
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Read Jedec Id completed.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @exception EFI_UNSUPPORTED This function is unsupport after SpiProtocolInit is called
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN Address,
+ IN OUT UINT8 *Buffer
+ )
+{
+ EFI_STATUS Status;
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchRootComplexBar;
+ UINT16 OpcodeType;
+ UINT8 Code;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ if (SpiInstance->SpiIdTable[0].VendorId != 0) {
+ DEBUG ((EFI_D_ERROR, "This function is unsupport after SpiProtocolInit is called, please use SpiProtocolExecute to get Jedec ID!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+ SpiInstance->SpiInitTable.SpiCmdConfig[0].Operation = EnumSpiOperationJedecId;
+ SpiInstance->SpiInitTable.SpiCmdConfig[0].Frequency = EnumSpiCycle50MHz;
+ OpcodeType = (UINT16) (V_PCH_SPI_OPTYPE_RDNOADDR);
+ Code = PCH_SPI_COMMAND_READ_ID;
+
+ ///
+ /// Set Opcode Menu Configuration registers.
+ /// Need to be done before sending any SPI command
+ ///
+ MmioWrite8 (PchRootComplexBar + R_PCH_SPI_OPMENU, Code);
+ MmioRead8 (PchRootComplexBar + R_PCH_SPI_OPMENU);
+ ///
+ /// Set Opcode Type Configuration registers.
+ ///
+ MmioWrite16 (PchRootComplexBar + R_PCH_SPI_OPTYPE, OpcodeType);
+ MmioRead16 (PchRootComplexBar + R_PCH_SPI_OPTYPE);
+
+ Status = SpiProtocolExecute (
+ This,
+ 0,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ Address,
+ 3,
+ Buffer,
+ EnumSpiRegionAll
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Get Descriptor values from the Descriptor Region.
+
+ @param[in] This A pointer to "EFI_SPI_PROTOCOL" for issuing commands
+
+ @retval None
+**/
+VOID
+EFIAPI
+GetDescriptorValues (
+ IN EFI_SPI_PROTOCOL *This
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchRootComplexBar;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+ ///
+ /// Select to Flash Map 0 Register to get the number of flash Component
+ ///
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)),
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_FSDM | R_PCH_SPI_FDBAR_FLASH_MAP0)
+ );
+
+ ///
+ /// Copy Zero based Number Of Components
+ ///
+ SpiInstance->SpiDescriptor.NumberComponents = (UINT8) ((MmioRead16 (PchRootComplexBar + R_PCH_SPI_FDOD) & B_PCH_SPI_FDBAR_NC) >> N_PCH_SPI_FDBAR_NC);
+
+ ///
+ /// Select to Flash Components Register to get the Component 1 Density
+ ///
+ MmioAndThenOr32 (
+ PchRootComplexBar + R_PCH_SPI_FDOC,
+ (UINT32) (~(B_PCH_SPI_FDOC_FDSS_MASK | B_PCH_SPI_FDOC_FDSI_MASK)),
+ (UINT32) (V_PCH_SPI_FDOC_FDSS_COMP | R_PCH_SPI_FCBA_FLCOMP)
+ );
+
+ ///
+ /// Copy Component 1 Density
+ ///
+ SpiInstance->SpiDescriptor.Comp1Density = (UINT8) MmioRead32 (PchRootComplexBar + R_PCH_SPI_FDOD) & B_PCH_SPI_FLCOMP_COMP1_MASK;
+}
+
+/**
+ Get VSCC values from the Descriptor Region (VSCC Table).
+
+ @param[in] This A pointer to "EFI_SPI_PROTOCOL" for issuing commands
+ @param[in] ReadDataCmdOpcodeIndex The index of the opcode - "PCH_SPI_COMMAND_READ_DATA"
+ @param[in, out] Vscc0Value VSCC0 (Vendor Specific Component Capabilities) Value
+ @param[in, out] Vscc1Value VSCC1 (Vendor Specific Component Capabilities) Value
+
+ @retval EFI_SUCCESS Found the VSCC values on Descriptor Region
+ @retval EFI_NOT_FOUND Couldn't find the VSCC values on Descriptor Region
+ @exception EFI_UNSUPPORTED ReadDataCmdOpcodeIndex is out of range
+**/
+EFI_STATUS
+EFIAPI
+GetDescriptorVsccValues (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 ReadDataCmdOpcodeIndex,
+ IN OUT UINT32 *Vscc0Value,
+ IN OUT UINT32 *Vscc1Value
+ )
+{
+ UINT32 SpiDescFlashUpperMap1;
+ UINT32 VsccTableBaseAddr;
+ UINT32 VsccTableLength;
+ UINT32 JedecIdRegIndex;
+ EFI_STATUS Status;
+ UINT32 FlashDescriptor;
+ SPI_INSTANCE *SpiInstance;
+ BOOLEAN MatchedVtbEntryFound;
+ UINT8 SpiIndex;
+ UINT32 Data32;
+ Data32 = 0;
+
+ if (ReadDataCmdOpcodeIndex >= SPI_NUM_OPCODE) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ Status = SpiProtocolExecute (
+ This,
+ ReadDataCmdOpcodeIndex,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ (UINTN) R_PCH_SPI_FLASH_UMAP1,
+ sizeof (SpiDescFlashUpperMap1),
+ (UINT8 *) &SpiDescFlashUpperMap1,
+ EnumSpiRegionDescriptor
+ );
+ if ((EFI_ERROR (Status)) || (SpiDescFlashUpperMap1 == 0xFFFFFFFF)) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// B_PCH_SPI_FLASH_UMAP1_VTBA represents address bits [11:4]
+ ///
+ VsccTableBaseAddr = ((SpiDescFlashUpperMap1 & B_PCH_SPI_FLASH_UMAP1_VTBA) << 4);
+ ///
+ /// Multiplied by 4? B_PCH_SPI_FDBAR_VTL is the 1-based number of DWORDs.
+ ///
+ VsccTableLength = (((SpiDescFlashUpperMap1 & B_PCH_SPI_FLASH_UMAP1_VTL) >> 8) << 2);
+ if (VsccTableLength < SIZE_OF_SPI_VTBA_ENTRY) {
+ ///
+ /// Non-existent or invalid Vscc Table
+ ///
+ return EFI_NOT_FOUND;
+ }
+
+ for (SpiIndex = 0; SpiIndex <= SpiInstance->SpiDescriptor.NumberComponents; SpiIndex++) {
+ JedecIdRegIndex = 0;
+ MatchedVtbEntryFound = FALSE;
+ while (JedecIdRegIndex <= (VsccTableLength - SIZE_OF_SPI_VTBA_ENTRY)) {
+ Status = SpiProtocolExecute (
+ This,
+ ReadDataCmdOpcodeIndex,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ (UINTN) (VsccTableBaseAddr + JedecIdRegIndex),
+ sizeof (UINT32),
+ (UINT8 *) &FlashDescriptor,
+ EnumSpiRegionDescriptor
+ );
+
+ if ((EFI_ERROR (Status)) || (FlashDescriptor == 0xFFFFFFFF)) {
+ break;
+ }
+
+ if (((FlashDescriptor & B_PCH_SPI_VTBA_JID0_VID) != SpiInstance->SpiIdTable[SpiIndex].VendorId) ||
+ (((FlashDescriptor & B_PCH_SPI_VTBA_JID0_DID0) >> N_PCH_SPI_VTBA_JID0_DID0)
+ != SpiInstance->SpiIdTable[SpiIndex].DeviceId0) ||
+ (((FlashDescriptor & B_PCH_SPI_VTBA_JID0_DID1) >> N_PCH_SPI_VTBA_JID0_DID1)
+ != SpiInstance->SpiIdTable[SpiIndex].DeviceId1)) {
+ JedecIdRegIndex += SIZE_OF_SPI_VTBA_ENTRY;
+ } else {
+ MatchedVtbEntryFound = TRUE;
+ break;
+ }
+ }
+
+ if (!MatchedVtbEntryFound) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = SpiProtocolExecute (
+ This,
+ ReadDataCmdOpcodeIndex,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ (UINTN) (VsccTableBaseAddr + JedecIdRegIndex + R_PCH_SPI_VTBA_VSCC0),
+ sizeof (UINT32),
+ (UINT8 *) &Data32,
+ EnumSpiRegionDescriptor
+ );
+ if ((EFI_ERROR (Status)) || (Data32 == 0xFFFFFFFF)) {
+ return EFI_NOT_FOUND;
+ }
+ ///
+ /// Copy correct VSCCn value
+ ///
+ if (SpiIndex == 0) {
+ *Vscc0Value = Data32;
+ } else {
+ *Vscc1Value = Data32;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Discover if the flash parts supports 4KB Block/Sector erase size.
+
+ @param[in] This A pointer to "EFI_SPI_PROTOCOL" for issuing commands
+
+ @retval EFI_SUCCESS The flash part supports 4KB erase size.
+ @exception EFI_UNSUPPORTED The flash part does not support 4KB erase size.
+**/
+EFI_STATUS
+EFIAPI
+SpiDiscoveryParameters (
+ IN EFI_SPI_PROTOCOL *This
+ )
+{
+ UINT16 ParameterTableIndex;
+ UINT32 Data32;
+ SPI_INSTANCE *SpiInstance;
+ UINT8 SpiIndex;
+ UINTN PchRootComplexBar;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+ ///
+ /// Check if valid SFDP table is present for SPI0
+ ///
+ Data32 = MmioRead32 ((UINTN) (PchRootComplexBar + R_PCH_SPI_VSCC0)) & B_PCH_SPI_VSCC0_CPPTV;
+ if (Data32 == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+
+ ///
+ /// Check if valid SFDP table is present for SPI1
+ ///
+ if (SpiInstance->SpiDescriptor.NumberComponents) {
+ Data32 = MmioRead32 ((UINTN) (PchRootComplexBar + R_PCH_SPI_VSCC1)) & B_PCH_SPI_VSCC1_CPPTV;
+ if (Data32 == 0) {
+ ///
+ /// Program VSCCn values from Flash Descriptor or internal BIOS table
+ /// if both parts do not support SFDP
+ ///
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ for (SpiIndex = 0; SpiIndex <= SpiInstance->SpiDescriptor.NumberComponents; SpiIndex++) {
+ ///
+ /// Read Block/Sector Erase Size in 1st dword in the Flash Parameter Table.
+ ///
+ ParameterTableIndex = (SpiIndex << N_PCH_SPI_PINTX_SPT) | (V_PCH_SPI_PINTX_HORD_DATA << N_PCH_SPI_PINTX_HORD);
+ MmioWrite32 (PchRootComplexBar + R_PCH_SPI_PINTX, ParameterTableIndex);
+ Data32 = MmioRead32 (PchRootComplexBar + R_PCH_SPI_PTDATA) & B_PCH_SPI_VSCC0_BSES_MASK;
+
+ ///
+ /// Program VSCCn.EO from Flash Descriptor or internal BIOS table
+ /// if erase size other than 4KB.
+ ///
+ if (Data32 != V_PCH_SPI_VSCC0_BSES_4K) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initialize the host controller to execute SPI command.
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] InitData Initialization data to be programmed into the SPI host controller.
+
+ @retval EFI_SUCCESS Initialization completed.
+ @retval EFI_ACCESS_DENIED The SPI static configuration interface has been locked-down.
+ @retval EFI_INVALID_PARAMETER Bad input parameters.
+ @exception EFI_UNSUPPORTED Can't get Descriptor mode VSCC values
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolInit (
+ IN EFI_SPI_PROTOCOL *This,
+ IN SPI_INIT_DATA *InitData
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINT16 OpcodeType;
+ SPI_INSTANCE *SpiInstance;
+ SPI_SPECIAL_OPCODE_ENTRY *SpecialOpcodeEntry;
+ UINT32 Vscc0Value;
+ UINT32 Vscc1Value;
+ UINTN PchRootComplexBar;
+ UINT8 UnlockCmdOpcodeIndex;
+ UINT8 ReadDataCmdOpcodeIndex;
+ UINT8 JedecIdCmdOpcodeIndex;
+ UINT8 Code;
+ UINT8 FlashPartId[3];
+ UINT32 Data32;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+ Vscc0Value = 0;
+ Vscc1Value = 0;
+
+ if (InitData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Check if the SPI interface has been locked-down.
+ ///
+ if ((MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFS) & B_PCH_SPI_HSFS_FLOCKDN) != 0) {
+ ASSERT_EFI_ERROR (EFI_ACCESS_DENIED);
+ return EFI_ACCESS_DENIED;
+ }
+ ///
+ /// Copy Flash Descriptor Values into SPI driver Private data structure
+ ///
+ SpiInstance->DescriptorMode = PchIsSpiDescriptorMode (PchRootComplexBar);
+ if (SpiInstance->DescriptorMode == TRUE) {
+ GetDescriptorValues (This);
+ }
+ ///
+ /// Clear all the status bits for hardware regs.
+ ///
+ MmioOr16 (
+ (UINTN) (PchRootComplexBar + R_PCH_SPI_HSFS),
+ (UINT16) ((B_PCH_SPI_HSFS_AEL | B_PCH_SPI_HSFS_FCERR | B_PCH_SPI_HSFS_FDONE))
+ );
+ MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFS);
+
+ ///
+ /// Clear all the status bits for software regs.
+ ///
+ MmioOr8 (
+ (UINTN) (PchRootComplexBar + R_PCH_SPI_SSFS),
+ (UINT8) ((B_PCH_SPI_SSFS_FCERR | B_PCH_SPI_SSFS_CDS))
+ );
+ MmioRead8 (PchRootComplexBar + R_PCH_SPI_SSFS);
+
+ ReadDataCmdOpcodeIndex = SPI_NUM_OPCODE;
+ UnlockCmdOpcodeIndex = SPI_NUM_OPCODE;
+ JedecIdCmdOpcodeIndex = SPI_NUM_OPCODE;
+ ///
+ /// Set Opcode Type Configuration registers.
+ /// Need to be done before sending any SPI command
+ ///
+ for (Index = 0, OpcodeType = 0; Index < SPI_NUM_OPCODE; Index++) {
+ ///
+ /// Copy Operation and Frequency into SPI driver Private data structure
+ ///
+ SpiInstance->SpiInitTable.SpiCmdConfig[Index].Operation = InitData->SpiCmdConfig[Index].Operation;
+ SpiInstance->SpiInitTable.SpiCmdConfig[Index].Frequency = InitData->SpiCmdConfig[Index].Frequency;
+
+ switch (SpiInstance->SpiInitTable.SpiCmdConfig[Index].Operation) {
+ case EnumSpiOperationReadData:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_READ_DATA;
+ ReadDataCmdOpcodeIndex = Index;
+ break;
+
+ case EnumSpiOperationFastRead:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_FAST_READ;
+ ReadDataCmdOpcodeIndex = Index;
+ break;
+
+ case EnumSpiOperationDualOutputFastRead:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_DUAL_FAST_READ;
+ ReadDataCmdOpcodeIndex = Index;
+ break;
+
+ case EnumSpiOperationDiscoveryParameters:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_DISCOVERY_PARAMETERS;
+ break;
+
+ case EnumSpiOperationProgramData_1_Byte:
+ case EnumSpiOperationProgramData_64_Byte:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_PROGRAM_BYTE;
+ break;
+
+ case EnumSpiOperationErase_256_Byte:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_256B_ERASE;
+ break;
+
+ case EnumSpiOperationErase_4K_Byte:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_4KB_ERASE;
+ break;
+
+ case EnumSpiOperationErase_64K_Byte:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_64KB_ERASE;
+ break;
+
+ case EnumSpiOperationWriteStatus:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_WRITE_STATUS;
+ UnlockCmdOpcodeIndex = Index;
+ break;
+
+ case EnumSpiOperationWriteDisable:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_WRITE_DISABLE;
+ break;
+
+ case EnumSpiOperationWriteEnable:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_WRITE_ENABLE;
+ break;
+
+ case EnumSpiOperationEnableWriteStatus:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_ENABLE_WRITE_STATUS;
+ break;
+
+ case EnumSpiOperationFullChipErase:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_WRNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_FULL_CHIP_ERASE;
+ break;
+
+ case EnumSpiOperationReadStatus:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_READ_STATUS;
+ break;
+
+ case EnumSpiOperationJedecId:
+ OpcodeType |= (UINT16) (V_PCH_SPI_OPTYPE_RDNOADDR << (Index * 2));
+ Code = PCH_SPI_COMMAND_READ_ID;
+ JedecIdCmdOpcodeIndex = Index;
+ break;
+
+ case EnumSpiOperationErase_8K_Byte:
+ case EnumSpiOperationOther:
+ Code = 0;
+ break;
+
+ default:
+ Code = 0;
+ ASSERT (FALSE);
+ break;
+ }
+ ///
+ /// Overrided Opcode Type and Menu Configuration registers per SpecialOpcodeEntry
+ ///
+ if (InitData->SpecialOpcodeEntry != NULL) {
+ SpecialOpcodeEntry = InitData->SpecialOpcodeEntry;
+
+ while (SpecialOpcodeEntry->OpcodeIndex != 0xFF) {
+ if (SpecialOpcodeEntry->OpcodeIndex == Index) {
+ OpcodeType &= (UINT16)~(B_PCH_SPI_OPTYPE0_MASK << (Index * 2));
+ OpcodeType |= (UINT16) (SpecialOpcodeEntry->Type << (Index * 2));
+ Code = SpecialOpcodeEntry->Code;
+ }
+
+ SpecialOpcodeEntry++;
+ }
+ }
+ ///
+ /// Set Opcode Menu Configuration registers.
+ /// Need to be done before sending any SPI command
+ ///
+ MmioWrite8 (
+ PchRootComplexBar + R_PCH_SPI_OPMENU + Index,
+ Code
+ );
+ MmioRead8 (PchRootComplexBar + R_PCH_SPI_OPMENU + Index);
+ }
+ ///
+ /// Set Opcode Type Configuration registers.
+ ///
+ MmioWrite16 (PchRootComplexBar + R_PCH_SPI_OPTYPE, OpcodeType);
+ MmioRead16 (PchRootComplexBar + R_PCH_SPI_OPTYPE);
+
+ if (JedecIdCmdOpcodeIndex >= SPI_NUM_OPCODE) {
+ return EFI_UNSUPPORTED;
+ } else {
+ ///
+ /// Read VendorId/DeviceId from SPI Component 1
+ ///
+ Status = SpiProtocolExecute (
+ This,
+ JedecIdCmdOpcodeIndex,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ (UINTN) 0,
+ 3,
+ FlashPartId,
+ EnumSpiRegionDescriptor
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Copy VendorId, DeviceId0, DeviceId1 and BiosStartOffset into SPI
+ /// driver Private data structure
+ ///
+ SpiInstance->SpiIdTable[0].VendorId = FlashPartId[0];
+ SpiInstance->SpiIdTable[0].DeviceId0 = FlashPartId[1];
+ SpiInstance->SpiIdTable[0].DeviceId1 = FlashPartId[2];
+ SpiInstance->SpiInitTable.BiosStartOffset = InitData->BiosStartOffset;
+ if (SpiInstance->SpiDescriptor.NumberComponents == 0x01) {
+ ///
+ /// If SPI Descriptor indicates two SPI components then
+ /// read VendorId/DeviceId from SPI Component 2.
+ /// Calculate SPI Component 2 address. The secondary SPI's address is equal to the first SPI's size
+ /// Note: 512KB (BIT19) is the minimum Componenty Density.
+ ///
+ Data32 = (UINT32) (UINTN) (V_PCH_SPI_FLCOMP_COMP_512KB << SpiInstance->SpiDescriptor.Comp1Density);
+ Status = SpiProtocolExecute (
+ This,
+ JedecIdCmdOpcodeIndex,
+ 0,
+ TRUE,
+ TRUE,
+ FALSE,
+ (UINTN) Data32,
+ 3,
+ FlashPartId,
+ EnumSpiRegionAll
+ );
+ if (!EFI_ERROR (Status)) {
+ ///
+ /// Copy VendorId, DeviceId0, DeviceId1 into SPI
+ /// driver Private data structure
+ ///
+ SpiInstance->SpiIdTable[1].VendorId = FlashPartId[0];
+ SpiInstance->SpiIdTable[1].DeviceId0 = FlashPartId[1];
+ SpiInstance->SpiIdTable[1].DeviceId1 = FlashPartId[2];
+ }
+ }
+ ///
+ /// Set the Prefix Opcode registers.
+ ///
+ MmioWrite16 (
+ PchRootComplexBar + R_PCH_SPI_PREOP,
+ (InitData->PrefixOpcode[1] << 8) | InitData->PrefixOpcode[0]
+ );
+ MmioRead16 (PchRootComplexBar + R_PCH_SPI_PREOP);
+
+ ///
+ /// Copy PrefixOpcode into SPI driver Private data structure
+ ///
+ for (Index = 0; Index < SPI_NUM_PREFIX_OPCODE; Index++) {
+ SpiInstance->SpiInitTable.PrefixOpcode[Index] = InitData->PrefixOpcode[Index];
+ }
+ ///
+ /// Copy BiosSize into SPI driver Private data structure
+ ///
+ SpiInstance->SpiInitTable.BiosSize = InitData->BiosSize;
+ }
+ ///
+ /// Get VSCC values from VTBA table in the Descriptor.
+ ///
+ if (SpiInstance->DescriptorMode == TRUE) {
+ Status = GetDescriptorVsccValues (
+ This,
+ ReadDataCmdOpcodeIndex,
+ &Vscc0Value,
+ &Vscc1Value
+ );
+
+ if (EFI_ERROR (Status)) {
+ ///
+ /// Program the VSCC0 & VSCC1 registers by getting the data from SpiInitTable
+ ///
+ for (Index = 0; Index < SPI_NUM_OPCODE; Index++) {
+ ///
+ /// For every platform that supports ME, only 4 KB erase is supported
+ /// Get the opcode from SpiInitTable if the operation is 4 KB erase
+ ///
+ if (SpiInstance->SpiInitTable.SpiCmdConfig[Index].Operation == EnumSpiOperationErase_4K_Byte) {
+ Vscc0Value = Vscc0Value | (UINT32) (V_PCH_SPI_VSCC0_BSES_4K);
+ Vscc0Value = Vscc0Value | (UINT32) (PCH_SPI_COMMAND_4KB_ERASE << 8);
+ } else if (SpiInstance->SpiInitTable.SpiCmdConfig[Index].Operation == EnumSpiOperationProgramData_64_Byte) {
+ Vscc0Value = Vscc0Value | (UINT32) (B_PCH_SPI_VSCC0_WG_64B);
+ }
+ }
+ ///
+ /// Bit WSR and WEWS should NOT be both set to 1, so we check if there is any "Write enable on Write status" prefix opcode
+ /// from SpiInitTable at first, then check "Write Status Enable" prefix opcode
+ ///
+ if ((SpiInstance->SpiInitTable.PrefixOpcode[0] == PCH_SPI_COMMAND_WRITE_ENABLE) ||
+ (SpiInstance->SpiInitTable.PrefixOpcode[1] == PCH_SPI_COMMAND_WRITE_ENABLE)) {
+ Vscc0Value = Vscc0Value | (UINT32) (B_PCH_SPI_VSCC0_WEWS);
+ } else if ((SpiInstance->SpiInitTable.PrefixOpcode[0] == PCH_SPI_COMMAND_WRITE_STATUS_EN) ||
+ (SpiInstance->SpiInitTable.PrefixOpcode[1] == PCH_SPI_COMMAND_WRITE_STATUS_EN)) {
+ Vscc0Value = Vscc0Value | (UINT32) (B_PCH_SPI_VSCC0_WSR);
+ }
+
+ Vscc1Value = Vscc0Value;
+ }
+ ///
+ /// The VCL locks itself when set, it will assert because we have no way to update VSCC value
+ ///
+ if ((MmioRead32 ((UINTN) (PchRootComplexBar + R_PCH_SPI_VSCC0)) & B_PCH_SPI_VSCC0_VCL) != 0) {
+ ASSERT_EFI_ERROR (EFI_ACCESS_DENIED);
+ return EFI_ACCESS_DENIED;
+ }
+
+ ASSERT (Vscc0Value != 0);
+ MmioWrite32 ((UINTN) (PchRootComplexBar + R_PCH_SPI_VSCC0), Vscc0Value);
+ if (SpiInstance->SpiDescriptor.NumberComponents) {
+ MmioWrite32 ((UINTN) (PchRootComplexBar + R_PCH_SPI_VSCC1), Vscc1Value);
+ }
+ }
+
+ SpiPhaseInit ();
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Execute SPI commands from the host controller.
+ This function would be called by runtime driver, please do not use any MMIO marco here
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] OpcodeIndex Index of the command in the OpCode Menu.
+ @param[in] PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+ @param[in] DataCycle TRUE if the SPI cycle contains data
+ @param[in] Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+ @param[in] ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+ @param[in] Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the
+ data transfer into multiple operations. This function ensures each operation does
+ not cross 256 byte flash address boundary.
+ *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+ (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+ function to cut the data transfer at proper address boundaries, and it's the
+ caller's reponsibility to pass in a properly cut DataByteCount parameter.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the
+ SPI cycle.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @exception EFI_UNSUPPORTED Command not supported.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolExecute (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 OpcodeIndex,
+ IN UINT8 PrefixOpcodeIndex,
+ IN BOOLEAN DataCycle,
+ IN BOOLEAN Atomic,
+ IN BOOLEAN ShiftOut,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer,
+ IN SPI_REGION_TYPE SpiRegionType
+ )
+{
+ EFI_STATUS Status;
+ UINT8 BiosCtlSave;
+ UINT32 Data32;
+ UINT32 PmBase;
+ UINT32 SmiEnSave;
+
+ BiosCtlSave = 0;
+ SmiEnSave = 0;
+
+ ///
+ /// Check if the parameters are valid.
+ ///
+ if ((OpcodeIndex >= SPI_NUM_OPCODE) || (PrefixOpcodeIndex >= SPI_NUM_PREFIX_OPCODE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Make sure it's safe to program the command.
+ /// Poll both Hardware Sequencing and Software Sequencing Status
+ ///
+ if (!WaitForSpiCycleComplete (This, TRUE, FALSE)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (!WaitForSpiCycleComplete (This, FALSE, FALSE)) {
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Acquire access to the SPI interface is not required any more.
+ ///
+ ///
+ /// Disable SMIs to make sure normal mode flash access is not interrupted by an SMI
+ /// whose SMI handler accesses flash (e.g. for error logging)
+ ///
+ /// *** NOTE: if the SMI_LOCK bit is set (i.e., B0:D31:F0:Offset A0h [4]='1'),
+ /// clearing B_GBL_SMI_EN will not have effect. In this situation, some other
+ /// synchronization methods must be applied either here or in the consumer of the
+ /// EFI_SPI_PROTOCOl.Execute(). An example method is disabling the specific SMI sources
+ /// whose SMI handlers access flash before calling Execute() and re-enabling the SMI
+ /// sources after the call.
+ ///
+ PmBase = PciRead32 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ SmiEnSave = IoRead32 ((UINTN) (PmBase + R_PCH_SMI_EN));
+ Data32 = SmiEnSave &~B_PCH_SMI_EN_GBL_SMI;
+ IoWrite32 ((UINTN) (PmBase + R_PCH_SMI_EN), Data32);
+ ///
+ /// If shifts the data out, disable Prefetching and Caching.
+ ///
+ if (ShiftOut) {
+ BiosCtlSave = PciRead8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL)
+ ) & V_PCH_LPC_BIOS_CNTL_SRC;
+ PciAndThenOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (~V_PCH_LPC_BIOS_CNTL_SRC),
+ (UINT8) ((V_PCH_SRC_PREF_DIS_CACHE_DIS))
+ );
+ }
+ ///
+ /// Sends the command to the SPI interface to execute.
+ ///
+ Status = SendSpiCmd (
+ This,
+ OpcodeIndex,
+ PrefixOpcodeIndex,
+ DataCycle,
+ Atomic,
+ ShiftOut,
+ Address,
+ DataByteCount,
+ Buffer,
+ SpiRegionType
+ );
+ ///
+ /// Restore the settings for SPI Prefetching and Caching.
+ ///
+ if (ShiftOut) {
+ PciAndThenOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (~V_PCH_LPC_BIOS_CNTL_SRC),
+ (UINT8) (BiosCtlSave)
+ );
+ }
+ ///
+ /// Restore SMIs.
+ ///
+ IoWrite32 ((UINTN) (PmBase + R_PCH_SMI_EN), SmiEnSave);
+
+ return Status;
+}
+
+/**
+ Convert SPI offset to Physical address of SPI hardware
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] SpiRegionOffset In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] BaseAddress Base Address of the region.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+ @param[in, out] HardwareSpiAddress Return absolution SPI address (i.e., Flash Linear Address)
+ @param[in, out] BaseAddress Return base address of the region type
+ @param[in, out] LimitAddress Return limit address of the region type
+
+ @retval EFI_SUCCESS Command succeed.
+**/
+VOID
+SpiOffset2Physical (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN SpiRegionOffset,
+ IN SPI_REGION_TYPE SpiRegionType,
+ OUT UINTN *HardwareSpiAddress,
+ OUT UINTN *BaseAddress,
+ OUT UINTN *LimitAddress
+ )
+{
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchRootComplexBar;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+ if (SpiInstance->DescriptorMode == TRUE) {
+ switch (SpiRegionType) {
+
+ case EnumSpiRegionBios:
+ *LimitAddress = (((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG1_BIOS)
+ & B_PCH_SPI_FREG1_LIMIT_MASK) >> 16) + 1) << 12;
+ *BaseAddress = (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG1_BIOS)
+ & B_PCH_SPI_FREG1_BASE_MASK) << 12;
+ break;
+
+ case EnumSpiRegionGbE:
+ *BaseAddress = (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG3_GBE) & B_PCH_SPI_FREG3_BASE_MASK) << 12;
+ *LimitAddress = (((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG3_GBE)
+ & B_PCH_SPI_FREG3_LIMIT_MASK) >> 16) + 1) << 12;
+ break;
+
+ case EnumSpiRegionMe:
+ *BaseAddress = (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG2_ME) & B_PCH_SPI_FREG2_BASE_MASK) << 12;
+ *LimitAddress = (((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG2_ME)
+ & B_PCH_SPI_FREG2_LIMIT_MASK) >> 16) + 1) << 12;
+ break;
+
+ case EnumSpiRegionDescriptor:
+ *BaseAddress = (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG0_FLASHD) & B_PCH_SPI_FREG0_BASE_MASK) << 12;
+ *LimitAddress = (((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG0_FLASHD)
+ & B_PCH_SPI_FREG0_LIMIT_MASK) >> 16) + 1) << 12;
+ break;
+
+ case EnumSpiRegionPlatformData:
+ *BaseAddress = (MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG4_PLATFORM_DATA) & B_PCH_SPI_FREG4_BASE_MASK) << 12;
+ *LimitAddress = (((MmioRead32 (PchRootComplexBar + R_PCH_SPI_FREG4_PLATFORM_DATA)
+ & B_PCH_SPI_FREG4_LIMIT_MASK) >> 16) + 1) << 12;
+ break;
+
+ default:
+ ///
+ /// EnumSpiRegionAll indicates address is relative to flash device (i.e., address is Flash
+ /// Linear Address)
+ ///
+ *BaseAddress = 0;
+ *LimitAddress = 0;
+ break;
+ }
+
+ *HardwareSpiAddress = SpiRegionOffset +*BaseAddress;
+ } else {
+ if (SpiRegionType == EnumSpiRegionAll) {
+ ///
+ /// EnumSpiRegionAll indicates address is relative to flash device (i.e., address is Flash
+ /// Linear Address)
+ ///
+ *HardwareSpiAddress = SpiRegionOffset;
+ } else {
+ ///
+ /// Otherwise address is relative to BIOS image
+ ///
+ *HardwareSpiAddress = SpiRegionOffset + SpiInstance->SpiInitTable.BiosStartOffset;
+ }
+ }
+}
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] OpcodeIndex Index of the command in the OpCode Menu.
+ @param[in] PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+ @param[in] DataCycle TRUE if the SPI cycle contains data
+ @param[in] Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+ @param[in] ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+ @param[in] Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the
+ data transfer into multiple operations. This function ensures each operation does
+ not cross 256 byte flash address boundary.
+ *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+ (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+ function to cut the data transfer at proper address boundaries, and it's the
+ caller's reponsibility to pass in a properly cut DataByteCount parameter.
+ @param[in, out] Buffer Data received or sent during the SPI cycle.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 OpcodeIndex,
+ IN UINT8 PrefixOpcodeIndex,
+ IN BOOLEAN DataCycle,
+ IN BOOLEAN Atomic,
+ IN BOOLEAN ShiftOut,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer,
+ IN SPI_REGION_TYPE SpiRegionType
+ )
+{
+ UINT32 Index;
+ SPI_INSTANCE *SpiInstance;
+ UINTN HardwareSpiAddr;
+ UINTN SpiBiosSize;
+ BOOLEAN UseSoftwareSequence;
+ UINTN BaseAddress;
+ UINTN LimitAddress;
+ UINT32 SpiDataCount;
+ UINT8 OpCode;
+ UINT16 OpType;
+ SPI_OPERATION Operation;
+ UINTN PchRootComplexBar;
+ UINT32 SpiSoftFreq;
+ UINT16 FlashCycle;
+ UINT8 BiosCntl;
+ BOOLEAN BiosWriteProtect;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+ SpiBiosSize = SpiInstance->SpiInitTable.BiosSize;
+ Operation = SpiInstance->SpiInitTable.SpiCmdConfig[OpcodeIndex].Operation;
+ OpCode = MmioRead8 (PchRootComplexBar + R_PCH_SPI_OPMENU + OpcodeIndex);
+ OpType = (MmioRead16 (PchRootComplexBar + R_PCH_SPI_OPTYPE) >> OpcodeIndex * 2) & (UINT16) (B_PCH_SPI_OPTYPE0_MASK);
+ ///
+ /// Please use PciRead here, it will link to MmioRead
+ /// if the caller is a Runtime driver, please use PchDxeRuntimePciLibPciExpress library, refer
+ /// PciExpressRead() on Library\DxeRuntimePciLibPciExpress\DxeRuntimePciLibPciExpress.c for the details.
+ /// For the rest please use EdkIIGlueBasePciLibPciExpress library
+ ///
+ BiosCntl = PciRead8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL));
+ ///
+ /// Check if the value of opcode register is 0 or the BIOS Size of SpiInitTable is 0 while SpiRegionType is EnumSpiRegionBios.
+ ///
+ if (OpCode == 0 || (SpiBiosSize == 0 && SpiRegionType == EnumSpiRegionBios)) {
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Check if need to disable BIOS Write Protect
+ ///
+ if ((Operation == EnumSpiOperationProgramData_1_Byte) ||
+ (Operation == EnumSpiOperationProgramData_64_Byte) ||
+ (Operation == EnumSpiOperationErase_256_Byte) ||
+ (Operation == EnumSpiOperationErase_4K_Byte) ||
+ (Operation == EnumSpiOperationErase_8K_Byte) ||
+ (Operation == EnumSpiOperationErase_64K_Byte) ||
+ (Operation == EnumSpiOperationFullChipErase)) {
+ DisableBiosWriteProtect ();
+ BiosWriteProtect = FALSE;
+ } else {
+ BiosWriteProtect = TRUE;
+ }
+ ///
+ /// Per PCH BIOS Spec Section 3.7 BIOS Region SMM Protection Enabling,
+ /// If SMM_BWP bit (D31:F0:RegDCh[5]) is set, the BIOS Region can only be updated
+ /// by following the steps:
+ /// - Once all threads enter SMM
+ /// - Read memory location FED30880h OR with 00000001h, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh. (This is done in
+ /// DisableBiosWriteProtect())
+ ///
+ if (((BiosCntl & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) &&
+ (BiosWriteProtect == FALSE) &&
+ ((MmioRead32 ((UINTN) 0xFED30880) & (UINT32) BIT0) == 0)) {
+ EnableBiosWriteProtect ();
+ return EFI_ACCESS_DENIED;
+ }
+ ///
+ /// When current code is read id OR current is not descriptor mode, we will use compatible mode
+ ///
+ UseSoftwareSequence = FALSE;
+ if ((Operation == EnumSpiOperationJedecId) ||
+ (Operation == EnumSpiOperationReadStatus) ||
+ (Operation == EnumSpiOperationWriteStatus) ||
+ (Operation == EnumSpiOperationWriteDisable) ||
+ (Operation == EnumSpiOperationWriteEnable) ||
+ (Operation == EnumSpiOperationEnableWriteStatus) ||
+ (Operation == EnumSpiOperationOther) ||
+ (Operation == EnumSpiOperationDiscoveryParameters) ||
+ (SpiInstance->DescriptorMode == FALSE)
+ ) {
+ UseSoftwareSequence = TRUE;
+ }
+
+ SpiOffset2Physical (This, Address, SpiRegionType, &HardwareSpiAddr, &BaseAddress, &LimitAddress);
+ ///
+ /// Have direct access to BIOS region in Descriptor mode,
+ ///
+ if (OpType == EnumSpiOpcodeRead && SpiRegionType == EnumSpiRegionBios) {
+ CopyMem (
+ Buffer,
+ (UINT8 *) ((HardwareSpiAddr - BaseAddress) + (UINT32) (~(SpiBiosSize - 1))),
+ DataByteCount
+ );
+ return EFI_SUCCESS;
+ }
+ ///
+ /// DEBUG((EFI_D_ERROR, "SPIADDR %x, %x, %x, %x\n", Address, HardwareSpiAddr, BaseAddress,
+ /// LimitAddress));
+ ///
+ if ((DataCycle == FALSE) && (DataByteCount > 0)) {
+ DataByteCount = 0;
+ }
+
+ do {
+ ///
+ /// Trim at 256 byte boundary per operation,
+ /// - PCH SPI controller requires trimming at 4KB boundary
+ /// - Some SPI chips require trimming at 256 byte boundary for write operation
+ /// - Trimming has limited performance impact as we can read / write atmost 64 byte
+ /// per operation
+ ///
+ if (HardwareSpiAddr + DataByteCount > ((HardwareSpiAddr + BIT8) &~(BIT8 - 1))) {
+ SpiDataCount = (((UINT32) (HardwareSpiAddr) + BIT8) &~(BIT8 - 1)) - (UINT32) (HardwareSpiAddr);
+ } else {
+ SpiDataCount = DataByteCount;
+ }
+ ///
+ /// Calculate the number of bytes to shift in/out during the SPI data cycle.
+ /// Valid settings for the number of bytes duing each data portion of the
+ /// PCH SPI cycles are: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 32, 40, 48, 56, 64
+ ///
+ if ((SpiInstance->DescriptorMode == FALSE) &&
+ (OpCode == PCH_SPI_COMMAND_PROGRAM_BYTE || Operation == EnumSpiOperationProgramData_1_Byte)) {
+ SpiDataCount = 1;
+ } else if (SpiDataCount >= 64) {
+ SpiDataCount = 64;
+ } else if ((SpiDataCount &~0x07) != 0) {
+ SpiDataCount = SpiDataCount &~0x07;
+ }
+ ///
+ /// If shifts data out, load data into the SPI data buffer.
+ ///
+ if (ShiftOut) {
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ MmioWrite8 (PchRootComplexBar + R_PCH_SPI_FDATA00 + Index, Buffer[Index]);
+ MmioRead8 (PchRootComplexBar + R_PCH_SPI_FDATA00 + Index);
+ }
+ }
+
+ MmioWrite32 (
+ (PchRootComplexBar + R_PCH_SPI_FADDR),
+ (UINT32) (HardwareSpiAddr & B_PCH_SPI_FADDR_MASK)
+ );
+ MmioRead32 (PchRootComplexBar + R_PCH_SPI_FADDR);
+
+ ///
+ /// Execute the command on the SPI compatible mode
+ ///
+ if (UseSoftwareSequence) {
+ ///
+ /// Software sequencing ...
+ ///
+ ///
+ /// Clear error flags
+ ///
+ MmioWrite16 (PchRootComplexBar + R_PCH_SPI_HSFS, (UINT16) B_PCH_SPI_HSFS_AEL);
+ MmioWrite8 (PchRootComplexBar + R_PCH_SPI_SSFS, (UINT8) B_PCH_SPI_SSFS_FCERR);
+
+ switch (SpiInstance->SpiInitTable.SpiCmdConfig[OpcodeIndex].Frequency) {
+ case EnumSpiCycle20MHz:
+ SpiSoftFreq = V_PCH_SPI_SSFC_SCF_20MHZ;
+ break;
+
+ case EnumSpiCycle33MHz:
+ SpiSoftFreq = V_PCH_SPI_SSFC_SCF_33MHZ;
+ break;
+
+ case EnumSpiCycle50MHz:
+ SpiSoftFreq = V_PCH_SPI_SSFC_SCF_50MHZ;
+ break;
+
+ default:
+ ///
+ /// This is an invalid use of the protocol
+ /// See definition, but caller must call with valid value
+ ///
+ SpiSoftFreq = 0;
+ ASSERT (!EFI_UNSUPPORTED);
+ break;
+ }
+ ///
+ /// PCH Chipset EDS 1.1, Section 22.1.19
+ /// SSFC BIT23:19 are reserved, BIOS must set this field to '11111'b
+ /// To change the offset to the right DWORD boundary, so use offset 0x90 as the operation address
+ ///
+ if (DataCycle) {
+ MmioWrite32 (
+ (PchRootComplexBar + R_PCH_SPI_SSFC - 1),
+ ( (UINT32) (BIT23 | BIT22 | BIT21 | BIT20 | BIT19) |
+ (UINT32) ((SpiSoftFreq << 16) & B_PCH_SPI_SSFC_SCF_MASK) |
+ (UINT32) (B_PCH_SPI_SSFC_DS) | (UINT32) (((SpiDataCount - 1) << 8) & B_PCH_SPI_SSFC_DBC_MASK) |
+ (UINT32) ((OpcodeIndex << 4) & B_PCH_SPI_SSFC_COP) |
+ (UINT32) ((PrefixOpcodeIndex << 3) & B_PCH_SPI_SSFC_SPOP) |
+ (UINT32) (Atomic ? B_PCH_SPI_SSFC_ACS : 0) |
+ (UINT32) (B_PCH_SPI_SSFC_SCGO)) << 8);
+ } else {
+ MmioWrite32 (
+ (PchRootComplexBar + R_PCH_SPI_SSFC - 1),
+ ( (UINT32) (BIT23 | BIT22 | BIT21 | BIT20 | BIT19) |
+ (UINT32) ((SpiSoftFreq << 16) & B_PCH_SPI_SSFC_SCF_MASK) |
+ (UINT32) ((OpcodeIndex << 4) & B_PCH_SPI_SSFC_COP) |
+ (UINT32) ((PrefixOpcodeIndex << 3) & B_PCH_SPI_SSFC_SPOP) |
+ (UINT32) (Atomic ? B_PCH_SPI_SSFC_ACS : 0) |
+ (UINT32) (B_PCH_SPI_SSFC_SCGO)) << 8);
+ }
+
+ MmioRead32 (PchRootComplexBar + R_PCH_SPI_SSFC - 1);
+ } else {
+ ///
+ /// Hardware sequencing ...
+ ///
+ ///
+ /// check for PCH SPI hardware sequencing required commands
+ ///
+ if (Operation == EnumSpiOperationReadData ||
+ Operation == EnumSpiOperationFastRead ||
+ Operation == EnumSpiOperationDualOutputFastRead) {
+ ///
+ /// Read Cycle
+ ///
+ FlashCycle = (UINT16) (V_PCH_SPI_HSFC_FCYCLE_READ << 1);
+ } else if (Operation == EnumSpiOperationProgramData_1_Byte ||
+ Operation == EnumSpiOperationProgramData_64_Byte) {
+ ///
+ /// Write Cycle
+ ///
+ FlashCycle = (UINT16) (V_PCH_SPI_HSFC_FCYCLE_WRITE << 1);
+ } else if (Operation == EnumSpiOperationErase_256_Byte ||
+ Operation == EnumSpiOperationErase_4K_Byte ||
+ Operation == EnumSpiOperationErase_8K_Byte ||
+ Operation == EnumSpiOperationErase_64K_Byte ||
+ Operation == EnumSpiOperationFullChipErase) {
+ ///
+ /// Erase Cycle
+ ///
+ FlashCycle = (UINT16) (V_PCH_SPI_HSFC_FCYCLE_ERASE << 1);
+ } else {
+ ///
+ /// Unrecognized Operation
+ ///
+ ASSERT (FALSE);
+ return EFI_ACCESS_DENIED;
+ }
+ ///
+ /// Clear error flags
+ ///
+ MmioWrite16 (
+ PchRootComplexBar + R_PCH_SPI_HSFS,
+ (UINT16) (B_PCH_SPI_HSFS_AEL | B_PCH_SPI_HSFS_FCERR)
+ );
+ ///
+ /// Send the command
+ ///
+ MmioWrite16 (
+ PchRootComplexBar + R_PCH_SPI_HSFC,
+ (UINT16) (((SpiDataCount - 1) << 8) & B_PCH_SPI_HSFC_FDBC_MASK) |
+ FlashCycle | B_PCH_SPI_HSFC_FCYCLE_FGO
+ );
+ ///
+ /// Read back for posted write to take effect
+ ///
+ MmioRead16 (PchRootComplexBar + R_PCH_SPI_HSFC);
+ }
+ ///
+ /// end of command execution
+ ///
+ /// Wait the SPI cycle to complete.
+ ///
+ if (!WaitForSpiCycleComplete (This, UseSoftwareSequence, TRUE)) {
+ if (BiosWriteProtect == FALSE) {
+ ///
+ /// Enable BIOS Write Protect
+ ///
+ EnableBiosWriteProtect ();
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// If shifts data in, get data from the SPI data bufffer.
+ ///
+ if (!ShiftOut) {
+ for (Index = 0; Index < SpiDataCount; Index++) {
+ Buffer[Index] = MmioRead8 (PchRootComplexBar + R_PCH_SPI_FDATA00 + Index);
+ }
+ }
+
+ HardwareSpiAddr += SpiDataCount;
+ Buffer += SpiDataCount;
+ DataByteCount -= SpiDataCount;
+ } while (DataByteCount > 0);
+
+ if (BiosWriteProtect == FALSE) {
+ ///
+ /// Enable BIOS Write Protect
+ ///
+ EnableBiosWriteProtect ();
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Wait execution cycle to complete on the SPI interface. Check both Hardware
+ and Software Sequencing status registers
+
+ @param[in] This The SPI protocol instance
+ @param[in] UseSoftwareSequence TRUE if Software Sequencing
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN BOOLEAN UseSoftwareSequence,
+ IN BOOLEAN ErrorCheck
+ )
+{
+ UINT64 WaitTicks;
+ UINT64 WaitCount;
+ UINT32 StatusRegAddr;
+ UINT32 CycleInProgressBit;
+ UINT16 AelBit;
+ UINT16 FcErrBit;
+ UINT16 FcycleDone;
+ UINT16 Data16;
+ SPI_INSTANCE *SpiInstance;
+ UINTN PchRootComplexBar;
+
+ SpiInstance = SPI_INSTANCE_FROM_SPIPROTOCOL (This);
+ PchRootComplexBar = SpiInstance->PchRootComplexBar;
+
+ if (UseSoftwareSequence) {
+ ///
+ /// This is Software Sequencing
+ ///
+ StatusRegAddr = R_PCH_SPI_SSFS;
+ CycleInProgressBit = B_PCH_SPI_SSFS_SCIP;
+ AelBit = B_PCH_SPI_SSFS_AEL;
+ FcErrBit = B_PCH_SPI_SSFS_FCERR;
+ FcycleDone = B_PCH_SPI_SSFS_CDS;
+ } else {
+ ///
+ /// This is Hardware Sequencing
+ ///
+ StatusRegAddr = R_PCH_SPI_HSFS;
+ CycleInProgressBit = B_PCH_SPI_HSFS_SCIP;
+ AelBit = B_PCH_SPI_HSFS_AEL;
+ FcErrBit = B_PCH_SPI_HSFS_FCERR;
+ FcycleDone = B_PCH_SPI_HSFS_FDONE;
+ }
+ ///
+ /// Convert the wait period allowed into to tick count
+ ///
+ WaitCount = WAIT_TIME / WAIT_PERIOD;
+
+ ///
+ /// Wait for the SPI cycle to complete.
+ ///
+ for (WaitTicks = 0; WaitTicks < WaitCount; WaitTicks++) {
+ Data16 = MmioRead16 (PchRootComplexBar + StatusRegAddr);
+ if ((Data16 & CycleInProgressBit) == 0) {
+ if (UseSoftwareSequence){
+ MmioWrite8 (PchRootComplexBar + StatusRegAddr, (UINT8)(AelBit | FcErrBit | FcycleDone));
+ }else{
+ MmioWrite16 (PchRootComplexBar + StatusRegAddr, (AelBit | FcErrBit | FcycleDone));
+ }
+ if (((Data16 & AelBit) || (Data16 & FcErrBit)) && (ErrorCheck == TRUE)) {
+ return FALSE;
+ } else {
+ return TRUE;
+ }
+ }
+
+ PchPmTimerStall (WAIT_PERIOD);
+ }
+
+ return FALSE;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.h b/ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.h
new file mode 100644
index 0000000..224ebee
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Common/SpiCommon.h
@@ -0,0 +1,300 @@
+/** @file
+ Header file for the PCH SPI Common Driver.
+
+@copyright
+ Copyright (c) 2008 - 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 _SPI_COMMON_H_
+#define _SPI_COMMON_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 "PchAccess.h"
+#include "PchPlatformLib.h"
+#endif
+//
+// Maximum time allowed while waiting the SPI cycle to complete
+// Wait Time = 6 seconds = 6000000 microseconds
+// Wait Period = 10 microseconds
+//
+#define WAIT_TIME 6000000 ///< Wait Time = 6 seconds = 6000000 microseconds
+#define WAIT_PERIOD 10 ///< Wait Period = 10 microseconds
+//
+// PCH Required SPI Commands -------- COMMAND SET I ------------
+// SPI flash device must support in order to be compatible with PCH
+//
+#define PCH_SPI_COMMAND_WRITE_STATUS 0x01
+#define PCH_SPI_COMMAND_PROGRAM_BYTE 0x02
+#define PCH_SPI_COMMAND_READ_DATA 0x03
+#define PCH_SPI_COMMAND_WRITE_DISABLE 0x04
+#define PCH_SPI_COMMAND_READ_STATUS 0x05
+#define PCH_SPI_COMMAND_WRITE_ENABLE 0x06
+#define PCH_SPI_COMMAND_FAST_READ 0x0B
+#define PCH_SPI_COMMAND_DUAL_FAST_READ 0x3B ///< Dual Output Fast Read
+#define PCH_SPI_COMMAND_ENABLE_WRITE_STATUS 0x50 ///< Enable Write Status Register
+#define PCH_SPI_COMMAND_DISCOVERY_PARAMETERS 0x5A ///< Serial Flash Discovery Parameters
+#define PCH_SPI_COMMAND_READ_ID 0x9F ///< JEDEC Read ID
+#define PCH_SPI_COMMAND_FULL_CHIP_ERASE 0xC7 ///< Full Chip Erase
+//
+// Need to support at least one of the following three kinds of size of sector for erasing
+//
+#define PCH_SPI_COMMAND_4KB_ERASE 0x20
+#define PCH_SPI_COMMAND_64KB_ERASE 0xD8
+#define PCH_SPI_COMMAND_256B_ERASE 0xDB
+//
+// ICH8M Recommended SPI Commands -------- COMMAND SET II ------------
+// SPI flash device best to support
+//
+#define PCH_SPI_COMMAND_WRITE_STATUS 0x01
+#define PCH_SPI_COMMAND_WRITE_STATUS_EN 0x50
+#define PCH_SPI_COMMAND_FULL_CHIP_ERASE 0xC7
+
+#define SIZE_OF_SPI_VTBA_ENTRY (S_PCH_SPI_VTBA_JID0 + S_PCH_SPI_VTBA_VSCC0)
+
+///
+/// Private data structure definitions for the driver
+///
+#define PCH_SPI_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'S', 'P', 'I')
+
+///
+/// Initialization data table loaded to the SPI host controller
+/// PrefixOpcode Prefix opcodes which are loaded into the SPI host controller
+/// SpiCmdConfig Determines Opcode Type, Menu and Frequency of the SPI commands
+/// BiosStartOffset The offset of the start of the BIOS image relative to the flash device.
+/// Please note this is a Flash Linear Address, NOT a memory space address.
+/// This value is platform specific and depends on the system flash map.
+/// This value is only used on non Descriptor mode.
+/// BiosSize The the BIOS Image size in flash. This value is platform specific
+/// and depends on the system flash map. Please note BIOS Image size may
+/// be smaller than BIOS Region size (in Descriptor Mode) or the flash size
+/// (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be
+/// placed at the top end of the BIOS Region (in Descriptor Mode) or the flash
+/// (in Non Descriptor Mode)
+///
+typedef struct _SPI_INIT_TABLE {
+ UINT8 PrefixOpcode[SPI_NUM_PREFIX_OPCODE];
+ SPI_COMMAND_CONFIG SpiCmdConfig[SPI_NUM_OPCODE];
+ UINTN BiosStartOffset;
+ UINTN BiosSize;
+} SPI_INIT_TABLE;
+
+typedef struct _SPI_ID_TABLE {
+ UINT8 VendorId;
+ UINT8 DeviceId0;
+ UINT8 DeviceId1;
+} SPI_ID_TABLE;
+
+typedef struct _SPI_DESCRIPTOR_TABLE {
+ UINT8 NumberComponents :2;
+ UINT8 Comp1Density :4;
+ UINT8 Rsvd :2;
+} SPI_DESCRIPTOR_TABLE;
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SPI_PROTOCOL SpiProtocol;
+ SPI_INIT_TABLE SpiInitTable;
+ SPI_ID_TABLE SpiIdTable[2];
+ UINTN PchRootComplexBar;
+ SPI_DESCRIPTOR_TABLE SpiDescriptor;
+ BOOLEAN DescriptorMode;
+} SPI_INSTANCE;
+
+#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol, PCH_SPI_PRIVATE_DATA_SIGNATURE)
+
+//
+// Function prototypes used by the SPI protocol.
+//
+
+/**
+ Initialize an SPI protocol instance.
+ The function will assert in debug if PCH RCBA has not been initialized
+
+ @param[in] SpiInstance Pointer to SpiInstance to initialize
+
+ @retval EFI_SUCCESS The protocol instance was properly initialized
+ @exception EFI_UNSUPPORTED The PCH is not supported by this module
+**/
+EFI_STATUS
+SpiProtocolConstructor (
+ SPI_INSTANCE *SpiInstance
+ );
+
+/**
+ JEDEC Read IDs from SPI flash part, this function will return 1-byte Vendor ID and 2-byte Device ID
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] Address This value is for determines the command is sent to SPI Component 1 or 2
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle.
+
+ @retval EFI_SUCCESS Read Jedec Id completed.
+ @retval EFI_DEVICE_ERROR Device error, operation failed.
+ @exception EFI_UNSUPPORTED This function is unsupport after SpiProtocolInit is called
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolReadId (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINTN Address,
+ IN OUT UINT8 *Buffer
+ );
+
+/**
+ Initialize the host controller to execute SPI command.
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] InitData Initialization data to be programmed into the SPI host controller.
+
+ @retval EFI_SUCCESS Initialization completed.
+ @retval EFI_ACCESS_DENIED The SPI static configuration interface has been locked-down.
+ @retval EFI_INVALID_PARAMETER Bad input parameters.
+ @exception EFI_UNSUPPORTED Can't get Descriptor mode VSCC values
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolInit (
+ IN EFI_SPI_PROTOCOL *This,
+ IN SPI_INIT_DATA *InitData
+ );
+
+/**
+ Execute SPI commands from the host controller.
+ This function would be called by runtime driver, please do not use any MMIO marco here
+
+ @param[in] This Pointer to the EFI_SPI_PROTOCOL instance.
+ @param[in] OpcodeIndex Index of the command in the OpCode Menu.
+ @param[in] PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+ @param[in] DataCycle TRUE if the SPI cycle contains data
+ @param[in] Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+ @param[in] ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+ @param[in] Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the
+ data transfer into multiple operations. This function ensures each operation does
+ not cross 256 byte flash address boundary.
+ *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+ (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+ function to cut the data transfer at proper address boundaries, and it's the
+ caller's reponsibility to pass in a properly cut DataByteCount parameter.
+ @param[in, out] Buffer Pointer to caller-allocated buffer containing the dada received or sent during the
+ SPI cycle.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+ @retval EFI_SUCCESS Command succeed.
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+ @exception EFI_UNSUPPORTED Command not supported.
+ @retval EFI_DEVICE_ERROR Device error, command aborts abnormally.
+**/
+EFI_STATUS
+EFIAPI
+SpiProtocolExecute (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 OpcodeIndex,
+ IN UINT8 PrefixOpcodeIndex,
+ IN BOOLEAN DataCycle,
+ IN BOOLEAN Atomic,
+ IN BOOLEAN ShiftOut,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer,
+ IN SPI_REGION_TYPE SpiRegionType
+ );
+
+/**
+ This function sends the programmed SPI command to the slave device.
+
+ @param[in] OpcodeIndex Index of the command in the OpCode Menu.
+ @param[in] PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence.
+ @param[in] DataCycle TRUE if the SPI cycle contains data
+ @param[in] Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed.
+ @param[in] ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in.
+ @param[in] Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform
+ Region, this value specifies the offset from the Region Base; for BIOS Region,
+ this value specifies the offset from the start of the BIOS Image. In Non
+ Descriptor Mode, this value specifies the offset from the start of the BIOS Image.
+ Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor
+ Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is
+ supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or
+ the flash (in Non Descriptor Mode)
+ @param[in] DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the
+ data transfer into multiple operations. This function ensures each operation does
+ not cross 256 byte flash address boundary.
+ *NOTE: if there is some SPI chip that has a stricter address boundary requirement
+ (e.g., its write page size is < 256 byte), then the caller cannot rely on this
+ function to cut the data transfer at proper address boundaries, and it's the
+ caller's reponsibility to pass in a properly cut DataByteCount parameter.
+ @param[in, out] Buffer Data received or sent during the SPI cycle.
+ @param[in] SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe,
+ EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in
+ Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode
+ and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative
+ to base of the 1st flash device (i.e., it is a Flash Linear Address).
+
+ @retval EFI_SUCCESS SPI command completes successfully.
+ @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally.
+ @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode
+ @retval EFI_INVALID_PARAMETER The parameters specified are not valid.
+**/
+EFI_STATUS
+SendSpiCmd (
+ IN EFI_SPI_PROTOCOL *This,
+ IN UINT8 OpcodeIndex,
+ IN UINT8 PrefixOpcodeIndex,
+ IN BOOLEAN DataCycle,
+ IN BOOLEAN Atomic,
+ IN BOOLEAN ShiftOut,
+ IN UINTN Address,
+ IN UINT32 DataByteCount,
+ IN OUT UINT8 *Buffer,
+ IN SPI_REGION_TYPE SpiRegionType
+ );
+
+/**
+ Wait execution cycle to complete on the SPI interface. Check both Hardware
+ and Software Sequencing status registers
+
+ @param[in] This The SPI protocol instance
+ @param[in] UseSoftwareSequence TRUE if this is a Hardware Sequencing operation
+ @param[in] ErrorCheck TRUE if the SpiCycle needs to do the error check
+
+ @retval TRUE SPI cycle completed on the interface.
+ @retval FALSE Time out while waiting the SPI cycle to complete.
+ It's not safe to program the next command on the SPI interface.
+**/
+BOOLEAN
+WaitForSpiCycleComplete (
+ IN EFI_SPI_PROTOCOL *This,
+ IN BOOLEAN UseSoftwareSequence,
+ IN BOOLEAN ErrorCheck
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c
new file mode 100644
index 0000000..f5b0062
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.c
@@ -0,0 +1,133 @@
+/** @file
+ PCH SPI PEIM implements the SPI Host Controller Compatibility Interface.
+
+@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
+**/
+#include "PchSpi.h"
+
+/**
+ Installs PCH SPI PPI
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS PCH SPI PPI is installed successfully
+ @retval EFI_OUT_OF_RESOURCES Can't allocate pool
+**/
+EFI_STATUS
+InstallPchSpi (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ PEI_SPI_INSTANCE *PeiSpiInstance;
+ SPI_INSTANCE *SpiInstance;
+
+ DEBUG ((EFI_D_INFO, "InstallPchSpi() Start\n"));
+
+ PeiSpiInstance = (PEI_SPI_INSTANCE *) AllocateZeroPool (sizeof (PEI_SPI_INSTANCE));
+ if (NULL == PeiSpiInstance) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ SpiInstance = &(PeiSpiInstance->SpiInstance);
+ SpiProtocolConstructor (SpiInstance);
+
+ PeiSpiInstance->PpiDescriptor.Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PeiSpiInstance->PpiDescriptor.Guid = &gPeiSpiPpiGuid;
+ PeiSpiInstance->PpiDescriptor.Ppi = &(SpiInstance->SpiProtocol);
+
+ ///
+ /// Install the SPI PPI
+ ///
+ Status = (**PeiServices).InstallPpi (PeiServices, &PeiSpiInstance->PpiDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "SPI PPI Installed\n"));
+
+ DEBUG ((EFI_D_INFO, "InstallPchSpi() End\n"));
+
+ return Status;
+}
+
+/**
+ This function is a a hook for Spi Pei phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ )
+{
+ return;
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+ ///
+ /// Enable the access to the BIOS space for both read and write cycles
+ ///
+ PciOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+ ///
+ /// Disable the access to the BIOS space for write cycles
+ ///
+ PciAnd8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (~B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.dxs b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.dxs
new file mode 100644
index 0000000..a2a2f80
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.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/Spi/Pei/PchSpi.h b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.h
new file mode 100644
index 0000000..d7be0a2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpi.h
@@ -0,0 +1,74 @@
+/** @file
+ Header file for the PCH SPI Runtime Driver.
+
+@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_SPI_H_
+#define _PCH_SPI_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include EFI_PPI_PRODUCER (Spi)
+#include "SpiCommon.h"
+#endif
+
+typedef struct {
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ SPI_INSTANCE SpiInstance;
+} PEI_SPI_INSTANCE;
+
+/**
+ This function is a hook for Spi Pei phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif
new file mode 100644
index 0000000..e6e60c4
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchSpiPeim"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Spi\Pei"
+ RefName = "PchSpiPeim"
+[files]
+"PchSpiPeim.sdl"
+"PchSpiPeim.mak"
+"PchSpi.c"
+"PchSpi.h"
+"PchSpi.dxs"
+"PchSpiPeim.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf
new file mode 100644
index 0000000..44d0485
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.inf
@@ -0,0 +1,83 @@
+## @file
+# Component description file for the SPI 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 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 = PchSpiPeim
+FILE_GUID = AA652CB9-2D52-4624-9FAE-D4E58B67CA46
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchSpi.h
+ PchSpi.c
+ ../Common/SpiCommon.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
+#
+# 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
+
+[libraries.common]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkPpiLib
+ PchPlatformLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSpi.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi
+ 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/Spi/Pei/PchSpiPeim.mak b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.mak
new file mode 100644
index 0000000..5504366
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.mak
@@ -0,0 +1,99 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSpiPeim/PchSpiPeim.mak 2 2/24/12 2:24a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:24a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiPeim/PchSpiPeim.mak $
+#
+# 2 2/24/12 2:24a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:23a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSpiPeim Driver
+#---------------------------------------------------------------------------
+EDK : PchSpiPeim
+PchSpiPeim : $(BUILD_DIR)\PchSpiPeim.mak PchSpiPeimBin
+
+
+$(BUILD_DIR)\PchSpiPeim.mak : $(PchSpiPeim_DIR)\$(@B).cif $(PchSpiPeim_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSpiPeim_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSpiPeim_INCLUDES=\
+ $(PCH_SPI_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchSpiPeim_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi"\
+ /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__
+
+PchSpiPeim_LIB_LINKS =\
+ $(PchPlatformPeiLib_LIB)\
+ $(PchSpiCommonPeiLib_LIB)\
+ $(IntelPchPpiLib_LIB)\
+ $(IntelPchPpiLib_BIN)\
+ $(EDKFRAMEWORKGUIDLIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB)\
+ $(EdkIIGluePeiMemoryAllocationLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+
+PchSpiPeimBin: $(PchSpiPeim_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSpiPeim.mak all\
+ NAME=PchSpiPeim\
+ MAKEFILE=$(BUILD_DIR)\PchSpiPeim.mak \
+ GUID=AA652CB9-2D52-4624-9FAE-D4E58B67CA46\
+ "MY_INCLUDES=$(PchSpiPeim_INCLUDES)"\
+ "MY_DEFINES=$(MY_DEFINES) $(PchSpiPeim_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchSpiPeim_DIR)\PchSpi.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/Spi/Pei/PchSpiPeim.sdl b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.sdl
new file mode 100644
index 0000000..526a272
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Pei/PchSpiPeim.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/PchSpiPeim/PchSpiPeim.sdl 1 2/08/12 9:23a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:23a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiPeim/PchSpiPeim.sdl $
+#
+# 1 2/08/12 9:23a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSpiPeim_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable PchSpiPeim support in Project"
+End
+
+PATH
+ Name = "PchSpiPeim_DIR"
+ Help = "PchSpiPeim file source directory"
+End
+
+MODULE
+ File = "PchSpiPeim.mak"
+ Help = "Includes PchSpiPeim.mak to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiPeim.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/Spi/RuntimeDxe/PchSpi.c b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.c
new file mode 100644
index 0000000..b833b63
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.c
@@ -0,0 +1,322 @@
+/** @file
+ PCH SPI Runtime Driver implements the SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2004 - 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 "PchSpi.h"
+
+///
+/// Global variables
+///
+SPI_INSTANCE *mSpiInstance;
+EFI_SPI_DATA_PROTOCOL mSpiDataInfoProtocol;
+
+static CONST UINT32 mSpiRegister[] = {
+ R_PCH_SPI_SSFS,
+ R_PCH_SPI_PREOP,
+ R_PCH_SPI_OPMENU,
+ R_PCH_SPI_OPMENU + 4,
+ R_PCH_SPI_VSCC0,
+ R_PCH_SPI_VSCC1
+};
+
+//
+// Function implementations
+//
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context. Not used in this event handler.
+
+ @retval None.
+**/
+EFI_RUNTIMESERVICE
+VOID
+PchSpiVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->PchRootComplexBar));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Init));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiProtocol.Execute));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance->SpiDescriptor));
+ gRT->ConvertPointer (EFI_INTERNAL_POINTER, (VOID *) &(mSpiInstance));
+}
+
+/**
+ Entry point for the SPI host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT64 BaseAddress;
+ UINT64 Length;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdMemorySpaceDescriptor;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR LpcMemorySpaceDescriptor;
+ UINT64 Attributes;
+
+ DEBUG ((EFI_D_INFO, "InstallPchSpi() Start\n"));
+
+ Status = PciLibConstructor ();
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate Runtime memory for the SPI protocol instance.
+ ///
+ mSpiInstance = AllocateRuntimeZeroPool (sizeof (SPI_INSTANCE));
+ if (mSpiInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ Status = SpiProtocolConstructor (mSpiInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Install the EFI_SPI_PROTOCOL interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(mSpiInstance->Handle),
+ &gEfiSpiProtocolGuid,
+ &(mSpiInstance->SpiProtocol),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ FreePool (mSpiInstance);
+ return EFI_DEVICE_ERROR;
+ }
+ ///
+ /// Set RCBA space in GCD to be RUNTIME so that the range will be supported in
+ /// virtual address mode in EFI aware OS runtime.
+ /// It will assert if RCBA Memory Space is not allocated
+ /// The caller is responsible for the existence and allocation of the RCBA Memory Spaces
+ ///
+ BaseAddress = (EFI_PHYSICAL_ADDRESS) (mSpiInstance->PchRootComplexBar);
+ Length = 0x4000;
+
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &GcdMemorySpaceDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes = GcdMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
+
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ Attributes
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// LPC memory space
+ ///
+ BaseAddress = MmPciAddress(0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0
+ );
+ Length = 4096;
+
+ Status = gDS->GetMemorySpaceDescriptor (BaseAddress, &LpcMemorySpaceDescriptor);
+ ASSERT_EFI_ERROR (Status);
+
+ Attributes = LpcMemorySpaceDescriptor.Attributes | EFI_MEMORY_RUNTIME;
+
+ Status = gDS->SetMemorySpaceAttributes (
+ BaseAddress,
+ Length,
+ Attributes
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PciLibRegisterMemory (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ 0),
+ (UINTN) Length
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InstallPchSpi() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Save SPI VSCC0/VSCC1 register into S3 resume script table.
+
+ @param[in] Event The event that triggered this notification function
+ @param[in] ParentImageHandle Pointer to the notification functions context
+**/
+VOID
+EFIAPI
+VsccS3SaveRestore (
+ IN EFI_EVENT Event,
+ IN VOID *ParentImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave;
+ UINTN Index;
+
+ ///
+ /// Check whether this is real BootScriptSave notification, or just a SignalEvent
+ ///
+ Status = gBS->LocateProtocol (&gEfiBootScriptSaveGuid, NULL, (VOID **) &BootScriptSave);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+ ///
+ /// Closed the event to avoid call twice when launch shell
+ ///
+ gBS->CloseEvent (Event);
+
+ ///
+ /// Save SPI Registers for S3 resume usage
+ ///
+ INITIALIZE_SCRIPT (ParentImageHandle, gST);
+
+ for (Index = 0; Index < sizeof (mSpiRegister) / sizeof (UINT32); Index++) {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index]),
+ 1,
+ (VOID *) (UINTN) (mSpiInstance->PchRootComplexBar + mSpiRegister[Index])
+ );
+ }
+
+ return;
+}
+
+/**
+ This function is a hook for Spi Dxe phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ )
+{
+ VOID *Registration;
+ EFI_STATUS Status;
+
+ ///
+ /// Create event for the SPI flash VSCC registers S3 save/restore.
+ ///
+ EfiCreateProtocolNotifyEvent (
+ &gEfiBootScriptSaveGuid,
+ TPL_CALLBACK,
+ VsccS3SaveRestore,
+ NULL,
+ &Registration
+ );
+
+ ///
+ /// Initialize and Install the SPI Data protocol
+ ///
+ mSpiDataInfoProtocol.BiosSize = mSpiInstance->SpiInitTable.BiosSize;
+ mSpiDataInfoProtocol.BiosStartMemoryAddress = SIZE_4GB - mSpiDataInfoProtocol.BiosSize;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(mSpiInstance->Handle),
+ &gEfiSpiDataProtocolGuid,
+ &mSpiDataInfoProtocol,
+ NULL
+ );
+ if (EFI_ERROR(Status))
+ {
+ ASSERT(FALSE);
+ }
+
+ return;
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+ ///
+ /// Enable the access to the BIOS space for both read and write cycles
+ ///
+ PciOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+ ///
+ /// Disable the access to the BIOS space for write cycles
+ ///
+ PciAnd8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (~B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.dxs b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.dxs
new file mode 100644
index 0000000..7a9a510
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.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 "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"
+#endif
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h
new file mode 100644
index 0000000..aaee7fb
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpi.h
@@ -0,0 +1,92 @@
+/** @file
+ Header file for the PCH SPI Runtime Driver.
+
+@copyright
+ Copyright (c) 2004 - 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
+**/
+#ifndef _PCH_SPI_H_
+#define _PCH_SPI_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include EFI_PROTOCOL_PRODUCER (Spi)
+#include "SpiCommon.h"
+#include "DxeRuntimePciLibPciExpress.h"
+#include "EfiScriptLib.h"
+#include EFI_PROTOCOL_CONSUMER (BootScriptSave)
+#endif
+
+#define SIZE_4GB 0x0000000100000000ULL
+
+//
+// Function prototypes used by the SPI protocol.
+//
+
+/**
+ Fixup internal data pointers so that the services can be called in virtual mode.
+
+ @param[in] Event The event registered.
+ @param[in] Context Event context. Not used in this event handler.
+
+ @retval None.
+**/
+VOID
+PchSpiVirtualAddressChangeEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ This function is a hook for Spi Dxe phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif
new file mode 100644
index 0000000..f721bd8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchSpiRuntime"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Spi\RuntimeDxe"
+ RefName = "PchSpiRuntime"
+[files]
+"PchSpiRuntime.sdl"
+"PchSpiRuntime.mak"
+"PchSpi.c"
+"PchSpi.h"
+"PchSpi.dxs"
+"PchSpiRuntime.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf
new file mode 100644
index 0000000..cd4ced8
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.inf
@@ -0,0 +1,91 @@
+## @file
+# Component description file for the SPI Runtime driver.
+#
+#@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
+#
+
+[defines]
+BASE_NAME = PchSpiRuntime
+FILE_GUID = C194C6EA-B68C-4981-B64B-9BD271474B20
+COMPONENT_TYPE = RT_DRIVER
+
+[sources.common]
+ PchSpi.h
+ PchSpi.c
+ ../Common/SpiCommon.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.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
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueEdkDxeRuntimeDriverLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueDxeServicesTableLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchDxeRuntimePciLibPciExpress
+ PchPlatformLib
+ EfiScriptLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSpi.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=PchSpiVirtualAddressChangeEvent
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ -D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_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_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak
new file mode 100644
index 0000000..39646e9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.mak
@@ -0,0 +1,113 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSpiRuntime/PchSpiRuntime.mak 2 2/24/12 2:27a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:27a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiRuntime/PchSpiRuntime.mak $
+#
+# 2 2/24/12 2:27a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:26a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSpiRuntime Driver
+#---------------------------------------------------------------------------
+EDK : PchSpiRuntime
+PchSpiRuntime : $(BUILD_DIR)\PchSpiRuntime.mak PchSpiRuntimeBin
+
+
+$(BUILD_DIR)\PchSpiRuntime.mak : $(PchSpiRuntime_DIR)\$(@B).cif $(PchSpiRuntime_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSpiRuntime_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSpiRuntime_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(EDK_INCLUDES)\
+ $(PCH_SPI_INCLUDES)\
+
+PchSpiRuntime_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi"\
+ /D "__EDKII_GLUE_SET_VIRTUAL_ADDRESS_MAP_EVENT_HANDLER__=PchSpiVirtualAddressChangeEvent"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_EDK_DXE_RUNTIME_DRIVER_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+
+PchSpiRuntime_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueEdkDxeRuntimeDriverLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(DxeRuntimePciLibPciExpressLib_LIB)\
+ $(PchPlatformDxeLib_LIB)\
+ $(EFISCRIPTLIB)\
+ $(PchSpiCommonDxeLib_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+PchSpiRuntimeBin: $(PchSpiRuntime_LIB_LINKS)
+ $(ECHO) DEPENDENCY_START > $(BUILD_DIR)\Fake.dxs
+ $(ECHO) FALSE >> $(BUILD_DIR)\Fake.dxs
+ $(ECHO) DEPENDENCY_END >> $(BUILD_DIR)\Fake.dxs
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSpiRuntime.mak all \
+ "MY_INCLUDES=$(PchSpiRuntime_INCLUDES)"\
+ "MY_DEFINES=$(PchSpiRuntime_DEFINES)"\
+ GUID=C194C6EA-B68C-4981-B64B-9BD271474B20\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=RT_DRIVER\
+ EDKIIModule=DXEDRIVER\
+ DEPEX1=$(BUILD_DIR)\Fake.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/Spi/RuntimeDxe/PchSpiRuntime.sdl b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.sdl
new file mode 100644
index 0000000..02546b0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/RuntimeDxe/PchSpiRuntime.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/PchSpiRuntime/PchSpiRuntime.sdl 1 2/08/12 9:25a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:25a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiRuntime/PchSpiRuntime.sdl $
+#
+# 1 2/08/12 9:25a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSpiRuntime_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSpiRuntime support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSpiRuntime_DIR"
+End
+
+MODULE
+ File = "PchSpiRuntime.mak"
+ Help = "Includes PchSpiRuntime to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiRuntime.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/Spi/Smm/PchSpi.c b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.c
new file mode 100644
index 0000000..9c041ad
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.c
@@ -0,0 +1,244 @@
+/** @file
+ PCH SPI SMM Driver implements the SPI Host Controller Compatibility Interface.
+
+@copyright
+ Copyright (c) 2008 - 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 "PchSpi.h"
+
+//
+// Global variables
+//
+EFI_SMM_BASE_PROTOCOL *mSmmBase;
+EFI_SMM_SYSTEM_TABLE *mSmst;
+SPI_INSTANCE *mSpiInstance;
+
+/**
+ Entry point for the SPI host controller driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Global system service table.
+
+ @retval EFI_SUCCESS Initialization complete.
+ @exception EFI_UNSUPPORTED The chipset is unsupported by this driver.
+ @retval EFI_OUT_OF_RESOURCES Do not have enough resources to initialize the driver.
+ @retval EFI_DEVICE_ERROR Device error, driver exits abnormally.
+**/
+EFI_STATUS
+EFIAPI
+InstallPchSpi (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate SMM Base Protocol
+ ///
+ Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Initialize our module variables
+ ///
+ Status = mSmmBase->GetSmstLocation (mSmmBase, &mSmst);
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Allocate pool for SPI protocol instance
+ ///
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData, /// MemoryType don't care
+ sizeof (SPI_INSTANCE),
+ (VOID **) &mSpiInstance
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (mSpiInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMem ((VOID *) mSpiInstance, sizeof (SPI_INSTANCE));
+ ///
+ /// Initialize the SPI protocol instance
+ ///
+ Status = SpiProtocolConstructor (mSpiInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Install the SMM EFI_SPI_PROTOCOL interface
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &(mSpiInstance->Handle),
+ &gEfiSmmSpiProtocolGuid,
+ &(mSpiInstance->SpiProtocol),
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ mSmst->SmmFreePool (mSpiInstance);
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is a a hook for Spi Smm phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ )
+{
+ UINTN Index;
+ static CONST UINT32 SpiRegister[] = {
+ R_PCH_SPI_SSFS,
+ R_PCH_SPI_PREOP,
+ R_PCH_SPI_OPMENU,
+ R_PCH_SPI_OPMENU + 4,
+ R_PCH_SPI_VSCC0,
+ R_PCH_SPI_VSCC1
+ };
+
+ ///
+ /// Save SPI Registers for S3 resume usage
+ ///
+ for (Index = 0; Index < sizeof (SpiRegister) / sizeof (UINT32); Index++) {
+ SCRIPT_MEM_WRITE (
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ EfiBootScriptWidthUint32,
+ (UINTN) (mSpiInstance->PchRootComplexBar + SpiRegister[Index]),
+ 1,
+ (VOID *) (UINTN) (mSpiInstance->PchRootComplexBar + SpiRegister[Index])
+ );
+ }
+}
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ )
+{
+ UINT8 Data8;
+ UINT32 Data32;
+
+ ///
+ /// Set BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 1b
+ ///
+ PciOr8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+ ///
+ /// PCH BIOS Spec Rev 0.5.0, Section 3.7 BIOS Region SMM Protection Enabling
+ /// If the following steps are implemented:
+ /// - Set the SMM_BWP bit (B0:D31:F0 Offset DCh [5]) = 1b
+ /// - Follow the 1st recommendation in section 3.6
+ /// the BIOS Region can only be updated by following the steps bellow:
+ /// - Once all threads enter SMM
+ /// - Read memory location FED30880h OR with 00000001h, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+ /// - Set BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 1b
+ /// - Modify BIOS Region
+ /// - Clear BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 0b
+ /// - Read memory location FED30880h AND with FFFFFFFEh, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+ ///
+ Data8 = PciRead8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL)
+ );
+ ///
+ /// Check if SMM_BWP bit is set
+ ///
+ if ((Data8 & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) {
+ ///
+ /// Read memory location FED30880h OR with 00000001h, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+ ///
+ Data32 = MmioRead32 ((UINTN) (0xFED30880)) | (UINT32) (BIT0);
+ AsmWriteMsr32 (0x1FE, Data32);
+ }
+}
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ )
+{
+ UINT8 Data8;
+ UINT32 Data32;
+
+ ///
+ /// Clear BIOSWE bit (B0:D31:F0 Offset DCh [0]) = 0b
+ ///
+ PciAnd8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL),
+ (UINT8) (~B_PCH_LPC_BIOS_CNTL_BIOSWE)
+ );
+
+ Data8 = PciRead8 (
+ PCI_LIB_ADDRESS (DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ 0,
+ R_PCH_LPC_BIOS_CNTL)
+ );
+ ///
+ /// Check if SMM_BWP bit is set
+ ///
+ if ((Data8 & B_PCH_LPC_BIOS_CNTL_SMM_BWP) == B_PCH_LPC_BIOS_CNTL_SMM_BWP) {
+ ///
+ /// Read memory location FED30880h AND with FFFFFFFEh, place the result in EAX,
+ /// and write data to lower 32 bits of MSR 1FEh (sample code available)
+ ///
+ Data32 = MmioRead32 ((UINTN) (0xFED30880)) & (UINT32) (~BIT0);
+ AsmWriteMsr32 (0x1FE, Data32);
+ }
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs
new file mode 100644
index 0000000..0f2e9b0
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.dxs
@@ -0,0 +1,45 @@
+/** @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 "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 (SmmBase)
+#include EFI_PROTOCOL_DEFINITION (BootScriptSave)
+#include EFI_PROTOCOL_DEFINITION (Pfat)
+#endif
+
+DEPENDENCY_START
+#ifdef EFI_S3_RESUME
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL_GUID AND
+#endif
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h
new file mode 100644
index 0000000..1f9244e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpi.h
@@ -0,0 +1,76 @@
+/** @file
+ Header file for the PCH SPI SMM Driver.
+
+@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_SPI_H_
+#define _PCH_SPI_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#include EFI_PROTOCOL_PRODUCER (Spi)
+#include "SpiCommon.h"
+#include "EfiScriptLib.h"
+
+//
+// Driver Dependency Protocols
+//
+#include EFI_PROTOCOL_DEPENDENCY (SmmBase)
+#include EFI_PROTOCOL_CONSUMER (BootScriptSave)
+#endif
+
+/**
+ This function is a a hook for Spi Smm phase specific initialization
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+SpiPhaseInit (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to disable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+DisableBiosWriteProtect (
+ VOID
+ );
+
+/**
+ This function is a hook for Spi to enable BIOS Write Protect
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+EnableBiosWriteProtect (
+ VOID
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif
new file mode 100644
index 0000000..8ae77f5
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PchSpiSmm"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Spi\Smm"
+ RefName = "PchSpiSmm"
+[files]
+"PchSpiSmm.sdl"
+"PchSpiSmm.mak"
+"PchSpi.c"
+"PchSpi.h"
+"PchSpi.dxs"
+"PchSpiSmm.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf
new file mode 100644
index 0000000..5fe34a2
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.inf
@@ -0,0 +1,92 @@
+## @file
+# Component description file for the SPI SMM driver.
+#
+#@copyright
+# Copyright (c) 2008 - 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 = PchSpiSmm
+FILE_GUID = 27F4917B-A707-4aad-9676-26DF168CBF0D
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ PchSpi.h
+ PchSpi.c
+ ../Common/SpiCommon.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueSmmDriverEntryPoint.c
+
+
+[includes.common]
+ .
+ ../Common
+ $(EDK_SOURCE)/Foundation/Efi
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Library/Dxe/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+ $(EFI_SOURCE)/$(PROJECT_CPU_ROOT)
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueBaseLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueSmmRuntimeDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueDxeMemoryAllocationLib
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueUefiDevicePathLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkFrameworkProtocolLib
+ EdkProtocolLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ PchPlatformLib
+ EfiScriptLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = PchSpi.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ -D __EDKII_GLUE_SMM_RUNTIME_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_UEFI_DEVICE_PATH_LIB__ \
+ -D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__
diff --git a/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak
new file mode 100644
index 0000000..9b15d4d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.mak
@@ -0,0 +1,112 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchSpiSmm/PchSpiSmm.mak 3 9/26/12 3:40a Victortu $
+#
+# $Revision: 3 $
+#
+# $Date: 9/26/12 3:40a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiSmm/PchSpiSmm.mak $
+#
+# 3 9/26/12 3:40a Victortu
+# Lynx Point PCH Chipset Framework Reference Code Beta 0.7.0
+#
+# 2 2/24/12 2:26a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:24a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchSpi SMM Driver
+#---------------------------------------------------------------------------
+EDK : PchSpiSmm
+PchSpiSmm : $(BUILD_DIR)\PchSpiSmm.mak PchSpiSmmBin
+
+
+$(BUILD_DIR)\PchSpiSmm.mak : $(PchSpiSmm_DIR)\$(@B).cif $(PchSpiSmm_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchSpiSmm_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchSpiSmm_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(PCH_SPI_INCLUDES)\
+ $(PROJECT_CPU_INCLUDES)\
+
+PchSpiSmm_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InstallPchSpi"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /D __EDKII_GLUE_DXE_MEMORY_ALLOCATION_LIB__ \
+ /D __EDKII_GLUE_DXE_DEBUG_LIB_REPORT_STATUS_CODE__ \
+ /D __EDKII_GLUE_SMM_RUNTIME_DXE_REPORT_STATUS_CODE_LIB__ \
+ /D __EDKII_GLUE_UEFI_BOOT_SERVICES_TABLE_LIB__ \
+ /D __EDKII_GLUE_UEFI_DEVICE_PATH_LIB__ \
+ /D __EDKII_GLUE_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_UEFI_RUNTIME_SERVICES_TABLE_LIB__ \
+
+PchSpiSmm_LIB_LINKS =\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueSmmRuntimeDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeMemoryAllocationLib_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueUefiDevicePathLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EDKFRAMEWORKPROTOCOLLIB)\
+ $(EDKPROTOCOLLIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(PchPlatformSmmLib_LIB)\
+ $(PchSpiCommonSmmLib_LIB)\
+ $(EFISCRIPTLIB)\
+ $(EdkIIGlueUefiRuntimeServicesTableLib_LIB)\
+
+PchSpiSmmBin: $(PchSpiSmm_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchSpiSmm.mak all \
+ "MY_INCLUDES=$(PchSpiSmm_INCLUDES)"\
+ "MY_DEFINES=$(PchSpiSmm_DEFINES)"\
+ GUID=27F4917B-A707-4aad-9676-26DF168CBF0D\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=BS_DRIVER\
+ EDKIIModule=SMMDRIVER\
+ DEPEX1=$(PchSpiSmm_DIR)\PchSpi.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/Spi/Smm/PchSpiSmm.sdl b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.sdl
new file mode 100644
index 0000000..5310706
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Spi/Smm/PchSpiSmm.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/PchSpiSmm/PchSpiSmm.sdl 1 2/08/12 9:24a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:24a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchSpiSmm/PchSpiSmm.sdl $
+#
+# 1 2/08/12 9:24a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchSpiSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchSpi SMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchSpiSmm_DIR"
+End
+
+MODULE
+ File = "PchSpiSmm.mak"
+ Help = "Includes PchSpi to Project"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchSpiSmm.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/Usb/Pei/PchEhci.c b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.c
new file mode 100644
index 0000000..e65e39e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.c
@@ -0,0 +1,229 @@
+/** @file
+ Pch Ehci PPI Init
+
+@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
+**/
+#include "PchEhci.h"
+#include "PchPlatformLib.h"
+
+EFI_GUID mPeiEhciControllerPpiGuid = PEI_USB_CONTROLLER_PPI_GUID;
+
+///
+/// PPI interface function
+///
+STATIC
+EFI_STATUS
+EFIAPI
+GetEhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_CONTROLLER_PPI *This,
+ IN UINT8 UsbControllerId,
+ OUT UINTN *ControllerType,
+ OUT UINTN *BaseAddress
+ );
+
+///
+/// Globals variable
+///
+STATIC PEI_USB_CONTROLLER_PPI mEhciControllerPpi = { GetEhciController };
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &mPeiEhciControllerPpiGuid,
+ NULL
+};
+
+///
+/// Helper function
+///
+STATIC
+EFI_STATUS
+EnableEhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_EHCI_DEVICE *PeiPchEhciDev,
+ IN UINT8 UsbControllerId
+ );
+
+/**
+ Initialize PCH EHCI PEIM
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] UsbPolicyPpi PCH Usb Policy PPI
+
+ @retval EFI_SUCCESS The PCH EHCI PEIM is initialized successfully
+ @retval EFI_INVALID_PARAMETER UsbControllerId is out of range
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+InitForEHCI (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_USB_POLICY_PPI *UsbPolicyPpi
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ PCH_EHCI_DEVICE *PeiPchEhciDev;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG ((EFI_D_INFO, "InitForEHCI() Start\n"));
+
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+
+ ///
+ /// We do not export this in S3 boot path, because it is only for recovery.
+ ///
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ return EFI_SUCCESS;
+ }
+
+ PeiPchEhciDev = (PCH_EHCI_DEVICE *) AllocatePool (sizeof (PCH_EHCI_DEVICE));
+ if (PeiPchEhciDev == NULL) {
+ DEBUG ((EFI_D_ERROR, "Failed to allocate memory for PeiPchEhciDev! \n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PeiPchEhciDev->EhciControllerPpi = mEhciControllerPpi;
+ PeiPchEhciDev->PpiList = mPpiList;
+ PeiPchEhciDev->PpiList.Ppi = &PeiPchEhciDev->EhciControllerPpi;
+
+ PeiPchEhciDev->TotalEhciControllers = PchEhciControllerMax;
+
+ ///
+ /// Assign resources and enable EHCI controllers
+ ///
+ if (UsbPolicyPpi->EhciMemLength < (EHCI_MEMORY_SPACE * PeiPchEhciDev->TotalEhciControllers)) {
+ DEBUG ((EFI_D_ERROR, "The EhciMemLength got from UsbPolicyPpi is less than the required (%0x) !\n", (EHCI_MEMORY_SPACE * PeiPchEhciDev->TotalEhciControllers)));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Index = 0; Index < PeiPchEhciDev->TotalEhciControllers; Index++) {
+ PeiPchEhciDev->MemBase[Index] = UsbPolicyPpi->EhciMemBaseAddr + EHCI_MEMORY_SPACE * Index;
+ Status = EnableEhciController (PeiServices, PeiPchEhciDev, (UINT8) Index);
+ ASSERT_EFI_ERROR (Status);
+ }
+ ///
+ /// Install USB Controller PPI
+ ///
+ Status = PeiServicesInstallPpi (&PeiPchEhciDev->PpiList);
+
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "InitForEHCI() End\n"));
+
+ return Status;
+
+}
+
+///
+/// PPI interface implementation
+///
+
+/**
+ Get EHCI controller information
+
+ @param[in] PeiServices General PEI services
+ @param[in] This Pointer to the PEI_EHCI_CONTROLLER_PPI
+ @param[in] UsbControllerId The USB controller number
+ @param[out] ControllerType Output: USB controller type
+ @param[out] BaseAddress Output: EHCI controller memory base address
+
+ @retval EFI_INVALID_PARAMETER UsbControllerId is out of range
+ @retval EFI_SUCCESS Function completes successfully
+**/
+STATIC
+EFI_STATUS
+EFIAPI
+GetEhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_CONTROLLER_PPI *This,
+ IN UINT8 UsbControllerId,
+ OUT UINTN *ControllerType,
+ OUT UINTN *BaseAddress
+ )
+{
+ PCH_EHCI_DEVICE *PeiPchEhciDev;
+
+ PeiPchEhciDev = PCH_EHCI_DEVICE_FROM_THIS (This);
+
+ if (UsbControllerId >= PeiPchEhciDev->TotalEhciControllers) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ControllerType = PEI_EHCI_CONTROLLER;
+
+ *BaseAddress = PeiPchEhciDev->MemBase[UsbControllerId];
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Enable the EHCI controller
+
+ @param[in] PeiServices The general PEI services
+ @param[in] PeiPchEhciDev The EHCI device
+ @param[in] UsbControllerId The USB Controller number
+
+ @retval EFI_INVALID_PARAMETER UsbControllerId is out of range
+ @retval EFI_SUCCESS The function completes successfully
+**/
+STATIC
+EFI_STATUS
+EnableEhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_EHCI_DEVICE *PeiPchEhciDev,
+ IN UINT8 UsbControllerId
+ )
+{
+ UINTN BaseAddress;
+ UINTN EhciAddress;
+ PCH_SERIES PchSeries;
+
+ PchSeries = GetPchSeries();
+ if (UsbControllerId >= PeiPchEhciDev->TotalEhciControllers) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BaseAddress = PeiPchEhciDev->MemBase[UsbControllerId];
+
+ EhciAddress = EFI_UNSUPPORTED;
+ if (PchSeries == PchH) {
+ EhciAddress = PCH_H_PCIE_EHCI_ADDR (UsbControllerId);
+ } else if (PchSeries == PchLp) {
+ EhciAddress = PCH_LP_PCIE_EHCI_ADDR (UsbControllerId);
+ }
+
+ if (EhciAddress == EFI_UNSUPPORTED) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ///
+ /// Assign base address register
+ ///
+ MmioWrite32 ((EhciAddress + R_PCH_EHCI_MEM_BASE), BaseAddress);
+
+ ///
+ /// Enable PCH EHCI register
+ ///
+ MmioOr16 (
+ (EhciAddress + R_PCH_EHCI_COMMAND_REGISTER),
+ (UINT16) (B_PCH_EHCI_COMMAND_BME | B_PCH_EHCI_COMMAND_MSE)
+ );
+
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h
new file mode 100644
index 0000000..3c97998
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchEhci.h
@@ -0,0 +1,82 @@
+/** @file
+ Header file for the PCH EHCI PPI
+
+@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 _PEI_PCH_EHCI_H
+#define _PEI_PCH_EHCI_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 "EdkIIGluePeim.h"
+
+//
+// Driver Produced PPI Prototypes
+//
+#include EFI_PPI_DEFINITION (UsbController)
+
+//
+// Driver Consumed PPI Prototypes
+//
+#include EFI_PPI_CONSUMER (PchUsbPolicy)
+#include "PchAccess.h"
+#include "PchUsb.h"
+#endif
+
+#define PCH_PCIE_EHCI1_BUS_DEV_FUNC MmPciAddress ( \
+ 0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_USB, \
+ PCI_FUNCTION_NUMBER_PCH_EHCI, \
+ 0 \
+ )
+
+#define PCH_PCIE_EHCI2_BUS_DEV_FUNC MmPciAddress ( \
+ 0, \
+ DEFAULT_PCI_BUS_NUMBER_PCH, \
+ PCI_DEVICE_NUMBER_PCH_USB_EXT, \
+ PCI_FUNCTION_NUMBER_PCH_EHCI2, \
+ 0 \
+ )
+
+#define PCH_H_PCIE_EHCI_ADDR(Controller) ( \
+ (Controller == PchEhci1) ? PCH_PCIE_EHCI1_BUS_DEV_FUNC : \
+ (Controller == PchEhci2) ? PCH_PCIE_EHCI2_BUS_DEV_FUNC : EFI_UNSUPPORTED \
+ )
+
+#define PCH_LP_PCIE_EHCI_ADDR(Controller) ( \
+ (Controller == PchEhci1) ? PCH_PCIE_EHCI1_BUS_DEV_FUNC : EFI_UNSUPPORTED \
+ )
+
+#define PEI_PCH_EHCI_SIGNATURE EFI_SIGNATURE_32 ('E', 'H', 'C', 'I')
+#define EHCI_MEMORY_SPACE 0x400
+
+typedef struct {
+ UINTN Signature;
+ PEI_USB_CONTROLLER_PPI EhciControllerPpi;
+ EFI_PEI_PPI_DESCRIPTOR PpiList;
+ UINTN TotalEhciControllers;
+ UINTN MemBase[PchEhciControllerMax];
+} PCH_EHCI_DEVICE;
+
+#define PCH_EHCI_DEVICE_FROM_THIS(a) PEI_CR (a, PCH_EHCI_DEVICE, EhciControllerPpi, PEI_PCH_EHCI_SIGNATURE)
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c
new file mode 100644
index 0000000..493f5e6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.c
@@ -0,0 +1,77 @@
+/** @file
+ Pch Usb Pei Init
+
+@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
+**/
+#include "PchUsb.h"
+
+/**
+ Initialize PCH USB PEIM
+
+ @param[in] FfsHeader Not used.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS The PCH USB PEIM is initialized successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+InitializePchUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ PCH_USB_POLICY_PPI *UsbPolicyPpi;
+
+ DEBUG ((EFI_D_INFO, "InitializePchUsb() Start\n"));
+
+ ///
+ /// Locate UsbPolicy PPI
+ ///
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPchUsbPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &UsbPolicyPpi
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (Status == EFI_SUCCESS) {
+ ///
+ /// Enable USB controller and install PeiUsbControllerPpi for USB recovery function
+ ///
+ switch (UsbPolicyPpi->Mode) {
+ case EHCI_MODE:
+ DEBUG ((EFI_D_ERROR, "Usb Recovery Mode : EHCI !\n"));
+ DEBUG ((EFI_D_ERROR, "EhciMemBaseAddr:%0x!\n", UsbPolicyPpi->EhciMemBaseAddr));
+ DEBUG ((EFI_D_ERROR, "EhciMemLength:%0x!\n", UsbPolicyPpi->EhciMemLength));
+ InitForEHCI (PeiServices, UsbPolicyPpi);
+ break;
+
+ default:
+ ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
+ break;
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "InitializePchUsb() End\n"));
+
+ return Status;
+
+} \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif
new file mode 100644
index 0000000..277bd21
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "PchUsb"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Usb\Pei"
+ RefName = "PchUsb"
+[files]
+"PchUsb.sdl"
+"PchUsb.mak"
+"PchUsb.dxs"
+"PchEhci.c"
+"PchEhci.h"
+"PchUsb.c"
+"PchUsb.h"
+"PchUsb.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs
new file mode 100644
index 0000000..34d58dd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.dxs
@@ -0,0 +1,45 @@
+/** @file
+ Dependency expression file for PCH USB 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 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
+
+**/
+
+
+//
+// Same 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"
+
+#include EFI_PPI_DEFINITION (LoadFile)
+#include EFI_PPI_DEFINITION (PchUsbPolicy)
+#include EFI_PPI_CONSUMER (BootMode)
+#endif
+
+DEPENDENCY_START
+ EFI_PEI_FV_FILE_LOADER_GUID AND
+ PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ PCH_USB_POLICY_PPI_GUID
+DEPENDENCY_END \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h
new file mode 100644
index 0000000..7f20b4a
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.h
@@ -0,0 +1,47 @@
+/** @file
+ Header file for the PCH USB 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_USB_H_
+#define _PCH_USB_H_
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include "PchAccess.h"
+#include EFI_PPI_CONSUMER (PchUsbPolicy)
+#endif
+
+/**
+ Initialize PCH EHCI PEIM
+
+ @param[in] PeiServices General purpose services available to every PEIM.
+ @param[in] UsbPolicyPpi PCH Usb Policy PPI
+
+ @retval EFI_SUCCESS The PCH EHCI PEIM is initialized successfully
+ @retval EFI_INVALID_PARAMETER UsbControllerId is out of range
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create database
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+InitForEHCI (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PCH_USB_POLICY_PPI *UsbPolicyPpi
+ );
+
+#endif
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf
new file mode 100644
index 0000000..bb6fe1e
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.inf
@@ -0,0 +1,87 @@
+## @file
+# Component description file for PCH USB 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 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 = PchUsb
+FILE_GUID = 6B4FDBD2-47E1-4a09-BA8E-8E041F208B95
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ PchEhci.c
+ PchUsb.c
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGluePeimEntryPoint.c
+
+[includes.common]
+ $(EDK_SOURCE)/Foundation/Efi
+ .
+ $(EDK_SOURCE)/Foundation/Include
+ $(EDK_SOURCE)/Foundation/Efi/Include
+ $(EDK_SOURCE)/Foundation/Framework/Include
+ $(EDK_SOURCE)/Foundation/Library/Pei/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Protocol/PchPlatformPolicy
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Library/PchPlatformLib
+ $(EFI_SOURCE)/$(PROJECT_PCH_ROOT)/Include/Library
+#
+# 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]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGluePeiMemoryAllocationLib
+ EdkPpiLib
+ PchPlatformLib
+ EdkIIGlueBasePciLibPciExpress
+
+[nmake.common]
+ IMAGE_ENTRY_POINT=_ModuleEntryPoint
+ DPX_SOURCE=PchUsb.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchUsb
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -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__
diff --git a/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak
new file mode 100644
index 0000000..22c8316
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.mak
@@ -0,0 +1,111 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/PchUsb/PchUsb.mak 4 10/16/12 3:37a Scottyang $
+#
+# $Revision: 4 $
+#
+# $Date: 10/16/12 3:37a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsb/PchUsb.mak $
+#
+# 4 10/16/12 3:37a Scottyang
+# [TAG] EIP103924
+#
+# [Category] Improvement
+#
+# [Description] Update RC 0.7.1
+#
+# [Files] ReferenceCode\Chipset\LynxPoint\*.*, SBDxe.c, SB.sd,
+# SbSetupData.c, GetSetupDate.c
+#
+# 3 7/02/12 9:19a Victortu
+#
+# 2 2/24/12 2:30a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:30a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+
+#---------------------------------------------------------------------------
+# Create PchUsb Driver
+#---------------------------------------------------------------------------
+EDK : PchUsb
+PchUsb : $(BUILD_DIR)\PchUsb.mak PchUsbBin
+
+
+$(BUILD_DIR)\PchUsb.mak : $(PchUsb_DIR)\$(@B).cif $(PchUsb_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PchUsb_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PchUsb_INCLUDES=\
+ $(INTEL_PCH_INCLUDES)\
+ /I$(INTEL_PCH_DIR)\Library\PchPlatformLib\
+ $(EdkIIGlueLib_INCLUDES)\
+
+PchUsb_DEFINES = $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=InitializePchUsb"\
+ /D__EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /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_CF8__
+
+PchUsb_LIB_LINKS =\
+ $(EDKFRAMEWORKPPILIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB) \
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB) \
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB) \
+ $(EdkIIGluePeiReportStatusCodeLib_LIB) \
+ $(EdkIIGluePeiServicesLib_LIB) \
+ $(EdkIIGluePeiMemoryAllocationLib_LIB) \
+ $(EdkIIGlueBasePciLibCf8_LIB) \
+ $(IntelPchPpiLib_LIB) \
+ $(PchPlatformPeiLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)
+
+PchUsbBin: $(PchUsb_LIB_LINKS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\PchUsb.mak all\
+ NAME=PchUsb\
+ MAKEFILE=$(BUILD_DIR)\PchUsb.mak \
+ GUID=6B4FDBD2-47E1-4a09-BA8E-8E041F208B95\
+ "MY_INCLUDES=$(PchUsb_INCLUDES)"\
+ "MY_DEFINES=$(PchUsb_DEFINES)"\
+ ENTRY_POINT=_ModuleEntryPoint \
+ TYPE=PEIM \
+ EDKIIModule=PEIM\
+ DEPEX1=$(PchUsb_DIR)\PchUsb.dxs DEPEX1_TYPE=EFI_SECTION_PEI_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/Usb/Pei/PchUsb.sdl b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.sdl
new file mode 100644
index 0000000..ca8d385
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Usb/Pei/PchUsb.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/PchUsb/PchUsb.sdl 1 2/08/12 9:30a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:30a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/PchUsb/PchUsb.sdl $
+#
+# 1 2/08/12 9:30a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "PchUsb_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PchUsb support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PchUsb_DIR"
+End
+
+MODULE
+ Help = "Includes PchUsb.mak to Project"
+ File = "PchUsb.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PchUsb.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/Wdt/Common/WdtCommon.c b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.c
new file mode 100644
index 0000000..6576aad
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.c
@@ -0,0 +1,246 @@
+/** @file
+ Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueBase.h"
+#endif
+
+#include "WdtCommon.h"
+
+UINT8 mAllowExpectedReset = 0;
+///
+/// mWdtHobGuid is linked and used in WdtPei and WdtDxe
+///
+EFI_GUID mWdtHobGuid = WDT_HOB_GUID;
+
+/**
+ Reads LPC bridge to get Watchdog Timer address
+
+ @param[in] none
+
+ @retval UINT32 Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+ VOID
+ )
+{
+ UINT32 Address;
+
+ Address = (MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)) & B_PCH_LPC_ACPI_BASE_BAR)
+ + R_PCH_OC_WDT_CTL;
+
+ return Address;
+}
+
+/**
+ Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+ causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+ function was called too.
+
+ @param[in] TimeoutValue Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+ @retval EFI_SUCCESS if everything's OK
+ @retval EFI_INVALID_PARAMETER if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+ IN UINT32 TimeoutValue
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "\n(Wdt) ReloadAndStartTimer(%d)\n", TimeoutValue));
+
+ if ((TimeoutValue > B_PCH_OC_WDT_CTL_TOV_MASK) || (TimeoutValue == 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Readback = IoRead32 (WdtGetAddress ());
+ Readback |= (B_PCH_OC_WDT_CTL_EN | B_PCH_OC_WDT_CTL_FORCE_ALL | B_PCH_OC_WDT_CTL_ICCSURV);
+ if (mAllowExpectedReset == 0) {
+ Readback |= B_PCH_OC_WDT_CTL_UNXP_RESET_STS;
+ }
+
+#if defined EFI_DEBUG && !defined USE_WDT_IN_DEBUG_BIOS
+ ///
+ /// in Debug mode, WDT will not be turned on. This is to prevent platform reboots triggered
+ /// by WDT expiration, which can be expected when processor is halted for debugging
+ ///
+ Readback &= ~(B_PCH_OC_WDT_CTL_EN | B_PCH_OC_WDT_CTL_FORCE_ALL | B_PCH_OC_WDT_CTL_UNXP_RESET_STS);
+ DEBUG ((EFI_D_INFO, "(Wdt) Wdt disabled in Debug BIOS\n"));
+
+#endif
+
+ Readback &= ~(B_PCH_OC_WDT_CTL_TOV_MASK);
+ Readback |= ((TimeoutValue - 1) & B_PCH_OC_WDT_CTL_TOV_MASK);
+ IoWrite32 (WdtGetAddress (), Readback);
+ Readback |= B_PCH_OC_WDT_CTL_RLD;
+ IoWrite32 (WdtGetAddress (), Readback);
+ return EFI_SUCCESS;
+}
+
+/**
+ Disables WDT timer.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+WdtDisable (
+ VOID
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) DisableTimer\n"));
+
+ Readback = IoRead32 (WdtGetAddress ());
+ Readback &= ~(B_PCH_OC_WDT_CTL_EN | B_PCH_OC_WDT_CTL_FORCE_ALL | B_PCH_OC_WDT_CTL_UNXP_RESET_STS);
+ IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+ Returns WDT failure status.
+
+ @param[in] None
+
+ @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE If there was WDT expiration or unexpected reset
+ @retval V_PCH_OC_WDT_CTL_STATUS_OK Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+ VOID
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) CheckTimerStatus\n"));
+
+ Readback = IoRead32 (WdtGetAddress ());
+
+ DEBUG ((EFI_D_INFO, "(Wdt) Readback = (%x)\n", Readback));
+
+ if (Readback & B_PCH_OC_WDT_CTL_FAILURE_STS) {
+ DEBUG ((EFI_D_INFO, "(Wdt) Status = FAILURE\n"));
+ return V_PCH_OC_WDT_CTL_STATUS_FAILURE;
+ } else {
+ return V_PCH_OC_WDT_CTL_STATUS_OK;
+ }
+}
+
+/**
+ Normally, each reboot performed while watchdog runs is considered a failure.
+ This function allows platform to perform expected reboots with WDT running,
+ without being interpreted as failures.
+ In DXE phase, it is enough to call this function any time before reset.
+ In PEI phase, between calling this function and performing reset, ReloadAndStart()
+ must not be called.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+ VOID
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) AllowKnownReset\n"));
+
+ mAllowExpectedReset = 1;
+
+ Readback = IoRead32 (WdtGetAddress ());
+ Readback &= ~(B_PCH_OC_WDT_CTL_UNXP_RESET_STS | B_PCH_OC_WDT_CTL_FORCE_ALL);
+ IoWrite32 (WdtGetAddress (), Readback);
+}
+
+/**
+ Returns information if WDT coverage for the duration of BIOS execution
+ was requested by an OS application
+
+ @param[in] None
+
+ @retval TRUE if WDT was requested
+ @retval FALSE if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+ VOID
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) IsWdtRequired"));
+
+ Readback = IoRead32 (WdtGetAddress ());
+
+ if ((Readback & B_PCH_OC_WDT_CTL_AFTER_POST) != 0) {
+ DEBUG ((EFI_D_INFO, " - yes\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, " - no\n"));
+ return FALSE;
+ }
+
+}
+
+/**
+ Returns WDT enabled/disabled status.
+
+ @param[in] None
+
+ @retval TRUE if WDT is enabled
+ @retval FALSE if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+ VOID
+ )
+{
+ UINT32 Readback;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) IsWdtEnabled"));
+
+ Readback = IoRead32 (WdtGetAddress ());
+
+ if ((Readback & B_PCH_OC_WDT_CTL_EN) != 0) {
+ DEBUG ((EFI_D_INFO, " - yes\n"));
+ return TRUE;
+ } else {
+ DEBUG ((EFI_D_INFO, " - no\n"));
+ return FALSE;
+ }
+
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.h b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.h
new file mode 100644
index 0000000..dfc6959
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommon.h
@@ -0,0 +1,166 @@
+/** @file
+ Library that contains common parts of WdtPei and WdtDxe. Not a standalone module.
+
+@copyright
+ Copyright (c) 2010 - 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 "PchAccess.h"
+
+extern UINT8 mAllowExpectedReset;
+extern EFI_GUID mWdtHobGuid;
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define WDT_HOB_GUID \
+ { \
+ 0x65675786, 0xacca, 0x4b11, 0x8a, 0xb7, 0xf8, 0x43, 0xaa, 0x2a, 0x8b, 0xea \
+ }
+#else
+#define WDT_HOB_GUID \
+ { \
+ 0x65675786, 0xacca, 0x4b11, \
+ { \
+ 0x8a, 0xb7, 0xf8, 0x43, 0xaa, 0x2a, 0x8b, 0xea \
+ } \
+ }
+#endif
+//
+// HOB definitions duplicated from HOB.h which couldn't be included directly,
+// because it requires either EdkIIGluePeim.h or EdkIIGlueDxe.h,
+// and WdtCommon must not include any of those.
+//
+#ifndef _PEI_HOB_H_
+#ifndef __HOB__H__
+typedef struct _EFI_HOB_GENERIC_HEADER {
+ UINT16 HobType;
+ UINT16 HobLength;
+ UINT32 Reserved;
+} EFI_HOB_GENERIC_HEADER;
+
+typedef struct _EFI_HOB_GUID_TYPE {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+} EFI_HOB_GUID_TYPE;
+#endif
+#endif
+
+typedef struct {
+ EFI_HOB_GUID_TYPE Header;
+ UINT16 TimeoutValue;
+ UINT8 Active;
+} WDT_HOB;
+
+/**
+ Reads LPC bridge to get Watchdog Timer address
+
+ @param[in] none
+
+ @retval UINT32 Watchdog's address
+**/
+UINT32
+WdtGetAddress (
+ VOID
+ );
+
+/**
+ Reloads WDT with new timeout value and starts it. Also sets Unexpected Reset bit, which
+ causes the next reset to be treated as watchdog expiration - unless AllowKnownReset()
+ function was called too.
+
+ @param[in] TimeoutValue Time in seconds before WDT times out. Supported range = 1 - 1024.
+
+ @retval EFI_SUCCESS if everything's OK
+ @retval EFI_INVALID_PARAMETER if TimeoutValue parameter is wrong
+**/
+EFI_STATUS
+EFIAPI
+WdtReloadAndStart (
+ IN UINT32 TimeoutValue
+ );
+
+/**
+ Disables WDT timer.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+WdtDisable (
+ VOID
+ );
+
+/**
+ Returns WDT failure status.
+
+ @param[in] None
+
+ @retval V_PCH_OC_WDT_CTL_STATUS_FAILURE If there was WDT expiration or unexpected reset
+ @retval V_PCH_OC_WDT_CTL_STATUS_OK Otherwise
+**/
+UINT8
+EFIAPI
+WdtCheckStatus (
+ VOID
+ );
+
+/**
+ Normally, each reboot performed while watchdog runs is considered a failure.
+ This function allows platform to perform expected reboots with WDT running,
+ without being interpreted as failures.
+ In DXE phase, it is enough to call this function any time before reset.
+ In PEI phase, between calling this function and performing reset, ReloadAndStart()
+ must not be called.
+
+ @param[in] None
+
+ @retval None
+**/
+VOID
+EFIAPI
+WdtAllowKnownReset (
+ VOID
+ );
+
+/**
+ Returns information if WDT coverage for the duration of BIOS execution
+ was requested by an OS application
+
+ @param[in] None
+
+ @retval TRUE if WDT was requested
+ @retval FALSE if WDT was not requested
+**/
+UINT8
+EFIAPI
+IsWdtRequired (
+ VOID
+ );
+
+/**
+ Returns WDT enabled/disabled status.
+
+ @param[in] None
+
+ @retval TRUE if WDT is enabled
+ @retval FALSE if WDT is disabled
+**/
+UINT8
+EFIAPI
+IsWdtEnabled (
+ VOID
+ );
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif
new file mode 100644
index 0000000..588d9c9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "WdtCommonLib"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Common"
+ RefName = "WdtCommonLib"
+[files]
+"WdtCommonLib.sdl"
+"WdtCommonLib.mak"
+"WdtCommon.h"
+"WdtCommon.c"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak
new file mode 100644
index 0000000..8032e7d
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.mak
@@ -0,0 +1,103 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtCommonLib/WdtCommonLib.mak 1 2/08/12 9:31a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:31a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtCommonLib/WdtCommonLib.mak $
+#
+# 1 2/08/12 9:31a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+EDK : WdtCommonLib
+WdtDxe : $(BUILD_DIR)\WdtDxe.mak WdtDxeBin
+
+WdtCommonLib : WdtCommonDxeLib WdtCommonPeiLib
+
+$(WdtCommonDxeLib_LIB) : WdtCommonDxeLib
+$(WdtCommonPeiLib_LIB) : WdtCommonPeiLib
+
+WdtCommonDxeLib : $(BUILD_DIR)\WdtCommonLib.mak WdtCommonLibDxeBin
+
+WdtCommonPeiLib : $(BUILD_DIR)\WdtCommonLib.mak WdtCommonLibPeiBin
+
+$(BUILD_DIR)\WdtCommonLib.mak : $(WdtCommonLib_DIR)\$(@B).cif $(WdtCommonLib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(WdtCommonLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+WdtCommonLib_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(WdtCommonLib_INCLUDES)
+
+
+WdtCommonLib_DEFINES = \
+ $(CFLAGS)
+
+DxeCpuBuildDefine = \
+!IF "$(x64_BUILD)"=="1"
+ /DMDE_CPU_X64\
+!ELSE
+ /DMDE_CPU_IA32\
+!ENDIF
+
+PeimCpuBuildDefine = \
+ /DMDE_CPU_IA32\
+
+WdtCommonLibPeim_DEFINES = \
+ $(WdtCommonLib_DEFINES)\
+ $(PeimCpuBuildDefine)\
+
+WdtCommonLibDxe_DEFINES = \
+ $(WdtCommonLib_DEFINES)\
+ $(DxeCpuBuildDefine)\
+
+WdtCommonLibDxeBin :
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\WdtCommonLib.mak all\
+ "MY_INCLUDES=$(WdtCommonLib_INCLUDES)" \
+ "CFLAGS=$(WdtCommonLibDxe_DEFINES)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(WdtCommonDxeLib_LIB)
+
+WdtCommonLibPeiBin :
+!IF "$(x64_BUILD)"=="1"
+ $(MAKE) /$(MAKEFLAGS) $(EDK_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32 \
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+!ENDIF
+ /f $(BUILD_DIR)\WdtCommonLib.mak all\
+ "MY_INCLUDES=$(WdtCommonLib_INCLUDES)" \
+ "CFLAGS=$(WdtCommonLibPeim_DEFINES)"\
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(WdtCommonPeiLib_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/Wdt/Common/WdtCommonLib.sdl b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.sdl
new file mode 100644
index 0000000..46ed512
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Common/WdtCommonLib.sdl
@@ -0,0 +1,92 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtCommonLib/WdtCommonLib.sdl 1 2/08/12 9:31a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:31a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtCommonLib/WdtCommonLib.sdl $
+#
+# 1 2/08/12 9:31a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "WdtCommonLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable WdtCommonLib support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "WdtCommonLib_DIR"
+End
+
+MODULE
+ Help = "Includes WdtCommonLib.mak to Project"
+ File = "WdtCommonLib.mak"
+End
+
+ELINK
+ Name = "WdtCommonLib_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/I$(WdtCommonLib_DIR)"
+ Parent = "WdtCommonLib_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "WdtCommonDxeLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\WdtCommonDxeLib.lib"
+ Parent = "WdtCommonDxeLib_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "WdtCommonPeiLib_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\WdtCommonPeiLib.lib"
+ Parent = "WdtCommonPeiLib_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/Wdt/Dxe/WdtDxe.c b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.c
new file mode 100644
index 0000000..ea5bd2f
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.c
@@ -0,0 +1,218 @@
+/** @file
+ Implementation file for Watchdog Timer functionality
+
+@copyright
+ Copyright (c) 2010 - 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
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGlueDxe.h"
+#endif
+
+#include EFI_PROTOCOL_CONSUMER (PchReset)
+#include "WdtCommon.h"
+#include EFI_PROTOCOL_PRODUCER (Wdt)
+
+VOID
+EFIAPI
+WdtRunBeforeOsBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+WdtPchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ );
+
+#define TIMEOUT_AFTER_POST_MULTIPLIER 16
+#define MINIMUM_TIMEOUT_AT_S4_EXIT 600 ///< 10 minutes
+EFI_HANDLE mImageHandle;
+WDT_PROTOCOL mWdtProtocol = {
+ WdtReloadAndStart,
+ WdtCheckStatus,
+ WdtDisable,
+ WdtAllowKnownReset,
+ IsWdtRequired,
+ IsWdtEnabled
+};
+
+PCH_RESET_CALLBACK_PROTOCOL mPchResetCallbackProtocol = { WdtPchResetCallback };
+
+/**
+ Installs WDT protocol.
+ Registers a function to be executed just before booting to OS.
+
+ @param[in] ImageHandle Image handle for this driver image
+ @param[in] SystemTable Pointer to the EFI System Table
+
+ @retval EFI_SUCCESS WDT DXE driver initialization completed successfully
+**/
+EFI_STATUS
+WdtDxeEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ DEBUG ((EFI_D_INFO, "(Wdt) Entry Point to WdtDxe\n"));
+
+ mImageHandle = ImageHandle;
+
+ Status = gBS->CreateEvent (
+ EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_CALLBACK,
+ WdtRunBeforeOsBoot,
+ NULL,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = EfiCreateEventLegacyBootEx (
+ EFI_TPL_CALLBACK,
+ WdtRunBeforeOsBoot,
+ NULL,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ DEBUG ((EFI_D_INFO, "(Wdt) WDT event registration; Status = %r\n", Status));
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gWdtProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mWdtProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gPchResetCallbackProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mPchResetCallbackProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Turns on watchdog timer just before booting to OS, if an OS application requested that.
+ Clears request status.
+ Uninstalls Wdt protocol to prevent other modules from interfering with actions described above.
+
+ @param[in] Event useless here, but required in functions invoked by events
+ @param[in] Context useless here, but required in functions invoked by events
+
+ @retval None
+**/
+VOID
+EFIAPI
+WdtRunBeforeOsBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ UINT32 ReloadValue;
+ UINT32 Readback;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_PEI_HOB_POINTERS HobList;
+ WDT_HOB *WdtHob;
+
+ gBS->CloseEvent (Event);
+
+ DEBUG ((EFI_D_INFO, "(Wdt) RunWdtBeforeOsBoot\n"));
+ Status = gBS->UninstallProtocolInterface (
+ mImageHandle,
+ &gWdtProtocolGuid,
+ &mWdtProtocol
+ );
+
+ Status = gBS->UninstallProtocolInterface (
+ mImageHandle,
+ &gPchResetCallbackProtocolGuid,
+ &mPchResetCallbackProtocol
+ );
+ ///
+ /// check boot type, there are different flows for S4/S5
+ ///
+ EfiGetSystemConfigurationTable (&gEfiHobListGuid, (VOID **) &HobList.Raw);
+ if (HobList.Header->HobType != EFI_HOB_TYPE_HANDOFF) {
+ DEBUG ((EFI_D_ERROR, "(Wdt) Handoff Hob missing!\n"));
+ return;
+ }
+
+ BootMode = HobList.HandoffInformationTable->BootMode;
+
+ WdtHob = GetFirstGuidHob (&mWdtHobGuid);
+ if (WdtHob == NULL) {
+ return;
+ }
+
+ Readback = IoRead32 (WdtGetAddress ());
+ ReloadValue = TIMEOUT_AFTER_POST_MULTIPLIER * ((Readback & B_PCH_OC_WDT_CTL_AFTER_POST) >> 16);
+
+ if (BootMode == BOOT_ON_S4_RESUME) {
+ ///
+ /// S4 resume: if WDT was enabled before S0->S4 transition,
+ /// then WDT must be turned on even though TimeoutValueAfterPost == 0
+ /// unlike in S5->S0 flow, ToVaP is not set to zero after being consumed
+ ///
+ if (WdtHob->Active == 1) {
+ if (ReloadValue != 0) {
+ WdtReloadAndStart (ReloadValue);
+ } else {
+ WdtReloadAndStart (MINIMUM_TIMEOUT_AT_S4_EXIT);
+ }
+ } else {
+ WdtDisable ();
+ }
+ } else if (ReloadValue != 0) {
+ ///
+ /// start WDT with TimeoutValueAfterPost and clear that value from register
+ ///
+ Readback &= ~(B_PCH_OC_WDT_CTL_AFTER_POST);
+ IoWrite32 (WdtGetAddress (), Readback);
+ WdtReloadAndStart (ReloadValue);
+ } else {
+ WdtDisable ();
+ }
+
+ return;
+}
+
+/**
+ WDT call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+WdtPchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ )
+{
+ WdtAllowKnownReset ();
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif
new file mode 100644
index 0000000..84a9fad
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "WdtDxe"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Dxe\"
+ RefName = "WdtDxe"
+[files]
+"WdtDxe.sdl"
+"WdtDxe.dxs"
+"WdtDxe.mak"
+"WdtDxe.c"
+"WdtDxe.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs
new file mode 100644
index 0000000..b64a661
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.dxs
@@ -0,0 +1,30 @@
+/** @file
+ Dependencies file for Watchdog Timer functionality
+
+@copyright
+ Copyright (c) 2010 - 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
+
+**/
+
+
+#include "AutoGen.h"
+#include "DxeDepex.h"
+#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/Wdt/Dxe/WdtDxe.inf b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.inf
new file mode 100644
index 0000000..ceff3c7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.inf
@@ -0,0 +1,87 @@
+## @file
+# Component description file for the watchdog timer driver.
+#
+#@copyright
+# Copyright (c) 2010 - 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 = WdtDxe
+FILE_GUID = 5AAB83E5-F027-4ca7-BFD0-16358CC9E453
+COMPONENT_TYPE = BS_DRIVER
+
+[sources.common]
+ WdtDxe.c
+ ../Common/WdtCommon.h
+ ../Common/WdtCommon.c
+
+#
+# Edk II Glue Driver Entry Point
+#
+ EdkIIGlueDxeDriverEntryPoint.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
+#
+# 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
+
+[libraries.common]
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGlueBaseMemoryLib
+ EdkIIGlueBasePciLibPciExpress
+ EdkIIGlueDxeReportStatusCodeLib
+ EdkIIGlueDxeDebugLibReportStatusCode
+ EdkIIGlueUefiBootServicesTableLib
+ EdkIIGlueUefiRuntimeServicesTableLib
+ EdkIIGlueDxeServicesTableLib
+ EdkProtocolLib
+ EdkIIGlueDxeHobLib
+ $(PROJECT_PCH_FAMILY)ProtocolLib
+ EfiGuidLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = WdtDxe.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=WdtDxeEntryPoint \
+ -D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ -D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ -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_HOB_LIB__ \ No newline at end of file
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak
new file mode 100644
index 0000000..a36f6cd
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.mak
@@ -0,0 +1,102 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtDxe/WdtDxe.mak 3 9/26/12 3:43a Victortu $
+#
+# $Revision: 3 $
+#
+# $Date: 9/26/12 3:43a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtDxe/WdtDxe.mak $
+#
+# 3 9/26/12 3:43a Victortu
+# Lynx Point PCH Chipset Framework Reference Code Beta 0.7.0
+#
+# 2 2/24/12 2:31a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:32a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+EDK : WdtDxe
+WdtDxe : $(BUILD_DIR)\WdtDxe.mak WdtDxeBin
+
+$(BUILD_DIR)\WdtDxe.mak : $(WdtDxe_DIR)\$(@B).cif $(BUILD_RULES)
+ $(CIF2MAK) $(WdtDxe_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+WdtDxe_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(WdtCommonLib_INCLUDES)
+
+WdtDxe_LIBS=\
+!IF "$(x64_BUILD)"=="1"
+ $(EdkIIGlueBaseLibX64_LIB)\
+!ELSE
+ $(EdkIIGlueBaseLibIA32_LIB)\
+!ENDIF
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGlueBaseMemoryLib_LIB)\
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(EdkIIGlueDxeReportStatusCodeLib_LIB)\
+ $(EdkIIGlueDxeDebugLibReportStatusCode_LIB)\
+ $(EdkIIGlueUefiBootServicesTableLib_LIB)\
+ $(EdkIIGlueDxeServicesTableLib_LIB)\
+ $(EDKPROTOCOLLIB)\
+ $(EdkIIGlueDxeHobLib_LIB)\
+ $(INTEL_PCH_PROTOCOL_LIB)\
+ $(EFIGUIDLIB)\
+ $(WdtCommonDxeLib_LIB)
+
+WdtDxe_DEFINES=\
+ $(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=WdtDxeEntryPoint"\
+ /D __EDKII_GLUE_BASE_IO_LIB_INTRINSIC__ \
+ /D __EDKII_GLUE_BASE_MEMORY_LIB__ \
+ /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_HOB_LIB__
+
+WdtDxeBin : $(WdtDxe_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS)\
+ /f $(BUILD_DIR)\WdtDxe.mak all\
+ "MY_INCLUDES=$(WdtDxe_INCLUDES)"\
+ "MY_DEFINES=$(WdtDxe_DEFINES)"\
+ GUID=5AAB83E5-F027-4ca7-BFD0-16358CC9E453\
+ ENTRY_POINT=_ModuleEntryPoint \
+ EDKIIModule=DXEDRIVER\
+ TYPE=BS_DRIVER \
+ DEPEX1=$(WdtDxe_DIR)\WdtDxe.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/Wdt/Dxe/WdtDxe.sdl b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.sdl
new file mode 100644
index 0000000..edfd5a6
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Dxe/WdtDxe.sdl
@@ -0,0 +1,68 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtDxe/WdtDxe.sdl 1 2/08/12 9:32a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:32a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtDxe/WdtDxe.sdl $
+#
+# 1 2/08/12 9:32a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "WdtDxe_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable ICC support in Project in DXE Phase"
+End
+
+MODULE
+ Help = "Includes WdtDxe.mak to Project"
+ File = "WdtDxe.mak"
+End
+
+PATH
+ Name = "WdtDxe_DIR"
+ Help = "Icc Support commands"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\WdtDxe.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/Wdt/Pei/WdtPei.c b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.c
new file mode 100644
index 0000000..c1d1e03
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.c
@@ -0,0 +1,280 @@
+/** @file
+ Implementation file for Watchdog Timer functionality
+
+@copyright
+ Copyright (c) 2010 - 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
+
+**/
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#endif
+
+#include EFI_PPI_CONSUMER (PchReset)
+#include "WdtCommon.h"
+#include EFI_PPI_PRODUCER (Wdt)
+
+EFI_STATUS
+EFIAPI
+WdtPchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ );
+
+static WDT_PPI mWdtPpi = {
+ WdtReloadAndStart,
+ WdtCheckStatus,
+ WdtDisable,
+ WdtAllowKnownReset,
+ IsWdtRequired,
+ IsWdtEnabled
+};
+
+static PCH_RESET_CALLBACK_PPI mPchResetCallbackPpi = { WdtPchResetCallback };
+
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallWdtPpi = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gWdtPpiGuid,
+ &mWdtPpi
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mInstallPchResetCallbackPpi = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPchResetCallbackPpiGuid,
+ &mPchResetCallbackPpi
+};
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEndOfPeiSignalPpiGuid,
+ EndOfPeiCallback
+};
+
+#define MINIMUM_TIMEOUT_AT_S3_EXIT 10 ///< seconds
+
+/**
+ Reads PCH registers to check if platform wakes from S3/S4
+
+ @param[in] None
+
+ @retval TRUE if platfrom wakes from S3/S4
+ @retval FALSE otherwise
+**/
+UINT8
+IsWakeFromS3_S4 (
+ VOID
+ )
+{
+ UINT32 Address;
+ UINT16 SleepType;
+
+ Address = MmioRead32 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_PCH,
+ PCI_DEVICE_NUMBER_PCH_LPC,
+ PCI_FUNCTION_NUMBER_PCH_LPC,
+ R_PCH_LPC_ACPI_BASE)
+ ) & B_PCH_LPC_ACPI_BASE_BAR;
+
+ if (IoRead16 (Address + R_PCH_ACPI_PM1_STS) & B_PCH_ACPI_PM1_STS_WAK) {
+ SleepType = IoRead16 (Address + R_PCH_ACPI_PM1_CNT) & B_PCH_ACPI_PM1_CNT_SLP_TYP;
+ if ((SleepType == V_PCH_ACPI_PM1_CNT_S3) || (SleepType == V_PCH_ACPI_PM1_CNT_S4)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ Initializes watchdog failure bits.
+ If there was an unexpected reset, enforces WDT expiration.
+ Stores initial WDT state in a HOB, it is useful in flows with S3/S4 resume.
+ Stops watchdog.
+ Installs watchdog PPI for other modules to use.
+
+ @param[in] FfsHeader Pointer to Firmware File System file header.
+ @param[in] PeiServices General purpose services available to every PEIM.
+
+ @retval EFI_SUCCESS When everything is OK
+**/
+EFI_STATUS
+WdtPeiEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ UINT32 Readback;
+ EFI_STATUS Status;
+ UINT16 TimeoutValue;
+ UINT8 Active;
+ WDT_HOB *WdtHobPtr;
+
+#ifndef WDT_SUPPORT_ENABLED
+ ///
+ /// clear status bits and disable watchdog, then lock the register
+ ///
+ IoWrite32 (WdtGetAddress (), (B_PCH_OC_WDT_CTL_ICCSURV_STS | B_PCH_OC_WDT_CTL_NO_ICCSURV_STS));
+ IoWrite32 (WdtGetAddress (), B_PCH_OC_WDT_CTL_LCK);
+#endif
+
+ Readback = IoRead32 (WdtGetAddress ());
+
+ DEBUG ((EFI_D_INFO, "(WDT) Readback = 0x%08x\n", Readback));
+ ///
+ /// Write current Wdt settings to a HOB, they may be be needed in S3/S4 resume paths
+ ///
+ if (Readback & B_PCH_OC_WDT_CTL_EN) {
+ Active = 1;
+ TimeoutValue = (UINT16) ((Readback & B_PCH_OC_WDT_CTL_TOV_MASK) + 1);
+ } else {
+ Active = 0;
+ TimeoutValue = 0;
+ }
+
+ Status = (*PeiServices)->CreateHob (PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, sizeof (WDT_HOB), (VOID **) &WdtHobPtr);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ WdtHobPtr->Header.Name = mWdtHobGuid;
+ WdtHobPtr->Active = Active;
+ WdtHobPtr->TimeoutValue = TimeoutValue;
+ ///
+ /// If there was a WDT expiration, set Failure Status and clear timeout status bits
+ /// Timeout status bits are cleared by writing '1'
+ ///
+ if (Readback & (B_PCH_OC_WDT_CTL_ICCSURV_STS | B_PCH_OC_WDT_CTL_NO_ICCSURV_STS)) {
+ DEBUG ((EFI_D_ERROR, "(WDT) Expiration detected.\n", Readback));
+ Readback |= B_PCH_OC_WDT_CTL_FAILURE_STS;
+ Readback |= (B_PCH_OC_WDT_CTL_ICCSURV_STS | B_PCH_OC_WDT_CTL_NO_ICCSURV_STS);
+ Readback &= ~(B_PCH_OC_WDT_CTL_UNXP_RESET_STS);
+ } else {
+ ///
+ /// If there was unexpected reset but no WDT expiration and no resume from S3/S4,
+ /// clear unexpected reset status and enforce expiration. This is to inform Firmware
+ /// which has no access to unexpected reset status bit, that something went wrong.
+ ///
+ if ((Readback & B_PCH_OC_WDT_CTL_UNXP_RESET_STS) && !IsWakeFromS3_S4 ()) {
+#if defined EFI_DEBUG && !defined USE_WDT_IN_DEBUG_BIOS
+ DEBUG ((EFI_D_ERROR, "(WDT) Unexpected reset detected and ignored.\n"));
+ Readback &= ~(B_PCH_OC_WDT_CTL_FAILURE_STS | B_PCH_OC_WDT_CTL_UNXP_RESET_STS);
+ Readback |= (B_PCH_OC_WDT_CTL_ICCSURV_STS | B_PCH_OC_WDT_CTL_NO_ICCSURV_STS);
+#else
+ DEBUG ((EFI_D_ERROR, "(WDT) Unexpected reset detected. Enforcing Wdt expiration.\n"));
+ WdtReloadAndStart (1);
+ while (1) {
+ ///
+ /// wait for reboot caused by WDT expiration
+ ///
+ }
+#endif
+ } else {
+ ///
+ /// No WDT expiration and no unexpected reset - clear Failure status
+ ///
+ DEBUG ((EFI_D_INFO, "(WDT) Status OK.\n", Readback));
+ Readback &= ~(B_PCH_OC_WDT_CTL_FAILURE_STS);
+ Readback |= (B_PCH_OC_WDT_CTL_ICCSURV_STS | B_PCH_OC_WDT_CTL_NO_ICCSURV_STS);
+ }
+ }
+
+ IoWrite32 (WdtGetAddress (), Readback);
+ ///
+ /// register an event for EndOfPei. It will support Wdt in resume from S3.
+ ///
+ Status = (**PeiServices).NotifyPpi (PeiServices, &mNotifyList);
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mInstallWdtPpi);
+
+ Status = (**PeiServices).InstallPpi (PeiServices, &mInstallPchResetCallbackPpi);
+
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+/**
+ Support for WDT in S3 resume.
+ If WDT was enabled during S0->S3 transition, this function will turn on WDT
+ just before waking OS. Timeout value will be overridden if it was too small.
+
+ @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 When everything is OK
+ @retval EFI_NOT_FOUND WdtHob is not found
+**/
+EFI_STATUS
+EndOfPeiCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+{
+ WDT_HOB *WdtHob;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG ((EFI_D_INFO, "(WDT) EndOfPeiCallback\n"));
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ ASSERT_EFI_ERROR (Status);
+ WdtHob = GetFirstGuidHob (&mWdtHobGuid);
+ if (WdtHob == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ DEBUG ((EFI_D_INFO, "(WDT) BootMode %d, Hob, active %d, ToV %d\n", BootMode, WdtHob->Active, WdtHob->TimeoutValue));
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ if (WdtHob->Active == 1) {
+ if (WdtHob->TimeoutValue < MINIMUM_TIMEOUT_AT_S3_EXIT) {
+ WdtReloadAndStart (MINIMUM_TIMEOUT_AT_S3_EXIT);
+ } else {
+ WdtReloadAndStart (WdtHob->TimeoutValue);
+ }
+ } else {
+ WdtDisable ();
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ WDT call back function for Pch Reset.
+
+ @param[in] PchResetType Pch Reset Types which includes PowerCycle, Globalreset.
+
+ @retval EFI_SUCCESS The function completed successfully
+ @retval Others All other error conditions encountered result in an ASSERT.
+**/
+EFI_STATUS
+EFIAPI
+WdtPchResetCallback (
+ IN PCH_RESET_TYPE PchResetType
+ )
+{
+ WdtAllowKnownReset ();
+ return EFI_SUCCESS;
+}
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif
new file mode 100644
index 0000000..24fbb35
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "WdtPei"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\Pei\"
+ RefName = "WdtPei"
+[files]
+"WdtPei.sdl"
+"WdtPei.dxs"
+"WdtPei.mak"
+"WdtPei.c"
+"WdtPeim.inf"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs
new file mode 100644
index 0000000..9531248
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.dxs
@@ -0,0 +1,31 @@
+/** @file
+ Dependencies file for Watchdog Timer functionality
+
+@copyright
+ Copyright (c) 2010 - 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
+
+**/
+
+
+#include "AutoGen.h"
+#include "PeimDepex.h"
+
+#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/Wdt/Pei/WdtPei.mak b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.mak
new file mode 100644
index 0000000..1c2df94
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.mak
@@ -0,0 +1,94 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtPei/WdtPei.mak 2 2/24/12 2:32a Victortu $
+#
+# $Revision: 2 $
+#
+# $Date: 2/24/12 2:32a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtPei/WdtPei.mak $
+#
+# 2 2/24/12 2:32a Victortu
+# Updated to support 4.6.5.3_IntelEDK_1117_Patch7_00.
+#
+# 1 2/08/12 9:33a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+EDK : WdtPei
+WdtPei : $(BUILD_DIR)\WdtPei.mak WdtPeiBin
+
+$(BUILD_DIR)\WdtPei.mak : $(WdtPei_DIR)\$(@B).cif $(BUILD_RULES)
+ $(CIF2MAK) $(WdtPei_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+WdtPei_INCLUDES=\
+ $(EdkIIGlueLib_INCLUDES)\
+ $(INTEL_PCH_INCLUDES)\
+ $(WdtCommonLib_INCLUDES)\
+
+WdtPei_DEFINES=$(MY_DEFINES)\
+ /D"__EDKII_GLUE_MODULE_ENTRY_POINT__=WdtPeiEntryPoint"\
+ /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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ /D __EDKII_GLUE_PEI_HOB_LIB__ \
+!IF "$(WDT_SUPPORT_ENABLED)"=="1"
+ /D WDT_SUPPORT_ENABLED
+!ENDIF
+
+WdtPei_LIBS =\
+ $(IntelPchPpiLib_LIB)\
+ $(EdkIIGlueBaseLib_LIB)\
+ $(EdkIIGlueBaseLibIA32_LIB)\
+ $(EdkIIGlueBaseIoLibIntrinsic_LIB)\
+ $(EdkIIGluePeiDebugLibReportStatusCode_LIB)\
+ $(EdkIIGluePeiReportStatusCodeLib_LIB)\
+ $(EdkIIGluePeiServicesLib_LIB) \
+ $(EdkIIGlueBasePciLibPciExpress_LIB)\
+ $(WdtCommonPeiLib_LIB)\
+ $(EDKFRAMEWORKPPILIB)\
+ $(EdkIIGluePeiHobLib_LIB)
+
+WdtPeiBin : $(WdtPei_LIBS)
+ $(MAKE) /$(MAKEFLAGS) $(EDKIIGLUE_DEFAULTS) \
+ /f $(BUILD_DIR)\WdtPei.mak all \
+ "MY_INCLUDES = $(WdtPei_INCLUDES)" \
+ "MY_DEFINES = $(WdtPei_DEFINES)" \
+ GUID=1D88C542-9DF7-424a-AA90-02B61F286938 \
+ ENTRY_POINT=_ModuleEntryPoint \
+ EDKIIModule=PEIM\
+ TYPE=PEIM \
+ DEPEX1=$(WdtPei_DIR)\WdtPei.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/Wdt/Pei/WdtPei.sdl b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.sdl
new file mode 100644
index 0000000..59d48d3
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPei.sdl
@@ -0,0 +1,78 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/WdtPei/WdtPei.sdl 1 2/08/12 9:33a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:33a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/WdtPei/WdtPei.sdl $
+#
+# 1 2/08/12 9:33a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "WdtPei_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable Wdt support in Project in PEI Phase"
+End
+
+TOKEN
+ Name = "WDT_SUPPORT_ENABLED"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes WdtPei.mak to Project"
+ File = "WdtPei.mak"
+End
+
+PATH
+ Name = "WdtPei_DIR"
+ Help = "Wdt Support commands"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\WdtPei.ffs"
+ Parent = "FV_BB"
+ Priority = 30
+ 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/Wdt/Pei/WdtPeim.inf b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPeim.inf
new file mode 100644
index 0000000..2f574a9
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Pei/WdtPeim.inf
@@ -0,0 +1,87 @@
+## @file
+# Component description file for the watchdog driver.
+#
+#@copyright
+# Copyright (c) 2010 - 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 = WdtPeim
+FILE_GUID = 1D88C542-9DF7-424a-AA90-02B61F286938
+COMPONENT_TYPE = PE32_PEIM
+
+[sources.common]
+ WdtPei.c
+ ../Common/WdtCommon.h
+ ../Common/WdtCommon.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
+#
+# 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
+
+[libraries.common]
+ $(PROJECT_PCH_FAMILY)PpiLib
+ EdkIIGlueBaseIoLibIntrinsic
+ EdkIIGluePeiDebugLibReportStatusCode
+ EdkIIGluePeiReportStatusCodeLib
+ EdkIIGluePeiServicesLib
+ EdkIIGlueBasePciLibPciExpress
+ PchPlatformLib
+ EdkFrameworkPpiLib
+ EdkIIGluePeiHobLib
+ EdkPpiLib
+
+[nmake.common]
+ IMAGE_ENTRY_POINT = _ModuleEntryPoint
+ DPX_SOURCE = WdtPei.dxs
+#
+# Module Entry Point
+#
+ C_FLAGS = $(C_FLAGS) -D __EDKII_GLUE_MODULE_ENTRY_POINT__=WdtPeiEntryPoint
+ C_FLAGS = $(C_FLAGS) -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_BASE_PCI_LIB_PCI_EXPRESS__ \
+ -D __EDKII_GLUE_PEI_HOB_LIB__
+
+#
+# Undefine the flag below to disable and lock WDT
+#
+ C_FLAGS = $(C_FLAGS) -DWDT_SUPPORT_ENABLED
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif b/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif
new file mode 100644
index 0000000..26d94c7
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "Wdt"
+ category = ModulePart
+ LocalRoot = "ReferenceCode\Chipset\LynxPoint\Wdt\"
+ RefName = "Wdt"
+[files]
+"Wdt.sdl"
+[parts]
+"WdtCommonLib"
+"WdtDxe"
+"WdtPei"
+<endComponent>
diff --git a/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl b/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl
new file mode 100644
index 0000000..33ff822
--- /dev/null
+++ b/ReferenceCode/Chipset/LynxPoint/Wdt/Wdt.sdl
@@ -0,0 +1,73 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (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/Wdt/Wdt.sdl 1 2/08/12 9:31a Yurenlai $
+#
+# $Revision: 1 $
+#
+# $Date: 2/08/12 9:31a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Refcode/Wdt/Wdt.sdl $
+#
+# 1 2/08/12 9:31a Yurenlai
+# Intel Lynx Point/SB eChipset initially releases.
+#
+#*************************************************************************
+TOKEN
+ Name = "WDT_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable WDT support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "WDT_DIR"
+End
+
+ELINK
+ Name = "WDT_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/I$(WDT_DIR)"
+ Parent = "WDT_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I$(WDT_DIR)\Protocol"
+ Parent = "WDT_INCLUDES"
+ 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 **
+#** **
+#*************************************************************************
+#*************************************************************************